<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Tim Abell</title>
    <subtitle>Helping teams ship software to be proud of.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://0x5.uk/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://0x5.uk/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-11-11T00:00:00+00:00</updated>
    <id>https://0x5.uk/atom.xml</id>
    <entry xml:lang="en">
        <title>Running dotnet microservices in Aspire without a project reference</title>
        <published>2025-11-11T00:00:00+00:00</published>
        <updated>2025-11-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/11/11/running-dotnet-microservices-in-aspire-without-a-project-reference/"/>
        <id>https://0x5.uk/2025/11/11/running-dotnet-microservices-in-aspire-without-a-project-reference/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/11/11/running-dotnet-microservices-in-aspire-without-a-project-reference/">&lt;p&gt;Aspire from Microsoft is pretty tantalizing for local development, however all the instructions for how to add a dotnet web app to your new dotnet aspire AppHost tell you to add a direct reference to the .csproj file that you want to run. But after a lot of hunting, head-scratching and trial and error I&#x27;ve found a less entangled way.&lt;&#x2F;p&gt;
&lt;p&gt;I was convinced it must be possible to run a dotnet project with Aspire without this pesky project reference; after all Aspire has support for running nodejs web apps, and any other ecosystem you choose to add to it. If that&#x27;s the case, why do we have to have this .csproj reference?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;project-references&quot;&gt;Project references&lt;&#x2F;h2&gt;
&lt;p&gt;The standard way of adding dotnet projects (including web apps, apis, blazor etc) is to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;dotnet&#x2F;adding-dotnet-aspire-to-your-existing-dotnet-apps&#x2F;#add-project-references&quot;&gt;add a project reference&lt;&#x2F;a&gt; in the AppHost project to the dotnet project that you want to manage &amp;amp; run in aspire. This makes a lot of sense for a system that was built with Aspire from the start, and that lives in a monorepo.&lt;&#x2F;p&gt;
&lt;p&gt;You &lt;em&gt;can&lt;&#x2F;em&gt; add a relative path project reference that goes outside of the repo that your Aspire AppHost lives in (after all, csproj files have no knowledge of where the git repo root is):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;ProjectReference&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; Include&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;..\..\..\some-webapi\src\Some.API\Some.API.csproj&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This however causes a bunch of problems, especially if you are trying to bolt Aspire on to an existing system that was built without it in many git repositories.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The dotnet SDKs have to be aligned or the build fails - so if you have two microservices on different SDK versions then you&#x27;re in for a hard time (at least if you are using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;asdf-vm.com&#x2F;&quot;&gt;asdf-vm&lt;&#x2F;a&gt; to manage dotnet versions (highly recommended), which only has one sdk per dotnet install version).&lt;&#x2F;li&gt;
&lt;li&gt;The microservice projects have no idea they are being included in the Aspire host, so have no reason to not break your Aspire project, resulting in endless maintenance problems and unreliability (for example the .csproj you are referencing could just be moved to another folder, or deleted entirely).&lt;&#x2F;li&gt;
&lt;li&gt;ALL your services are pulled together into one single mega-build of everything, which means if you have conflicts or dependency version mismatches you are out of luck unless you then go and make a load of changes to the microservices.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Fundamentally it also increases the entanglement of what are supposed to be independent microservices. All in all it just smelt wrong to me. I gave it a good go and got about 5 services in before I couldn&#x27;t build the Aspire project any more due to version clashes.&lt;&#x2F;p&gt;
&lt;p&gt;So what to do? I did some searching for approaches to multi-repo setup, assuming that as soon as you were across repo boundaries people would stop recommending project references, but no, that still seems to be the recommended approach in spite of the above issues. So then I went back a level… if you can run nodejs etc, surely you can run anything with a binary…&lt;&#x2F;p&gt;
&lt;p&gt;Well it turned out that nodejs&#x2F;npm has some special wrappers in Aspire so that wasn&#x27;t much help, but after a bit more digging for how you might just run any binary, and finding an intersting diversion on the ability to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;juliocasal.com&#x2F;blog&#x2F;how-to-add-custom-commands-to-the-net-aspire-dashboard&quot;&gt;add arbitrary custom commands&lt;&#x2F;a&gt; to a service (useful!) I discovered you can indeed shell out to call any executable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dotnet-executable-reference&quot;&gt;Dotnet executable reference&lt;&#x2F;h2&gt;
&lt;p&gt;The inspiration that hit me after a while that I haven&#x27;t seen anyone else mention (let me know if I just failed to find it!) is that for local dev setup with Aspire we can just run &lt;code&gt;dotnet run&lt;&#x2F;code&gt; in the folder of the web app you want to run (or you could use the &lt;code&gt;--project&lt;&#x2F;code&gt; argument, not sure it makes much difference).&lt;&#x2F;p&gt;
&lt;p&gt;Eventually I found the fluent builder method for Aspire that I was looking for: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;aspire&#x2F;app-host&#x2F;executable-resources&quot;&gt;&lt;code&gt;.AddExecutable()&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And so, with all that waffle and backstory out the way, here&#x27;s the actually very small bit of code you came here for. This was enough to get an arbitary web app from a sibling git-repo folder up and running in the Aspire dashboard on a local dev machine.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; DistributedApplication&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;CreateBuilder&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;builder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;AddExecutable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;some-webapi&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        command&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;dotnet&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        workingDirectory&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Path&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;GetFullPath&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; get back to parent repo folder out of aspire-repo&#x2F;src&#x2F;AspireAppHost&#x2F;bin&#x2F;Debug&#x2F;net8.0&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;            Path&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Combine&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;AppContext&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;BaseDirectory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;some-webapi&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        args&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;run&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;WithUrl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;localhost:8080&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;WithExplicitStart&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;builder&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Build&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;experience-report&quot;&gt;Experience report&lt;&#x2F;h3&gt;
&lt;p&gt;Because in this setup Aspire has no knowledge of the web app, it can&#x27;t magically figure out the url&#x2F;port for the web app that it has started, so you have to add the &lt;code&gt;.WithUrl()&lt;&#x2F;code&gt; so that you get a link to click on in the dashboard when you&#x27;ve started the app.&lt;&#x2F;p&gt;
&lt;p&gt;Aspire captures the stdout&#x2F;err so you can immediately see the console logs for each web app in the dashboard, which is dead handy and beats flipping between a load of terminals or IDEs to find the logs. It even interleaves the logs from multiple services with a colourful prefix in the main log screen.&lt;&#x2F;p&gt;
&lt;p&gt;Without some extra work, Aspire has no insight into whether the service it has run is ready, so it shows the url and &quot;Running&quot; even though the app is still starting up. I suspect this might be solvable with some use of the &quot;health&quot; capabilities.&lt;&#x2F;p&gt;
&lt;p&gt;Because we are running &lt;code&gt;dotnet run&lt;&#x2F;code&gt; rather than the pre-built binary, if the code has changed the web app will be rebuilt automatically (resulting in a slower start, but this is for local development so that&#x27;s presumably what you&#x27;d want anyway). The full build output shows in the app&#x27;s Aspire console logs which is useful seeing what went wrong. Using the csproj reference approach I found the build errors of referenced projects much harder to figure out, especially as it wasn&#x27;t immediately clear which of the microservices had actually failed to build. This approach neatly segregates the builds once again.&lt;&#x2F;p&gt;
&lt;p&gt;It does not solve the problem of connecting the services to each other. I believe that if you go all-in with Aspire it will do the service-discovery &#x2F; dns for you (don&#x27;t quote me), but it&#x27;s a big ask to rework all your services when no-one in your org has seen any value from Aspire thus far. Microservices systems built without Aspire will of course alreay have some solution in place for connecting services to each other and deciding what to run locally and what to run in the cloud for local development, so you can continue to lean on that with this approach and lose nothing.&lt;&#x2F;p&gt;
&lt;p&gt;All in all I&#x27;m very happy with this, it allows me to bolt an Aspire dashboard, startup and logging to whatever pile of services I happen to be dealing with for a given client, no matter the state of them. This gives me an improved local development experience and reducing the burden of cognitive load of managing all the local services, freeing up limited mental resources for the actual work at hand.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references-further-reading&quot;&gt;References &amp;amp; further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;dotnet&#x2F;adding-dotnet-aspire-to-your-existing-dotnet-apps&#x2F;&quot;&gt;devblogs.microsoft.com: Adding .NET Aspire to your existing .NET apps - .NET Blog&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=fN3ufsIF7vs&quot;&gt;What is .NET Aspire? Why do you NEED it in every .NET app? How to get started in minutes! - YouTube&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=-73fAqw8ckU&quot;&gt;Migrating From Docker Compose to .NET Aspire (my experience) - YouTube&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;multi-repo
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dev.to&#x2F;dutchskull&#x2F;poly-repo-support-for-dotnet-aspire-14d5&quot;&gt;Enhance Your Development with Multi-Repo Support in Dotnet Aspire - DEV Community&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Dutchskull&#x2F;Aspire.PolyRepo&quot;&gt;Dutchskull&#x2F;Aspire.PolyRepo: This library for DotNet Aspire enables poly repo support and the addition of Git repositories to your Aspire projects. It simplifies multi-repository management and streamlines dependency handling, making it easier to work with multiple repositories in a Aspire project.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dotnet&#x2F;aspire&#x2F;discussions&#x2F;1137&quot;&gt;Add Multi repo support · dotnet&#x2F;aspire · Discussion #1137&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;tye is archived with no explanation &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dotnet&#x2F;tye&quot;&gt;dotnet&#x2F;tye: Tye is a tool that makes developing, testing, and deploying microservices and distributed applications easier. Project Tye includes a local orchestrator to make developing microservices easier and the ability to deploy microservices to Kubernetes with minimal configuration.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;77757079&#x2F;is-it-possible-to-use-net-aspire-across-multiple-net-solutions&#x2F;78033654#78033654&quot;&gt;Is it possible to use .NET Aspire across multiple .NET solutions? - Stack Overflow&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dotnet&#x2F;aspire&#x2F;discussions&#x2F;10276&quot;&gt;Multi-Repository Setup with .NET Aspire: Best Practices for Enterprise Constraints · dotnet&#x2F;aspire · Discussion #10276&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dotnet&#x2F;aspire&#x2F;discussions&#x2F;10644#discussion-8626583&quot;&gt;Aspire Roadmap (2025 → 2026) · dotnet&#x2F;aspire · Discussion #10644&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nikiforovall.blog&#x2F;dotnet&#x2F;aspire&#x2F;2024&#x2F;09&#x2F;30&#x2F;aspire-lessons-learned.html&quot;&gt;nikiforovall.blog: 10 Lessons I Learned from Using Aspire in Production&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;aspire&#x2F;get-started&#x2F;build-aspire-apps-with-nodejs&quot;&gt;learn.microsoft.com: Orchestrate Node.js apps in Aspire - Aspire | Microsoft Learn&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;add custom commands to services, e.g. clear-cache for redis
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;aspire&#x2F;fundamentals&#x2F;custom-resource-commands&quot;&gt;learn.microsoft.com: Custom resource commands - Aspire | Microsoft Learn&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;juliocasal.com&#x2F;blog&#x2F;how-to-add-custom-commands-to-the-net-aspire-dashboard&quot;&gt;juliocasal.com: How to Add Custom Commands to the .NET Aspire Dashboard&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;running projects without adding project references
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.c-sharpcorner.com&#x2F;article&#x2F;host-external-executables-in-net-aspire&#x2F;&quot;&gt;www.c-sharpcorner.com: Host external executables in .NET Aspire&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;aspire&#x2F;app-host&#x2F;executable-resources&quot;&gt;learn.microsoft.com: Host external executables in Aspire - Aspire | Microsoft Learn&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;anthonysimmon.com&#x2F;must-have-resources-for-new-dotnet-aspire-developers&#x2F;&quot;&gt;Must-have resources for new .NET Aspire developers ~ Anthony Simmon&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;anthonysimmon.com&#x2F;exploring-microsoft-developer-control-plane-core-dotnet-aspire-dotnet-8&#x2F;&quot;&gt;Exploring the Microsoft Developer Control Plane at the heart of the new .NET Aspire ~ Anthony Simmon&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Gitopolis to Manage Multiple Git Repositories</title>
        <published>2025-10-25T00:00:00+00:00</published>
        <updated>2025-10-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/10/25/using-gitopolis-to-manage-multiple-git-repositories/"/>
        <id>https://0x5.uk/2025/10/25/using-gitopolis-to-manage-multiple-git-repositories/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/10/25/using-gitopolis-to-manage-multiple-git-repositories/">&lt;p&gt;At some point, every microservices project turns into a small city of Git repos.&lt;br &#x2F;&gt;
You start with three or four, and before long you’ve got twenty.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rustworkshop&#x2F;gitopolis&quot;&gt;Gitopolis&lt;&#x2F;a&gt; makes that manageable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;billing&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;users&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;orders&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;payments&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;inventory&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;notifications&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web-ui&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;admin-ui&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mobile&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;infra&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ci&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;monitoring&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;alerts&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gateway&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;docs&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;devtools&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;scripts&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;design-system&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shared&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Alice is a backend developer, but she needs to keep an eye on frontend and infra changes too.&lt;br &#x2F;&gt;
All of it matters. All of it lives in Git.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;day-one-setup&quot;&gt;Day One: Setup&lt;&#x2F;h2&gt;
&lt;p&gt;She installs Gitopolis and points it at her working directory:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; ~&#x2F;work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; add&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Fifteen existing repos are added instantly.&lt;br &#x2F;&gt;
Gitopolis writes a &lt;code&gt;.gitopolis.toml&lt;&#x2F;code&gt; file listing their paths, remotes, and metadata.&lt;br &#x2F;&gt;
It’s plain text — no magic, no database.&lt;&#x2F;p&gt;
&lt;p&gt;Then she tags them by team:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; backend&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; billing&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; users&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; orders&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; payments&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; inventory&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; notifications&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; gateway&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; frontend&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; web-ui&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; admin-ui&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; mobile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; design-system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; infra&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; infra&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; ci&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; monitoring&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; alerts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; shared&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; shared&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; devtools&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; scripts&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; docs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now she can focus on only what matters that day.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;day-two-payoff&quot;&gt;Day Two: Payoff&lt;&#x2F;h2&gt;
&lt;p&gt;Instead of jumping between folders, she runs everything from the top level.&lt;&#x2F;p&gt;
&lt;p&gt;Pull all backend repos:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; exec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; backend&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; pull&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Check their current status:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; exec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; backend&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;See what’s changed in the last week:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; exec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; backend&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; log&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-since=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;One Week&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;She creates a few shell aliases:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;alias&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; gpl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;gitopolis exec -t backend -- git pull&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;alias&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; gst&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;gitopolis exec -t backend -- git status&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;alias&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; gls&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;gitopolis exec -t backend -- git log -n 5 --since=&amp;quot;One Week&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now she runs &lt;code&gt;gpl&lt;&#x2F;code&gt; with her morning coffee, &lt;code&gt;gst&lt;&#x2F;code&gt; before lunch, &lt;code&gt;gls&lt;&#x2F;code&gt; before stand-up.&lt;br &#x2F;&gt;
Her workflow stops feeling scattered.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;day-three-a-new-starter&quot;&gt;Day Three: A New Starter&lt;&#x2F;h2&gt;
&lt;p&gt;The company’s onboarding process mentions “Install Gitopolis”.&lt;br &#x2F;&gt;
Alice drops a copy of &lt;code&gt;.gitopolis.toml&lt;&#x2F;code&gt; into the shared Google Drive folder and links it in the new-starter docs.&lt;&#x2F;p&gt;
&lt;p&gt;When Dana joins the team, she runs:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; ~&#x2F;work&lt;&#x2F;span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; ~&#x2F;work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;cp&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; ~&#x2F;GoogleDrive&#x2F;dev-setup&#x2F;.gitopolis.toml&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; clone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All the right repos appear in the right places.&lt;&#x2F;p&gt;
&lt;p&gt;Alice shows her how to explore the setup:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tags&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-long&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;backend&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        auth&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        billing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        users&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        orders&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        payments&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        inventory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        notifications&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        gateway&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        shipping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;frontend&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        web-ui&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        admin-ui&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        mobile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        design-system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;infra&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        infra&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        ci&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        monitoring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        alerts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;shared&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        shared&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        devtools&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        scripts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        docs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Dana can instantly see which repos belong to which teams — &lt;code&gt;backend&lt;&#x2F;code&gt;, &lt;code&gt;frontend&lt;&#x2F;code&gt;, &lt;code&gt;infra&lt;&#x2F;code&gt;, &lt;code&gt;shared&lt;&#x2F;code&gt;.&lt;br &#x2F;&gt;
She starts working without having to ask where anything lives.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;day-four-evolving&quot;&gt;Day Four: Evolving&lt;&#x2F;h2&gt;
&lt;p&gt;As the project grows, Alice adds and syncs new repos as needed.&lt;&#x2F;p&gt;
&lt;p&gt;Adding a local repo she’s just created:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; add&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; shipping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; backend&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; shipping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Cloning a new remote one that Chloe (frontend) just pushed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; clone&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; git@github.com:org&#x2F;returns.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; frontend&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; returns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When remotes move or change names:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gitopolis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; sync&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-read-remotes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;.gitopolis.toml&lt;&#x2F;code&gt; stays current. Everyone stays in sync.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Immediate payoff for one developer&lt;&#x2F;strong&gt; before anyone else uses it.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Tag-scoped focus&lt;&#x2F;strong&gt; to limit noise across teams.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Simple onboarding&lt;&#x2F;strong&gt; with a shared config file.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;No daemons, no central service — just text and Git.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Hope that helps you see how Gitopolis can be useful in a real project.&lt;br &#x2F;&gt;
I’ve done everything above with names changed to avoid mentioning clients and details simplified for the sake of explanation.&lt;&#x2F;p&gt;
&lt;p&gt;Let me know how you get on with it or if you have any problems.&lt;&#x2F;p&gt;
&lt;p&gt;More info: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rustworkshop&#x2F;gitopolis&quot;&gt;github.com&#x2F;rustworkshop&#x2F;gitopolis&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Use Checklists &amp; Templates For Onboarding New People</title>
        <published>2025-09-19T00:00:00+00:00</published>
        <updated>2025-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/09/19/checklists-for-onboarding-new-people/"/>
        <id>https://0x5.uk/2025/09/19/checklists-for-onboarding-new-people/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/09/19/checklists-for-onboarding-new-people/">&lt;p&gt;We spend plenty of time as engineers either being onboarded into a new organisation &#x2F; project or helping onboard others.&lt;&#x2F;p&gt;
&lt;p&gt;The best onboarding experiences I&#x27;ve had have been low-stress, with a clear path to follow, a clear list of things to be done, and many access and setup hurdles magically automated or handled behind the scenes by others - the result is being productive far quicker, and being much less of a burden on others.&lt;&#x2F;p&gt;
&lt;p&gt;The worst have been multiple weeks of sorting through piles of badly written, wrong, outdated&#x2F;confusing documents, links and instructions trying to work out what I actually need to be productive with little help from others - the result is endless questions to others, feelings of imposter syndrome, doubt and stress all resulting in negative productivity for an extended period of time.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a small but powerful thing you can do to make that journey smoother for those who follow.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been on the receiving end of onboarding in places using this approach and it&#x27;s made a world of difference to my state of mind and productivity; not to mention my opinion of the organisation. First impressions stick.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-written-onboarding-guides&quot;&gt;1. Written onboarding guides&lt;&#x2F;h2&gt;
&lt;p&gt;First of all, if you have to have someone telling the new starter in-person how to get started because all the knowledge is in people&#x27;s head then there is huge risk of the information walking out the door with them, and huge opportunities for a more efficient process. I personally love spending time chatting with people, however even I worry about the time-cost of me getting one-to-one hand-holding by someone who clearly already has a ton to do.&lt;&#x2F;p&gt;
&lt;p&gt;So the simplest thing to do is open up a wiki page (confluence perhaps) or google doc and just start writing down all the steps that have to be done. Numbered bullets make for a nice guided flow. Make it easy to read, use proper headings and nice formatting. And lots of numbered bullets.&lt;&#x2F;p&gt;
&lt;p&gt;The best time to capture this is when someone new is onboarding. The person being onboarded and the person helping them know more than anyone else at that point about what&#x27;s needed. As they find blockers and missing information they should take a moment to capture what they found in the onboarding guide as they go. A quick review from the new starter in the few weeks after they start and have got the hang of things can capture a heap of critical details and ways to handle surprising things, gotchas and blockers.&lt;&#x2F;p&gt;
&lt;p&gt;Include everything you might say to a person - &quot;oh you need to ask xyz, here&#x27;s there email&quot;, or &quot;you need to submit a support ticket in this system [url] to get access to that and then abc has to approve it, here&#x27;s an example of what to write in the ticket....&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;If you can get that done you&#x27;re ahead of the bottom 30%&lt;sup&gt;†&lt;&#x2F;sup&gt; of teams&lt;&#x2F;p&gt;
&lt;p&gt;&lt;sup&gt;†&lt;&#x2F;sup&gt;&lt;em&gt;made up number to make a point&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-checklists&quot;&gt;2. Checklists&lt;&#x2F;h2&gt;
&lt;p&gt;Having got your basic onboarding doc in place, here&#x27;s a neat trick that I came across somewhere - instead of just numbered bullets, make them clickable checkboxes and tell the new starter to make a copy of the document and work through it ticking things off.&lt;&#x2F;p&gt;
&lt;p&gt;This is a huge stress reducers due to the anxiety caused by worrying about missing steps that have been provided in an unfamiliar environment (combined with the stress of any new role&#x2F;project), and prevents a lot of wasted time repeatedly reading the list to figure out what&#x27;s done or managing a separate list.&lt;&#x2F;p&gt;
&lt;p&gt;A lot of software now supports checklists, so whatever you use you can probably add them in.&lt;&#x2F;p&gt;
&lt;p&gt;I know of at least the following that support checkboxes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Trello&lt;&#x2F;li&gt;
&lt;li&gt;Notion&lt;&#x2F;li&gt;
&lt;li&gt;Slack canvases&lt;&#x2F;li&gt;
&lt;li&gt;Confluence&lt;&#x2F;li&gt;
&lt;li&gt;Google docs&lt;&#x2F;li&gt;
&lt;li&gt;Just about every markdown tool&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;google-docs&quot;&gt;Google docs&lt;&#x2F;h3&gt;
&lt;p&gt;Just type &lt;kbd&gt;[&lt;&#x2F;kbd&gt;, &lt;kbd&gt;]&lt;&#x2F;kbd&gt; and then &lt;kbd&gt;space&lt;&#x2F;kbd&gt; on a new line and magically get a checkbox that behaves a lot like a bullet.&lt;&#x2F;p&gt;
&lt;p&gt;You can use &lt;kbd&gt;tab&lt;&#x2F;kbd&gt; and &lt;kbd&gt;shift&lt;&#x2F;kbd&gt;+&lt;kbd&gt;tab&lt;&#x2F;kbd&gt; to indent&#x2F;outdent them too just like bullets.&lt;&#x2F;p&gt;
&lt;p&gt;Or use the menus - &quot;Format &amp;gt; Bullets &amp;gt; Checklist&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;checklists&#x2F;google-docs-checklist.png&quot; alt=&quot;A google doc with a checklist in it&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;trello&quot;&gt;Trello&lt;&#x2F;h3&gt;
&lt;p&gt;The trello checklist feature is pretty front and center, just create a card and there&#x27;s a checklist button right there.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;checklists&#x2F;trello-checklist.png&quot; alt=&quot;Adding a checklist to a trello card&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;3-templates&quot;&gt;3. Templates&lt;&#x2F;h2&gt;
&lt;p&gt;If you&#x27;ve already got a rudimentary (or perfect) onboarding doc, and have added some checkboxes, now take it to the next level by making the doc a proper template that new-starters can click a button to get their own copy to tick-off.&lt;&#x2F;p&gt;
&lt;p&gt;This is the icing on the cake for slick onboarding.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;trello-1&quot;&gt;Trello&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;checklists&#x2F;trello-make-template.png&quot; alt=&quot;Turning a trello card into a template&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;checklists&#x2F;trello-make-from-template.png&quot; alt=&quot;Making a trello card from a template&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;google-docs-1&quot;&gt;Google docs&lt;&#x2F;h3&gt;
&lt;p&gt;Custom templates in google docs are a bit of a faff and only available for paid g-suite accounts. It&#x27;s also not clear to me how easy it will be for new-starters to find and use the right template, though they have a &quot;category&quot; system which might help.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s a bit confusing but you can create and &quot;submit&quot; google docs to become templates, and you can edit the template and the created docs separately.&lt;&#x2F;p&gt;
&lt;p&gt;It has to be allowed in the workspace admin, but that might be the default: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;support.google.com&#x2F;a&#x2F;answer&#x2F;3055325?hl=en&quot;&gt;Turn custom Drive templates on or off for users - Google Workspace Admin Help&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To submit a template - go the usual new doc page, expand out the template list and click the &quot;Submit template&quot; button:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;checklists&#x2F;google-submit-template.png&quot; alt=&quot;Submitting a template&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Choosing a template from the list when creating a new google doc:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;checklists&#x2F;google-use-template.png&quot; alt=&quot;Default template list in new doc page&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;... the expanded template list (click the text &quot;Template gallery&quot; with the up&#x2F;down arrow to the right of it to get to here):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;checklists&#x2F;google-use-template-gallery.png&quot; alt=&quot;Viewing template gallery for doc creation&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once a document has been submitted as a template, editing the template makes it clear that that&#x27;s what you are editing:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;checklists&#x2F;google-editing-template.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;support.google.com&#x2F;a&#x2F;users&#x2F;answer&#x2F;13003605#create_document_templates&amp;amp;zippy=%2Clearn-how&quot;&gt;Tips to format &amp;amp; customize documents &amp;gt; Use and create document templates - Google Workspace Learning Center&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-tips&quot;&gt;Bonus tips&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-automated-setup&quot;&gt;1. Automated setup&lt;&#x2F;h3&gt;
&lt;p&gt;Make your git repos require nothing more than a clone and some kind of run script to have a fully functioning local dev setup (there are tons of ways of doing this, bash, docker, makefiles, dotnet-aspire, 12-factor etc. etc.)&lt;&#x2F;p&gt;
&lt;p&gt;Better than a checklist is no need for a checklist at all because there&#x27;s nothing to do but clone the repo and ship to prod. Having make the list, try and eliminate as much as possible so that the new starter doesn&#x27;t actually have to do anything. The ninja-level orgs I&#x27;ve joined where you can ship code in your first week (or day?!) work very hard on this level, with every developer tirelessly improving developer setup for code, and behind the scenes &lt;a href=&quot;&#x2F;2019&#x2F;07&#x2F;08&#x2F;why-every-team-needs-a-delivery-manager&#x2F;&quot;&gt;delivery managers&lt;&#x2F;a&gt; making all the organisational setup seamless and invisible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-have-an-new-starters-channel-for-questions&quot;&gt;2. Have an &lt;code&gt;#new-starters&lt;&#x2F;code&gt; channel for questions&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s common these days for teams to have slack or some equivalent (for example the universally-hated &quot;Microsoft teams&quot;) that support chat-room style channels.&lt;&#x2F;p&gt;
&lt;p&gt;New starters are often hesitant to bother the existing, often busy, team with &quot;newbie&quot; questions.&lt;&#x2F;p&gt;
&lt;p&gt;Create a &lt;code&gt;#new-starters&lt;&#x2F;code&gt; channel &#x2F; chat-room, and ask a few of your existing people who are more enthusiastic about helping new people to lurk in there and keep an eye out for questions. Make sure all new starters are added to that channel and are encouraged to ask all questions no matter how trivial, and let them know that you&#x27;ll use what&#x27;s in there to improve onboarding for future people to show that you value the questions beyond just getting them started as an individual.&lt;&#x2F;p&gt;
&lt;p&gt;This has massive benefits:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;New people will feel much more happy to ask all those &quot;silly questions&quot; that they run in to along the way to being productive instead of holding back or asking the wrong person. (There are no silly questions, there are only onboarding frictions that can be improved).&lt;&#x2F;li&gt;
&lt;li&gt;All those normally hidden frictions, confusion and stress can be flushed out into a shared channel where they can be improved upon &#x2F; eliminated for future new starters.&lt;&#x2F;li&gt;
&lt;li&gt;Your existing team can self-select into helping new people get started by joining the onboarding channel.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A win for everyone involved, for so little effort.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;A slick onboarding process is a never-ending process of constant improvement. Perfect onboarding is an &quot;ideal&quot; that can never be reached but that should be constantly strived for, with everyone encouraged to sand-off any rough edges along the way. It&#x27;s hard to design onboarding up-front because you just don&#x27;t know what people will trip over, so the best moment to capture this is the moment when someone is trying to get started, and someone is helping them. Take the time to make permanent improvements that will make each new person find the onboarding experience better and better.&lt;&#x2F;p&gt;
&lt;p&gt;The onboarding experience has, in my experience, been a pretty good indicator of the quality of the team I&#x27;m joining. Every team needs great people, and what better way to signal to the best of the best that your places is worth of their time than making every contact with the organisation a pleasure.&lt;&#x2F;p&gt;
&lt;p&gt;Go out and make your next new-starter&#x27;s experience a great one.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mandatory reading for tech leaders 📚</title>
        <published>2025-07-15T00:00:00+00:00</published>
        <updated>2025-07-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/07/15/mandatory-reading-for-tech-leaders/"/>
        <id>https://0x5.uk/2025/07/15/mandatory-reading-for-tech-leaders/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/07/15/mandatory-reading-for-tech-leaders/">&lt;p&gt;I repeatedly encounter ongoing software projects that are &lt;em&gt;far behind&lt;&#x2F;em&gt; industry best practice and as a result are getting the inevitable problems in quality, delays, waste etc. When I talk to the project leadership and above it often transpires that they are unaware of the literature that has been created off the back of many decades of experience, experimentation and research into what works and what doesn&#x27;t in software delivery.&lt;&#x2F;p&gt;
&lt;p&gt;I have read many things recently on high-performance software delivery and tech leadership, and out of everything I&#x27;ve read, these four books in my view hold so much condensed knowledge on what actually works that they would be transformational for any software delivery project where the technical (and non-technical) leadership read and implemented the ideas held within them.&lt;&#x2F;p&gt;
&lt;p&gt;These are, in an order that would be a good order to read them:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closed-book-the-unicorn-project&quot;&gt;📕 The Unicorn Project&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;44333183-the-unicorn-project&quot;&gt;The Unicorn Project by Gene Kim&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a book that tells the story of the transformation of a fictional organisation from outdated and ineffective practices of software delivery to a much more modern and effective approach.&lt;&#x2F;p&gt;
&lt;p&gt;The book is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;plexways.com&#x2F;literary-art&#x2F;didactic-novels&#x2F;&quot;&gt;didactic novel&lt;&#x2F;a&gt;, using a compelling and engaging story of a cast of fictional characters living through the changes and playing their roles in the change as they learn the principles at work — but do not be deceived, this is a book based on the foundation of deep industry knowledge and the lessons held within it are defensible and well researched.&lt;&#x2F;p&gt;
&lt;p&gt;It is a modernised version of the Phoenix project. Where the Phoenix project tackled the Dev&#x2F;Ops divide that has (mostly) been abandoned in software delivery, the Unicorn project tackles more modern dysfunctions (Dev&#x2F;QA silos, lack of communication and coordination etc.).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closed-book-the-devops-handbook&quot;&gt;📕 The DevOps Handbook&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;26083308-the-devops-handbook&quot;&gt;The DevOps Handbook: How to Create World-Class Agility, Reliability, and Security in Technology Organizations by Gene Kim, Patrick Debois, John Willis, Jez Humble&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is the full manual for high-performance software delivery. You can use it as a reference to design your processes and your software delivery organisation will as a result out-perform the average by a significant margin. It&#x27;s a drier read than the unicorn project, but very complete, and provides a great reference for all areas for any software team.&lt;&#x2F;p&gt;
&lt;p&gt;Advanced teams will want to iterate beyond the standard outlined in this book, but most organisations could benefit from moving from inferior practices to the standards outlined herein.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closed-book-the-goal&quot;&gt;📕 The Goal&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;113934.The_Goal&quot;&gt;The Goal: A Process of Ongoing Improvement by Eliyahu M. Goldratt, Jeff Cox&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t a book about software at all... but before you move on consider that a huge amount of the approaches that software development teams take for granted (agile, lean, kanban, WIP-limits, retrospectives, daily standups etc.) have their roots in previous decades of learning and research in the manufacturing industry.&lt;&#x2F;p&gt;
&lt;p&gt;This book is another didactic novel, this time following the transformation of a failing factory and its production lines into a profitable and efficient operation in the image of the Toyota Production System (TPS). The Pheonix Project and the Unicorn Project books were based on the style of The Goal and all three are great books thanks to the approach taken and the huge amount of effort that went into distilling the industry knowledge into this format.&lt;&#x2F;p&gt;
&lt;p&gt;There is a lot to learn from this book, as I think much of &quot;lean software delivery&quot; and &quot;Agile&quot; has &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.m.wikipedia.org&#x2F;wiki&#x2F;Cargo_cult_programming&quot;&gt;cargo-culted&lt;&#x2F;a&gt; the methods from Toyota without understanding the principles that drive the behaviours and systems, and as such don&#x27;t achieve the results they could. (For example the average SCRUM retrospective completely misses the point of the way Toyota runs continuous improvement).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closed-book-the-toyota-way&quot;&gt;📕 The Toyota Way&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;161789.The_Toyota_Way&quot;&gt;The Toyota Way: 14 Management Principles from the World&#x27;s Greatest Manufacturer by Jeffrey K. Liker&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A lot of the best practice in software (lean, kanban etc, continuous delivery etc) have their roots in the scientific understanding of flows of work developed at the world-leading car manufacturer Toyota.&lt;&#x2F;p&gt;
&lt;p&gt;This book goes far beyond the detailed improvement of a production line and the theories involved; covering the company culture that enables high performance lean operations, developing leadership and transforming organisations (the case study being the turnaround of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;NUMMI&quot;&gt;NUMMI plant&lt;&#x2F;a&gt; under Toyota&#x27;s care).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading-books&quot;&gt;Further reading 📚&lt;&#x2F;h2&gt;
&lt;p&gt;If the tech leaders I work with have read, absorbed and embody even one of the above books it makes it much more possible for me to lead teams into high-performance low-stress efficient software delivery.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;ve already read these books you might be interested in the related books on my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;review&#x2F;list&#x2F;50628592-tim-abell?utf8=%E2%9C%93&amp;amp;shelf=tech&amp;amp;title=tim-abell&amp;amp;per_page=100&quot;&gt;&quot;tech&quot; goodreads list&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The journey never ends, so if I&#x27;ve missed any books you think are key texts then do let me know. Let&#x27;s keep learning and improving together.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;let-s-talk&quot;&gt;Let&#x27;s talk&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;d like to work with more people who think like this, or who are open to moving in the direction these books teach.&lt;&#x2F;p&gt;
&lt;p&gt;If any of this resonates or you are keen to embark on this self-development journey then do get in touch and we can trade ideas and inspiration.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tech lead lessons learned</title>
        <published>2025-07-04T00:00:00+00:00</published>
        <updated>2025-07-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/07/04/tech-lead-lessons-learned/"/>
        <id>https://0x5.uk/2025/07/04/tech-lead-lessons-learned/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/07/04/tech-lead-lessons-learned/">&lt;ol&gt;
&lt;li&gt;Love Jira. The main method of ensuring the team builds the right thing at the right time is a quality &amp;amp; well ordered backlog.&lt;&#x2F;li&gt;
&lt;li&gt;The team owns the stories and tickets. The tickets are just a tool for the team to manage the sheer volume of information and plans for what they want to build. If the team likes the tickets that&#x27;s all that matters. Definition of ready should be defined by the team, bounce tickets that don&#x27;t meet the standard.&lt;&#x2F;li&gt;
&lt;li&gt;Accept all approaches to engineering. You can nudge, discuss, encourage collaboration and best practice, and if anyone is way off then you should inform management, but in the end the tech lead isn&#x27;t responsible for hiring and firing so work with and celebrate what you have, even if it&#x27;s not how you&#x27;d do it.&lt;&#x2F;li&gt;
&lt;li&gt;Balance tech debt and maintenance with features sprint by sprint. Have a chore ticket every sprint for upgrades.&lt;&#x2F;li&gt;
&lt;li&gt;Fill in the gaps. Got a great product person then support them, if not then that&#x27;s you and you need to bridge to the business.&lt;&#x2F;li&gt;
&lt;li&gt;Retrospectives are broken. Refocus them on what the team can improve instead of complaining about things that will never change.&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s all about relationships.&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s (also) all about sustainable &amp;amp; quality delivery of product increments.&lt;&#x2F;li&gt;
&lt;li&gt;Stay sharp, pick something to build or fix yourself that isn&#x27;t on the critical path but makes life better for the team and the company and which keeps you intimately familiar with the technology.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;i-will-never-love-jira&quot;&gt;&quot;I will &lt;em&gt;never&lt;&#x2F;em&gt; love Jira.&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;Well it seems I accidentally &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;feed&#x2F;update&#x2F;urn:li:activity:7346930162711625729&#x2F;&quot;&gt;created some clickbait on LinkedIn by mentioning jira&lt;&#x2F;a&gt; there. To be clear my point is about having tickets refined, ordered and ready for the team just in time. I reference jira purely because that&#x27;s what every client I&#x27;ve dealt with for years has used.&lt;&#x2F;p&gt;
&lt;p&gt;Like many others I also don&#x27;t care much for Jira, but it let&#x27;s me create and refine tickets with enough info, comments and attachments so what-evs. Other tools welcome too.&lt;&#x2F;p&gt;
&lt;p&gt;If the client&#x2F;company has mandated jira then as a tech lead then you had better love being in there making it ship shape so the team can fly. It takes a good amount of a tech lead&#x27;s time. All that time spent in jira solo, with the devs and with the product people is all well invested as it&#x27;s a big enabler for the team to build the right things at the right time without being blocked waiting for tickets and requirements.&lt;&#x2F;p&gt;
&lt;p&gt;Ironically the better you are at this, the faster the team goes, and the quicker they are demanding more ready tickets!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why not WhatsApp?</title>
        <published>2025-07-02T00:00:00+00:00</published>
        <updated>2025-07-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/07/02/why-not-whatsapp/"/>
        <id>https://0x5.uk/2025/07/02/why-not-whatsapp/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/07/02/why-not-whatsapp/">&lt;p&gt;People regularly look at me like I&#x27;m from another planet when I say &lt;strong&gt;&quot;I&#x27;m not on WhatsApp&quot;&lt;&#x2F;strong&gt;. And I feel the need to explain myself. To save everyone from what is frankly quite a boring IRL conversation about privacy, surveillance, trust and data security, here&#x27;s a written consideration of the matter which you may read or ignore as you please.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Everyone&lt;&#x2F;em&gt; is on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.whatsapp.com&#x2F;&quot;&gt;WhatsApp&lt;&#x2F;a&gt;, right? So why not me? Why give up all that convenience, connection and network-effect?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trust-in-facebook&quot;&gt;Trust in Facebook&lt;&#x2F;h2&gt;
&lt;p&gt;I uninstalled Whatsapp and deleted the account after &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.forbes.com&#x2F;sites&#x2F;parmyolson&#x2F;2014&#x2F;10&#x2F;06&#x2F;facebook-closes-19-billion-whatsapp-deal&#x2F;&quot;&gt;facebook bought whatsapp&lt;&#x2F;a&gt; and changed the terms and conditions to allow &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arstechnica.com&#x2F;tech-policy&#x2F;2021&#x2F;01&#x2F;whatsapp-users-must-share-their-data-with-facebook-or-stop-using-the-app&#x2F;&quot;&gt;facebook to slurp up whatsapp data and add it to their ever-growing stash&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Facebook (aka Meta) have previously shown that they can&#x27;t be trusted with your data by way of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theregister.com&#x2F;2025&#x2F;06&#x2F;03&#x2F;meta_pauses_android_tracking_tech&#x2F;&quot;&gt;use of a &quot;localhost&quot; data collection back-door on Android&lt;&#x2F;a&gt; that completely disregard Android&#x27;s security measures,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mashable.com&#x2F;article&#x2F;facebook-android-phone-call-data-gathering&quot;&gt;collection of phone call logs&lt;&#x2F;a&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bbc.co.uk&#x2F;news&#x2F;business-37485589&quot;&gt;slurping up whatsapp data&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;but-everyone-s-on-it&quot;&gt;But everyone&#x27;s on it!&lt;&#x2F;h2&gt;
&lt;p&gt;A common argument I get for &lt;em&gt;&quot;just using it&quot;&lt;&#x2F;em&gt; is that everyone is on it, it&#x27;s convenient and basically I&#x27;m cutting myself off from social connections. YEAH I KNOW, I&#x27;m not happy about it, but in the end I can&#x27;t make my entire network of connections move to Signal or equivalent, so my only choice is to carry on feeding data and trusting the platform or give up on it all.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;i.imgflip.com&#x2F;9vau5q.jpg&quot; alt=&quot;WhatsApp they-don&amp;#39;t-know whatsapp was acquired by Meta party meme&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I did try having a WhatsApp account without the app on my phone and just using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.whatsapp.com&#x2F;&quot;&gt;WhatsApp Web&lt;&#x2F;a&gt; or keeping it on a secondary smart phone in a drawer somewhere for those people who don&#x27;t have Signal&#x2F;Telegram, but unfortunately then everyone sees an active WhatsApp account on my phone number and uses it to send me messages I don&#x27;t see and then wonder why I&#x27;m ignoring them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;disappearing-messages&quot;&gt;Disappearing messages&lt;&#x2F;h2&gt;
&lt;p&gt;The disjoint between ephemeral IRL conversations where you can say any stupid thing you&#x27;ll regret but it&#x27;s gone the moment you say it and WhatsApp chat logs where you can say any stupid thing and it&#x27;ll live for 10 years or more in your chat logs waiting to bite you hard when you&#x27;re a different person has bothered me for years.&lt;&#x2F;p&gt;
&lt;p&gt;When I dropped WhatsApp there was no capability to limit the history. They have since added &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;faq.whatsapp.com&#x2F;673193694148537&quot;&gt;disappearing WhatsApp messages&#x2F;chats&lt;&#x2F;a&gt; to WhatsApp (assuming you trust them to actually leave no trace).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;end-to-end-encryption&quot;&gt;End-to-end encryption&lt;&#x2F;h2&gt;
&lt;p&gt;But it&#x27;s &quot;end-to-end encrypted&quot; so that means it&#x27;s totally private and secure... right? Just by chain of logical thinking there is nothing to stop these companies silently breaking the end-to-end encryption for individual users but leaving the user unaware.&lt;&#x2F;p&gt;
&lt;p&gt;With the closed-source nature of these apps it is impossible to inspect the application and verify that it doesn&#x27;t have back-doors, bypasses, kill-switches, and in the end you have to trust the organisation providing you software. Even if it was open source, the regular &quot;security and convenience&quot; updates that you can&#x27;t opt out of (because securité) means they could theoretically push out a back-doored app just for you on your phone any time they like.&lt;&#x2F;p&gt;
&lt;p&gt;I have no evidence (obviously), but just by chain of logic, if the government is the ultimate authority in our democracies, and we the people actually want them to use whatever power is available to them to stop the &quot;bad guys&quot;, it makes logic sense that the law-abiding tech companies will largely do whatever the authorities say, including introducing back-doors and surveillance capabilities? I have no evidence, but the incentives make it highly likely, and of course they would have a &quot;gag&quot; in place so the tech companies could never reveal it otherwise it would ruin &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theverge.com&#x2F;2024&#x2F;5&#x2F;23&#x2F;24163389&#x2F;joseph-cox-dark-wire-fbi-phone-startup-anom-criminals-secure-messaging-decoder-interview&quot;&gt;the whole game&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Governments have long argued that E2E encryption is hampering the investigation of serious crimes, at least on a larger scale.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;portswigger.net&#x2F;daily-swig&#x2F;western-governments-double-down-efforts-to-curtail-end-to-end-encryption&quot;&gt;https:&#x2F;&#x2F;portswigger.net&#x2F;daily-swig&#x2F;western-governments-double-down-efforts-to-curtail-end-to-end-encryption&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Not to mention, even end to end encryption is no good if you &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lifehacker.com&#x2F;tech&#x2F;signal-is-private-sure-but-not-that-private&quot;&gt;accidentally add the wrong person to the chat&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lifehacker.com&#x2F;tech&#x2F;apple-spyware-warning-is-real&quot;&gt;your phone gets malware&#x27;d&lt;&#x2F;a&gt;. The malware would affect any app including Signal, so that&#x27;s really only a warning to turn on disappearing messages and keep your phone secure if you can.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nothing-to-hide&quot;&gt;&quot;Nothing to hide&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;Don&#x27;t get me wrong, I&#x27;m not doing this because I have anything particularly sensitive in my chat logs, I&#x27;m not a hacker, ethical or otherwise, I&#x27;m not a journalist, and I&#x27;m not any number of other things that might make you need to really hide stuff. But that doesn&#x27;t mean you shouldn&#x27;t be sensible with your data. We all say things we wish we hadn&#x27;t at times, even if it&#x27;s not something that&#x27;s going to get the authorities interested.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The &#x27;&lt;strong&gt;nothing to hide&lt;&#x2F;strong&gt;&#x27; argument is a &lt;strong&gt;logical fallacy&lt;&#x2F;strong&gt; which states that individuals have no reason to fear or oppose surveillance programs unless they are afraid it will uncover their own illicit activities&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Nothing_to_hide_argument&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Nothing_to_hide_argument&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;One day you&#x27;re law abiding, and the next day they change the laws. See the famous &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;First_They_Came&quot;&gt;&quot;First they came...&quot;&lt;&#x2F;a&gt;, and more recently some &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.msn.com&#x2F;en-us&#x2F;news&#x2F;us&#x2F;masked-ice-officers-the-new-calling-card-of-the-trump-administration-s-immigration-crackdown&#x2F;ar-AA1H9V0c&quot;&gt;troubling goings on with ICE in the USA&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alternatives&quot;&gt;Alternatives&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;signal.org&#x2F;&quot;&gt;Signal&lt;&#x2F;a&gt; - allegedly very secure. Not quite as nice to use.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;telegram.org&#x2F;&quot;&gt;Telegram&lt;&#x2F;a&gt; - possibly not any better, but it&#x27;s not owned by Facebook and I really like the UX&lt;&#x2F;li&gt;
&lt;li&gt;SMS - lowest common denominator. Sucks, know to be surveilled, but sometimes people I message are nothing but WhatsApp&lt;&#x2F;li&gt;
&lt;li&gt;iMessage - Apple&#x27;s walled garden. Meh. I don&#x27;t like Android, I like iPhones even less.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.androidauthority.com&#x2F;rcs-iphone-hands-on-3454911&#x2F;&quot;&gt;Rich Communication Services (RCS) protocol&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.forbes.com&#x2F;sites&#x2F;kalevleetaru&#x2F;2018&#x2F;07&#x2F;20&#x2F;facebook-as-the-ultimate-government-surveillance-tool&#x2F;&quot;&gt;Forbes: &quot;Facebook As The Ultimate Government Surveillance Tool?&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.eff.org&#x2F;deeplinks&#x2F;2025&#x2F;02&#x2F;when-platforms-and-government-unite-remember-whats-private-and-what-isnt&quot;&gt;EFF: &quot;When Platforms and the Government Unite, Remember What’s Private and What Isn’t&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.aclu.org&#x2F;news&#x2F;national-security&#x2F;is-the-government-tracking-your-social-media-activity&quot;&gt;ACLU: &quot;Is the Government Tracking Your Social Media Activity?&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bbc.co.uk&#x2F;news&#x2F;technology-27887639&quot;&gt;BBC: &quot;Google and Facebook can be legally intercepted, says UK spy boss&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theverge.com&#x2F;2024&#x2F;5&#x2F;23&#x2F;24163389&#x2F;joseph-cox-dark-wire-fbi-phone-startup-anom-criminals-secure-messaging-decoder-interview&quot;&gt;The Verge: How the FBI built its own smartphone company to hack the criminal underworld&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lifehacker.com&#x2F;tech&#x2F;signal-is-private-sure-but-not-that-private&quot;&gt;LifeHacker: Signal Is Private, Sure, but Not That Private&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bbc.co.uk&#x2F;news&#x2F;articles&#x2F;c20g288yldko&quot;&gt;BBC: UK demands access to Apple users&#x27; encrypted data - Feb 2025&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lifehacker.com&#x2F;tech&#x2F;apple-spyware-warning-is-real&quot;&gt;LifeHacker: &quot;This Spyware Warning From Apple Is Actually Real&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;light-relief-through-satire&quot;&gt;Light relief through satire&lt;&#x2F;h2&gt;
&lt;p&gt;Man that was depressing&#x2F;heavy&#x2F;boring.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s lighten up and finish with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=juQcZO_WnsI&quot;&gt;some amusing satire on facebook data collection from The Onion&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;juQcZO_WnsI?si=47GA1NG06ut6o7x9&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.snopes.com&#x2F;fact-check&#x2F;facebook-cia-zuckerberg&#x2F;&quot;&gt;Snopes: &quot;Is Facebook a CIA Surveillance Program?&quot; (i.e. People don&#x27;t realize The Onion is satirical)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Hidden Cost of Overusing AI Coding Tools: Tech Debt in Sheep’s Clothing</title>
        <published>2025-06-25T00:00:00+00:00</published>
        <updated>2025-06-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/06/25/ai-coding-tools---tech-debt-in-sheeps-clothing/"/>
        <id>https://0x5.uk/2025/06/25/ai-coding-tools---tech-debt-in-sheeps-clothing/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/06/25/ai-coding-tools---tech-debt-in-sheeps-clothing/">&lt;p&gt;My personal experience of coding with AI has not yet lived up to the promises and hype I am seeing online. While the initial contact with LLM code generation was certainly impressive, and I would not forego access to these tools, I find the longer term and larger scale results are thus far disappointing when compared to some of the breathless reports from many online voices, especially the vendors of AI wares.&lt;&#x2F;p&gt;
&lt;p&gt;What follows is a report on the currently published evidence highlighting the shortcomings and downsides of the promised AI coding revolution. GPT has helped my with the research (irony acknowledged), and produces a more journalistically pleasing style than I would do alone, but I have checked out all the referenced sources and quotes to make sure it&#x27;s not made anything up, and the assertions made herein are backed up by my own direct experience with the available tooling. You may consider this report biased, it is not intended to present both sides, it is intended to provide a single summary of the published information on the &lt;em&gt;shortcomings&lt;&#x2F;em&gt; of the current AI tools, and I hope you will find it does a good job of that. Contributions and corrections welcome as always on this most contentious and fast moving of topics.&lt;&#x2F;p&gt;
&lt;p&gt;It is not currently clear to me how much AI coding will improve, though many seem certain that it will, so I can only comment on the state of AI coding right now (June 2025), and I will be more than happy to hear of experiences, tools and approaches that are genuinely improving on the state of the art. I would very much enjoy being able to move towards using AI to build products that solve real problems that would have been out of reach with hand coding, and have made &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;FakeCosmosDb&quot;&gt;serious attempts to generate real projects with AI&lt;&#x2F;a&gt;, so don&#x27;t think I am some kind of luddite here, innovations are often painful and disruptive, but in the end leave humanity better off.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-productivity-mirage-vs-real-world-reliability&quot;&gt;The Productivity Mirage vs. Real-World Reliability&lt;&#x2F;h2&gt;
&lt;p&gt;Generative AI coding assistants (Copilot, ChatGPT, etc.) burst onto the scene with promises of rapid development and higher productivity. Yet many of these gains are a mirage. A recent study measuring real developer output found &lt;em&gt;“no significant gains”&lt;&#x2F;em&gt; from using an AI assistant – in fact, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cio.com&#x2F;article&#x2F;3540579&#x2F;devs-gaining-little-if-anything-from-ai-coding-assistants.html#:~:text=Many%20developers%20say%20AI%20coding,from%20coding%20and%20collaboration%20data&quot;&gt;code produced with GitHub Copilot contained &lt;strong&gt;41% more bugs&lt;&#x2F;strong&gt; than code written without it (cio.com&#x2F;uplevel)&lt;&#x2F;a&gt;. Developers may feel they’re moving faster, but hidden errors accumulate, leading to &lt;strong&gt;downtime&lt;&#x2F;strong&gt; and &lt;strong&gt;outages&lt;&#x2F;strong&gt; when that code hits production.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;code produced with GitHub Copilot contained &lt;strong&gt;41% more bugs&lt;&#x2F;strong&gt; than code written without it&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devclass.com&#x2F;2025&#x2F;02&#x2F;20&#x2F;ai-is-eroding-code-quality-states-new-in-depth-report&#x2F;#:~:text=an%20estimated%20reduction%20in%20delivery%20stability%20by%207.2%20percent&quot;&gt;Google’s own 2024 DevOps research noted a &lt;em&gt;7.2% drop in delivery stability&lt;&#x2F;em&gt; at organizations with high AI adoption (devclass.com&#x2F;DORA)&lt;&#x2F;a&gt;. In plain terms, shipping more code &lt;em&gt;faster&lt;&#x2F;em&gt; means little if that code breaks more often. As one tech CEO put it, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cio.com&#x2F;article&#x2F;3540579&#x2F;devs-gaining-little-if-anything-from-ai-coding-assistants.html#:~:text=%E2%80%9C-,It%20becomes%20increasingly%20more%20challenging%20to%20understand%20and%20debug%20the%20AI%2Dgenerated%20code%2C%20and%20troubleshooting%20becomes%20so%20resource%2Dintensive%20that%20it%20is%20easier%20to%20rewrite%20the%20code%20from%20scratch%20than%20fix%20it,-.%E2%80%9D&quot;&gt;&lt;em&gt;“It becomes increasingly more challenging to understand and debug the AI-generated code, and troubleshooting becomes so resource-intensive that it is easier to rewrite the code from scratch than fix it.”&lt;&#x2F;em&gt; (cio.com)&lt;&#x2F;a&gt; In other words, today’s AI helpers often create &lt;strong&gt;reliability&lt;&#x2F;strong&gt; nightmares that devour any time they initially saved.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;research noted a &lt;em&gt;7.2% drop in delivery stability&lt;&#x2F;em&gt; at organizations with high AI adoption&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;eroding-code-quality-and-maintainability&quot;&gt;Eroding Code Quality and Maintainability&lt;&#x2F;h2&gt;
&lt;p&gt;GitClear’s analysis of 211 million lines of code shows that in the AI era &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devclass.com&#x2F;2025&#x2F;02&#x2F;20&#x2F;ai-is-eroding-code-quality-states-new-in-depth-report&#x2F;#:~:text=The%20researchers%20found%20that%20the,quality%20without%20changing%20its%20function&quot;&gt;copy-pasted and new code is growing fast while refactoring plummets (devclass.com&#x2F;GitClear)&lt;&#x2F;a&gt;. More duplicated code and less refactoring for reuse equals more &lt;strong&gt;technical debt&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Empirical evidence is piling up that AI-generated code is &lt;strong&gt;harder to maintain&lt;&#x2F;strong&gt;. GitClear’s in-depth analysis found that AI coding tools are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devclass.com&#x2F;2025&#x2F;02&#x2F;20&#x2F;ai-is-eroding-code-quality-states-new-in-depth-report&#x2F;#:~:text=eroding%20code%20quality%20by%20increasing%20duplicated%20and%20copy&#x2F;pasted%20code%20and%20decreasing%20refactoring&quot;&gt;&lt;em&gt;“eroding code quality by increasing duplicated and copy&#x2F;pasted code and decreasing refactoring.”&lt;&#x2F;em&gt; (devclass.com&#x2F;GitClear)&lt;&#x2F;a&gt;. In 2024, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devclass.com&#x2F;2025&#x2F;02&#x2F;20&#x2F;ai-is-eroding-code-quality-states-new-in-depth-report&#x2F;#:~:text=the%20number%20of%20code%20blocks%20with%205%20or%20more%20duplicated%20lines%20increased%20by%208%20times%20during%202024&quot;&gt;the number of code blocks with 5 or more duplicated lines jumped &lt;strong&gt;8 times&lt;&#x2F;strong&gt; higher than before (devclass.com&#x2F;GitClear)&lt;&#x2F;a&gt;, a massive explosion of copy-paste coding.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;the number of code blocks with 5 or more duplicated lines jumped &lt;strong&gt;8 times&lt;&#x2F;strong&gt; higher&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Duplicate code might work at first, but it’s a ticking time bomb – bloating codebases and &lt;strong&gt;increasing defect risk&lt;&#x2F;strong&gt; whenever a change in one place isn’t carried over everywhere. Alarmingly, 2024 was the &lt;strong&gt;first year on record&lt;&#x2F;strong&gt; where engineers removed&#x2F;rewrote (“moved”) &lt;em&gt;far fewer&lt;&#x2F;em&gt; lines of code than they copy-pasted; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devclass.com&#x2F;2025&#x2F;02&#x2F;20&#x2F;ai-is-eroding-code-quality-states-new-in-depth-report&#x2F;#:~:text=The%20researchers%20also%20noted%20a,the%20number%20of%20moved%20lines&quot;&gt;refactoring activity dropped ~40% (based on moved lines) (devclass.com&#x2F;GitClear)&lt;&#x2F;a&gt;. This matters because experienced human developers constantly refactor – they consolidate logic into reusable modules and improve clarity. That’s how we keep systems clean and adaptable. AI, by contrast, tends to paste new blocks wholesale without understanding the bigger design. The result is &lt;strong&gt;spaghetti code&lt;&#x2F;strong&gt; that might function today but becomes a nightmare tomorrow. As GitClear observes, the ability to &lt;strong&gt;“consolidate previous work into reusable modules”&lt;&#x2F;strong&gt; is an essential advantage human programmers have over AI – and we’re seeing significantly less of it in AI-influenced codebases.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;AI, by contrast, tends to paste new blocks wholesale without understanding the bigger design.&lt;&#x2F;p&gt;
&lt;p&gt;The result is spaghetti code that might function today but becomes a nightmare tomorrow.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In short, forcing programmers to over-rely on LLMs is &lt;strong&gt;injecting new tech debt&lt;&#x2F;strong&gt; into projects at unprecedented scale – an invisible debt that will come due with heavy interest in the form of difficult changes and costly bugs down the line. The programmers may be the ones who have to clean up the mess, but it&#x27;s the businesses, executives and their customers who will bear the &lt;strong&gt;real costs&lt;&#x2F;strong&gt; of failures, security flaws and loss of agility.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bugs-outages-and-the-risk-of-downtime&quot;&gt;Bugs, Outages and the Risk of Downtime&lt;&#x2F;h2&gt;
&lt;p&gt;It’s not just code aesthetics at stake – it’s uptime and business continuity. What good is cranking out features faster if your service becomes flaky or falls over in production? Unfortunately, organizations pushing LLM-generated code are reporting &lt;strong&gt;more fires to fight&lt;&#x2F;strong&gt;. In one survey of 500 software engineering leaders &amp;amp; practitioners, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=Harness%20found%2059,when%20using%20AI%20coding%20tools&quot;&gt;&lt;strong&gt;59%&lt;&#x2F;strong&gt; said that when using AI coding tools, they encounter problems in &lt;strong&gt;at least half&lt;&#x2F;strong&gt; of their code deployments (itpro.com&#x2F;Harness)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Each failed deployment could mean&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;an outage,&lt;&#x2F;li&gt;
&lt;li&gt;a rollback,&lt;&#x2F;li&gt;
&lt;li&gt;or sometimes hours of emergency troubleshooting.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;&lt;strong&gt;59%&lt;&#x2F;strong&gt; said that when using AI coding tools, they encounter problems in &lt;strong&gt;at least half&lt;&#x2F;strong&gt; of their code deployments&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Even more worrying, &lt;strong&gt;92%&lt;&#x2F;strong&gt; of respondents noted that while AI tools do increase the volume of code shipped to production, they also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=they%20noted%20they%20also%20increased%20the%20%E2%80%98blast%20radius%E2%80%99%20of%20a%20bad%20deployment.&quot;&gt;&lt;strong&gt;increase the “blast radius” of bad deployments&lt;&#x2F;strong&gt; (itpro.com&#x2F;Harness)&lt;&#x2F;a&gt;. In other words, when AI-assisted code blows up, it tends to create a &lt;em&gt;bigger mess&lt;&#x2F;em&gt; – affecting more modules and users – than traditionally written code. More surface area for failures means higher chances of severe downtime or cascading outages.&lt;&#x2F;p&gt;
&lt;p&gt;The reliability red flags don’t stop there. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=Just%20over%20half%20%2852,an%20increase%20in%20performance%20problems&quot;&gt;Over &lt;strong&gt;half&lt;&#x2F;strong&gt; of engineering leaders have observed a rise in security vulnerabilities and &lt;strong&gt;incidents&lt;&#x2F;strong&gt; after adopting AI-generated code (itpro.com&#x2F;Harness)&lt;&#x2F;a&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=Just%20over%20half%20%2852,an%20increase%20in%20performance%20problems&quot;&gt;Performance problems are cropping up as well (itpro.com&#x2F;Harness)&lt;&#x2F;a&gt;. These are exactly the sort of issues that lead to unplanned downtime and frantic late-night calls.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Over &lt;strong&gt;half&lt;&#x2F;strong&gt; of engineering leaders have observed a rise in security vulnerabilities and &lt;strong&gt;incidents&lt;&#x2F;strong&gt;&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Remember, downtime isn’t just an IT headache – it’s a &lt;strong&gt;financial nightmare&lt;&#x2F;strong&gt;. Recent research shows &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bigpanda.io&#x2F;blog&#x2F;it-outage-costs-2024&#x2F;#:~:text=Costs%20are%20rising.%20Unplanned%20downtime%20now%20averages%20:~:text=For%20years%2C%20the%20IT%20industry,to%20%2423%2C750%20for%20large%20enterprises4%2C056%20per%20minute%2C%20rising%20to%20$23%2C750%20for%20large%20enterprises&quot;&gt;unplanned IT outages now &lt;strong&gt;cost&lt;&#x2F;strong&gt; businesses on average about &lt;strong&gt;$14,000 per minute&lt;&#x2F;strong&gt;, rising to &lt;strong&gt;$23,000 per minute&lt;&#x2F;strong&gt; for large enterprises (bigpanda.io)&lt;&#x2F;a&gt;. Imagine a critical system going down for an hour due to a subtle bug in AI-written code – that could be a seven-figure loss, not even counting reputational damage.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;unplanned IT outages now &lt;strong&gt;cost&lt;&#x2F;strong&gt; businesses on average about &lt;strong&gt;$14,000 per minute&lt;&#x2F;strong&gt;&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It’s telling that Google’s DevOps report measured a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devclass.com&#x2F;2025&#x2F;02&#x2F;20&#x2F;ai-is-eroding-code-quality-states-new-in-depth-report&#x2F;#:~:text=the%20DORA%20report%20also%20identified,more%20prone%20to%20creating%20instability.%E2%80%9D&quot;&gt;&lt;em&gt;decrease&lt;&#x2F;em&gt; in overall software &lt;strong&gt;stability&lt;&#x2F;strong&gt; (devclass.com&#x2F;GitClear)&lt;&#x2F;a&gt; even as individual code snippets maybe got a bit cleaner.&lt;&#x2F;p&gt;
&lt;p&gt;Faster code delivery means nothing if it comes hand-in-hand with more frequent &lt;strong&gt;outages&lt;&#x2F;strong&gt;. Reliability is king in production, we even fund entire highly skilled and highly paid Site Reliability Engineering (SRE) teams to ensure reliability, and right now these AI coding tools are undermining it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;slower-progress-and-mounting-costs&quot;&gt;Slower Progress and Mounting Costs&lt;&#x2F;h2&gt;
&lt;p&gt;Paradoxically, the push to “speed up” development with LLMs can end up &lt;strong&gt;slowing you down&lt;&#x2F;strong&gt; in the long run. Teams quickly discover that AI-generated code isn’t a free lunch – you pay for it in &lt;strong&gt;verification and fixes&lt;&#x2F;strong&gt;. A majority of developers report that using AI assistants has &lt;em&gt;increased&lt;&#x2F;em&gt; the overhead of code reviews, testing, and debugging. In the same survey, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=67%25%20developers%20said%20they%20spend%20more%20time%20debugging%20AI%2Dgenerated%20code&quot;&gt;&lt;strong&gt;67%&lt;&#x2F;strong&gt; of developers said they now spend &lt;strong&gt;more time debugging&lt;&#x2F;strong&gt; AI-generated code (itpro.com&#x2F;Harness)&lt;&#x2F;a&gt; (chasing down the AI’s mistakes), and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=68%25%20spent%20more%20time%20resolving%20security%20vulnerabilities%20after%20adopting%20AI%20tools&quot;&gt;&lt;strong&gt;68%&lt;&#x2F;strong&gt; spend more time &lt;strong&gt;fixing security flaws&lt;&#x2F;strong&gt; introduced by AI suggestions (itpro.com&#x2F;Harness)&lt;&#x2F;a&gt;. This extra toil directly eats into time that could have built new features or improved customer experience. In fact, engineers note that this &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=The%20report%20argued%20that%20while%20AI%20accelerates%20code%20production%20it%20ultimately%20creates%20%E2%80%9Cnew%20demands%20around%20code%20review%2C%20security%20validation%2C%20and%20quality%20assurance%20%5BQA%5D.%E2%80%9D&quot;&gt;&lt;em&gt;“increased verification overhead”&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=this%20%E2%80%9Cincreased%20verification%20overhead%E2%80%9D%20offsets%20a%20%E2%80%9Cconsiderable%20amount%20of%20the%20productivity%20gains%E2%80%9D&quot;&gt;offsetting a &lt;strong&gt;considerable amount of the productivity gains&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; AI was supposed to bring. More code is getting written, yes – but &lt;strong&gt;more code = more to read, review, test, QA, troubleshoot and rework&lt;&#x2F;strong&gt;. As developers we&#x27;ve known for a very long time that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@harshithgowdakt&#x2F;every-line-of-code-you-write-is-a-liability-400d623a54c9&quot;&gt;Every Line of Code You Write Is a Liability&lt;&#x2F;a&gt; and that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.codinghorror.com&#x2F;the-best-code-is-no-code-at-all&#x2F;&quot;&gt;The Best Code is No Code At All&lt;&#x2F;a&gt;, so is it really a surprise that producing higher volumes of code with an unthinking LLM is turning out to have downsides?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;engineers note that this “increased verification overhead” is offsetting a considerable amount of the productivity gains AI was supposed to bring&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Even worse than the massive costs of time being spent by diligent developers fixing the AI generated security flaws before shipping is the developers who ship make themselves look like 100x engineers, blasting through tickets and story points twice as fast as their peers by not &quot;wasting&quot; any time at all even &lt;em&gt;looking&lt;&#x2F;em&gt; for security flaws and maintainability problems in the AI-generated code, thus leaving the organisation wide open to risk of cyberattacks. There is huge pressure on development teams right now to be ever more &quot;productive&quot; in the eyes of people who do not understand the difference between good code and bad code, so the incentives to just &quot;vibe code&quot; and ship whatever the AI produces is almost irresistible, especially when the &quot;slowest&quot; engineers are often unceremoniously fired in this highly competitive and budget constrained environment. Ironically the worst engineers are likely to move the fastest with AI as they blindly trust its output without knowing any better, massively increasing the risks to the organisation and the stability, flexibility and maintainability of the delivered systems.&lt;&#x2F;p&gt;
&lt;p&gt;Looking at pull requests and release cycles: one study found &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cio.com&#x2F;article&#x2F;3540579&#x2F;devs-gaining-little-if-anything-from-ai-coding-assistants.html#:~:text=The%20study%20measured%20pull%20request%20(PR)%20cycle%20time%2C%20or%20the%20time%20to%20merge%20code%20into%20a%20repository%2C%20and%20PR%20throughput%2C%20the%20number%20of%20pull%20requests%20merged.%20It%20found%20no%20significant%20improvements%20for%20developers%20using%20Copilot.&quot;&gt;&lt;strong&gt;no improvement in merge times or throughput&lt;&#x2F;strong&gt; for developers using Copilot (cio.com&#x2F;Uplevel)&lt;&#x2F;a&gt;. Any code churn savings were nullified by the need to double-check AI output or deal with new defects. As one report aptly stated, &lt;em&gt;AI accelerates code production but&lt;&#x2F;em&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=ultimately%20creates%20%E2%80%9Cnew%20demands%20around%20code%20review%2C%20security%20validation%2C%20and%20quality%20assurance%20%5BQA%5D.%E2%80%9D&quot;&gt;&lt;em&gt;ultimately creates “new demands around code review, security validation, and [QA].”&lt;&#x2F;em&gt; (itpro.com&#x2F;Harness)&lt;&#x2F;a&gt;. All that translates to &lt;strong&gt;inability to ship new features&lt;&#x2F;strong&gt; at the pace leadership expects, because developers are tied up in a perpetual game of AI code whack-a-mole. Instead of focusing on new business initiatives, your team is stuck &lt;strong&gt;fixing&lt;&#x2F;strong&gt; and re-architecting what the AI churned out. In practical terms, that’s lost opportunity.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;one study found no improvement in merge times or throughput for developers using Copilot&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This overhead has real financial cost. Consider debugging and rework: if highly-paid engineers are burning hours combing through AI-written code for errors or going back to find out which bit of the AI generated code broke production or resulted in a security breach the dollars add up fast. &lt;strong&gt;78%&lt;&#x2F;strong&gt; of developers say they spend at least 30% of their time on manual tasks (like writing compliance policies, conducting quality assurance testing, and error remediation) – &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code#:~:text=Using%20the%20average%20developer%20salary%20of%20:~:text=Using%20the%20average%20developer%20salary,of%20wasted%20investment%20per%20developer07%2C599%2C%20Harness%20found%20that%20if%20devs%20are%20spending%2030%25%20of%20their%20time%20on%20manual%20tasks%2C%20this%20would%20equate%20to%20$32%2C280%20of%20wasted%20investment%20per%20developer.&quot;&gt;equating to about &lt;strong&gt;$32,000 of salary per developer per year&lt;&#x2F;strong&gt; wasted (itpro.com&#x2F;Harness)&lt;&#x2F;a&gt; on work not directly contributing to product output. Scaled to a team of 25 devs, that’s roughly &lt;strong&gt;$800,000&lt;&#x2F;strong&gt; in lost productivity annually – including the hidden &lt;strong&gt;cost-of-fix&lt;&#x2F;strong&gt; for subpar code. Now imagine a chunk of that burden is increasingly becoming AI’s “bad output tax.” It’s like taking on a bunch of junior developers who can churn out code quickly but require senior engineers to babysit and clean up after them. The &lt;strong&gt;cost to fix&lt;&#x2F;strong&gt; issues later (in debugging, outages, patches, compliance work, etc.) &lt;em&gt;far exceeds&lt;&#x2F;em&gt; the cost to do it right upfront. No wonder some teams report that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.turintech.ai&#x2F;blog&#x2F;the-hidden-cost-of-ai-generated-code-what-research-and-industry-trends-are-revealing#:~:text=The%20paper%20highlights%20that%20increased%20AI%2Dgenerated%20code%20does%20not%20equate%20to%20faster%20software%20delivery.&quot;&gt;adopting AI coding tools actually &lt;em&gt;slowed&lt;&#x2F;em&gt; their feature delivery due to the remediation workload (turintech.ai)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps the most damning feedback comes from the trenches: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cio.com&#x2F;article&#x2F;3540579&#x2F;devs-gaining-little-if-anything-from-ai-coding-assistants.html#:~:text=becomes%20so%20resource%2Dintensive-,that%20it%20is%20easier%20to%20rewrite%20the%20code%20from%20scratch%20than%20fix%20it,-%2C%E2%80%9D%20he%20says.&quot;&gt;&lt;em&gt;“It is easier to rewrite the code from scratch than fix it”&lt;&#x2F;em&gt; (cio.com)&lt;&#x2F;a&gt; when it’s generated by current AI tools. Think about that. Throwaway code, maintainability so poor that starting over is preferable. That is the &lt;strong&gt;very definition of &lt;a href=&quot;&#x2F;2020&#x2F;07&#x2F;09&#x2F;approaches-to-refactoring-and-technical-debt&#x2F;&quot;&gt;technical debt&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;. Every time your developers have to scrap an AI-generated module and re-implement it properly, you’ve doubled the work and lost precious time. This is the “new tech debt in sheep’s clothing” – it sneaks in under the guise of rapid development, but later you pay through the nose to correct, refactor, or replace it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hype-vs-reality-don-t-buy-fool-s-gold&quot;&gt;Hype vs. Reality: Don’t Buy Fool’s Gold&lt;&#x2F;h2&gt;
&lt;p&gt;It’s easy to be swept up in the hype. In today’s “AI revolution,” many technical folks are eagerly justifying these tools – some genuinely optimistic, others perhaps seeing &lt;strong&gt;fool’s gold&lt;&#x2F;strong&gt; in the latest trend. We’ve all heard enthusiastic voices touting how AI will write flawless code and free us from grunt work. But as an engineering leader, you must cut through that noise. The facts on the ground are clear: current LLM-based coding tools are &lt;strong&gt;not&lt;&#x2F;strong&gt; on par with an experienced human engineer when it comes to producing clean, robust, supportable code. They might get there someday, but &lt;strong&gt;today they’re not even close&lt;&#x2F;strong&gt;. As one industry expert observed, we risk &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;junior-developer-ai-tools-coding-skills#:~:text=%E2%80%9C-,We%E2%80%99re%20trading%20deep%20understanding%20for%20quick%20fixes,-%2C%20and%20while%20it&quot;&gt;&lt;em&gt;“trading deep understanding for quick fixes”&lt;&#x2F;em&gt; (itpro.com&#x2F;Goel)&lt;&#x2F;a&gt; by over-relying on AI, especially with less-experienced devs. That trade-off can &lt;strong&gt;backfire&lt;&#x2F;strong&gt; spectacularly when complex systems start misbehaving. It&#x27;s hard to fix a complex system when you never understood how it worked in the first place.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The facts on the ground are clear: current LLM-based coding tools are not on par with an experienced human engineer when it comes to producing clean, robust, supportable code.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;None of this is to say AI has no place in software development – it can be a handy helper for boilerplate suggestions or exploration. The key is &lt;strong&gt;not to overuse or force it on programmers&lt;&#x2F;strong&gt; as a substitute for proper engineering practice. Wise CTOs and architects will treat AI outputs as junior developer code: useful, but to be thoroughly reviewed, tested, and often heavily refactored.&lt;&#x2F;p&gt;
&lt;p&gt;Blind faith in the current generation of LLMs is misplaced. They don’t understand your business domain, architecture, or quality standards – so treat the hype with healthy skepticism. The cost of getting it wrong isn’t just a petty code style issue; it’s &lt;strong&gt;lost revenue from outages&lt;&#x2F;strong&gt;, &lt;strong&gt;ballooning maintenance costs&lt;&#x2F;strong&gt;, and &lt;strong&gt;slower time-to-market&lt;&#x2F;strong&gt; for new initiatives while your team struggles under a mountain of AI-induced rework. In short, rushing unwarranted AI-generated code into your core systems can put your company on a fast track to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;charmconsulting.co.uk&#x2F;2020&#x2F;11&#x2F;27&#x2F;leaders-guide-to-technical-debt&#x2F;&quot;&gt;the kind of &lt;strong&gt;technical debt&lt;&#x2F;strong&gt; that cripples agility&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Blind faith in the current generation of LLMs is misplaced&lt;br &#x2F;&gt;
...&lt;br &#x2F;&gt;
a fast track to the kind of technical debt that cripples agility.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;conclusion-mitigate-now-or-pay-more-later&quot;&gt;Conclusion: Mitigate Now, or Pay (More) Later&lt;&#x2F;h2&gt;
&lt;p&gt;As someone with over 20 years in software engineering, I’ve seen this pattern before. Whether it was systems built by ultra-low-cost outsourcers or by undertrained teams, the result is the same: &lt;strong&gt;poor-quality code leads to pain&lt;&#x2F;strong&gt;. LLM-generated code, when overused, is &lt;em&gt;not that different&lt;&#x2F;em&gt;. It promises the world, but if you’re not extremely careful, you end up with a fragile, convoluted system that &lt;strong&gt;bleeds money and time&lt;&#x2F;strong&gt; to fix. The wise move for any technology executive today is to approach AI coding tools with &lt;strong&gt;eyes open&lt;&#x2F;strong&gt;. Establish strict guidelines, monitor code quality metrics, invest in additional testing and AI code validation if you do use them – and above all, don’t let the excitement over AI overshadow fundamental engineering principles. If a shortcut seems too good to be true, it probably is.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, be prepared: if you discover down the road that your codebase has become an unmaintainable AI-generated house of cards, don’t panic. &lt;strong&gt;I can help.&lt;&#x2F;strong&gt; I’ve spent years untangling disastrous, brittle systems and turning them into solid, scalable platforms. The sooner you address the issue, the less &lt;strong&gt;downtime&lt;&#x2F;strong&gt; and cost you’ll suffer.&lt;&#x2F;p&gt;
&lt;p&gt;Technology trends come and go, but solid software engineering practices are timeless. When the hype dust settles and the &lt;strong&gt;consequences&lt;&#x2F;strong&gt; of over-relying on today’s LLMs rear their head, make sure you have seasoned experts on hand to set things right. &lt;em&gt;You don’t have to wait for an outage to take action – let’s connect and ensure your software foundation stays strong.&lt;&#x2F;em&gt; Your future self (and your customers and CFO) will thank you.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources-references-further-reading&quot;&gt;Sources, references &amp;amp; further reading&lt;&#x2F;h2&gt;
&lt;p&gt;This article is based on recent research and industry reports on AI-generated code quality and business impact. Full list of sources below.&lt;&#x2F;p&gt;
&lt;p&gt;The case is getting stronger that the hype is not bourne out by the actual results being observed in industry when studied rigorously beyond individual anecdote, the wow-factor of first encounters with an LLM, marketing-hype and studies commissioned by the AI vendors.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;in-depth-reports-research&quot;&gt;In depth reports &amp;amp; research&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The adoption of AI codegen tools thus far has actually resulted in a significant increase in the developer workload–while AI accelerates initial code production, it creates new demands around code review, security validation, and quality assurance. This increased verification overhead arguably offsets a considerable amount of the productivity gains.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.harness.io&#x2F;state-of-software-delivery#:~:text=The%20adoption%20of%20AI%20codegen,%E2%80%8D&quot;&gt;&quot;The State of Software Delivery Report 2025: Beyond CodeGen: The Role of AI in the SDLC&quot; - harness.io&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;our research revealed a critical finding: AI adoption may negatively impact software delivery performance. As AI adoption increased, it was accompanied by an estimated  decrease in delivery throughput by 1.5%, and an estimated reduction in delivery stability by 7.2%. Our data suggest that improving the development process does not automatically improve software delivery&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;blog&#x2F;products&#x2F;devops-sre&#x2F;announcing-the-2024-dora-report#:~:text=our%20research%20revealed%20a%20critical,not%20automatically%20improve%20software%20delivery&quot;&gt;Google DORA 2024 report&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Developers with Copilot access saw a significantly higher bug rate while their issue throughput remained consistent&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;resources.uplevelteam.com&#x2F;gen-ai-for-coding#:~:text=Developers%20with%20Copilot%20access%20saw%20a%20significantly%20higher%20bug%20rate%20while%20their%20issue%20throughput%20remained%20consistent.&quot;&gt;&quot;Gen AI for Coding&quot; Research Report - Uplevel Data Labs&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;We observe a spike in the prevalence of duplicate code blocks, along with increases in short-term churn code, and the continued decline of moved lines (code reuse).&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gitclear.com&#x2F;ai_assistant_code_quality_2025_research#:~:text=We%20observe%20a%20spike%20in%20the%20prevalence%20of%20duplicate%20code%20blocks%2C%20along%20with%20increases%20in%20short%2Dterm%20churn%20code%2C%20and%20the%20continued%20decline%20of%20moved%20lines%20(code%20reuse).&quot;&gt;&quot;AI Copilot Code Quality: 2025 Data Suggests 4x Growth in Code Clones&quot; - GitClear&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I decided to investigate more systematically how well such AI startups were doing. I found that many were proving not nearly as valuable to society as all the hype would suggest.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;spectrum.ieee.org&#x2F;ai-and-economic-productivity-expect-evolution-not-revolution#:~:text=I%20decided%20to%20investigate%20more%20systematically%20how%20well%20such%20AI%20startups%20were%20doing.%20I%20found%20that%20many%20were%20proving%20not%20nearly%20as%20valuable%20to%20society%20as%20all%20the%20hype%20would%20suggest.&quot;&gt;&quot;AI and Economic Productivity: Expect Evolution, Not Revolution&quot; - IEEE Spectrum, 2019&lt;&#x2F;a&gt; by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;dr-jeffrey-funk-a979435&#x2F;&quot;&gt;Dr. Jeffrey Funk&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;published-articles&quot;&gt;Published articles&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;It becomes increasingly more challenging to understand and debug the AI-generated code, and troubleshooting becomes so resource-intensive that it is easier to rewrite the code from scratch than fix it.&quot; - Ivan Gekht, CEO, Gehtsoft&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cio.com&#x2F;article&#x2F;3540579&#x2F;devs-gaining-little-if-anything-from-ai-coding-assistants.html#:~:text=%E2%80%9CIt%20becomes%20increasingly%20more%20challenging,%E2%80%94Ivan%20Gekht%2C%20CEO%2C%20Gehtsoft&quot;&gt;&quot;Devs gaining little (if anything) from AI coding assistants&quot; - CIO.com&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;It is easy to say, as Google does, that organizations should establish guidelines for use of AI to address concerns; but tools which encourage bad practice will inevitably increase bad practice until they are improved.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devclass.com&#x2F;2025&#x2F;02&#x2F;20&#x2F;ai-is-eroding-code-quality-states-new-in-depth-report&#x2F;#:~:text=It%20is%20easy%20to%20say%2C%20as%20Google%20does%2C%20that%20organizations%20should%20establish%20guidelines%20for%20use%20of%20AI%20to%20address%20concerns;%20but%20tools%20which%20encourage%20bad%20practice%20will%20inevitably%20increase%20bad%20practice%20until%20they%20are%20improved.&quot;&gt;&quot;AI is eroding code quality states new in-depth report - devclass.com&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Costs are rising. Unplanned downtime now averages $14,056 per minute, rising to $23,750 for large enterprises.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bigpanda.io&#x2F;blog&#x2F;it-outage-costs-2024&#x2F;&quot;&gt;&quot;The rising costs of downtime - BigPanda&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;AI-generated code is increasing the burden on development teams, rather than reducing it.  This isn’t just an isolated finding. Across the industry, teams are realizing that while AI can accelerate code production, it often introduces new inefficiencies in validation, security, and maintainability.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.turintech.ai&#x2F;blog&#x2F;the-hidden-cost-of-ai-generated-code-what-research-and-industry-trends-are-revealing&quot;&gt;&quot;The Hidden Cost of AI-Generated Code: What Research and Industry Trends Are Revealing - TurinTech AI&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Sure, the code works, but ask &lt;em&gt;why&lt;&#x2F;em&gt; it works that way instead of another way? Crickets. Ask about edge cases? Blank stares.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nmn.gl&#x2F;blog&#x2F;ai-and-learning#:~:text=Sure%2C%20the%20code%20works%2C%20but%20ask%20why%20it%20works%20that%20way%20instead%20of%20another%20way?%20Crickets.%20Ask%20about%20edge%20cases?%20Blank%20stares.&quot;&gt;New Junior Developers Can’t Actually Code - N’s Blog&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Every line of code has the potential to contain bugs or errors, leading to unexpected behaviour, system crashes, or incorrect results.&lt;br &#x2F;&gt;
...&lt;br &#x2F;&gt;
Code can inadvertently create security holes that attackers might exploit to gain unauthorized access or disrupt services.&quot;
~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@harshithgowdakt&#x2F;every-line-of-code-you-write-is-a-liability-400d623a54c9#:~:text=Every%20line%20of%20code%20has%20the%20potential%20to%20contain%20bugs%20or%20errors%2C%20leading%20to%20unexpected%20behaviour%2C%20system%20crashes%2C%20or%20incorrect%20results.&quot;&gt;Every Line of Code You Write Is a Liability ~ Harshith Gowda&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;the best code is no code at all. Every new line of code you willingly bring into the world is code that has to be debugged, code that has to be read and understood, code that has to be supported. Every time you write new code, you should do so reluctantly, under duress, because you completely exhausted all your other options. Code is only our enemy because there are so many of us programmers writing so damn much of it. If you can’t get away with no code, the next best thing is to start with brevity.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.codinghorror.com&#x2F;the-best-code-is-no-code-at-all&#x2F;#:~:text=the%20best%20code%20is%20no,is%20to%20start%20with%20brevity.&quot;&gt;The Best Code is No Code At All ~ Jeff Atwood&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;“A mess is not a technical debt. A mess is just a mess.” ~ Uncle Bob&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;2020&#x2F;07&#x2F;09&#x2F;approaches-to-refactoring-and-technical-debt&#x2F;&quot;&gt;Approaches to refactoring, technical debt and legacy code&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;We need to rewrite x&#x2F;y, or maybe even the entire system&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;charmconsulting.co.uk&#x2F;2020&#x2F;11&#x2F;27&#x2F;leaders-guide-to-technical-debt&#x2F;&quot;&gt;Leaders guide to technical debt - aka &quot;why can&#x27;t we ship anything!?&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;secondary-articles&quot;&gt;Secondary articles&lt;&#x2F;h3&gt;
&lt;p&gt;These are journalistic pieces based on other primary sources listed in this article:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;junior-developer-ai-tools-coding-skills&quot;&gt;&quot;‘We’re trading deep understanding for quick fixes’: Junior software developers lack coding skills because of an overreliance on AI tools – and it could spell trouble for the future of development - itpro.com&quot;&lt;&#x2F;a&gt; - based on N&#x27;s blog (above)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itpro.com&#x2F;software&#x2F;development&#x2F;ai-coding-tools-arent-the-solution-to-the-unfolding-developer-crisis-teams-think-they-can-boost-productivity-and-delivery-times-but-end-up-bogged-down-by-manual-remediation-and-unsafe-code&quot;&gt;&quot;AI coding tools aren’t the solution to the unfolding &#x27;developer crisis&#x27;&quot;- itpro.com&quot;&lt;&#x2F;a&gt; - Based on the Harness report (above)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to upload kindle fire kids photos to amazon photos</title>
        <published>2025-05-20T00:00:00+00:00</published>
        <updated>2025-05-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/05/20/how-to-upload-kindle-fire-kids-photos-to-amazon-photos/"/>
        <id>https://0x5.uk/2025/05/20/how-to-upload-kindle-fire-kids-photos-to-amazon-photos/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/05/20/how-to-upload-kindle-fire-kids-photos-to-amazon-photos/">&lt;p&gt;This is a bit off my normal subject, so ignore this if you are not a user of the amazon kindle fire kids tablets.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-upset-kindle-users&quot;&gt;Other upset kindle users&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve been having a world of pain trying to get the kids&#x27; photos off their old tablet before sending it back, fortunately before it was completely broken. Apparently I&#x27;m not alone:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;sivx7d&#x2F;getting_photos_and_videos_off_of_kids_fire&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;sivx7d&#x2F;getting_photos_and_videos_off_of_kids_fire&#x2F;&lt;&#x2F;a&gt; “Granddaughter takes photos constantly on her Fire HD 8 Kids Edition… but how do we get them off? Nothing is backed up.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;19bmn8h&#x2F;backup_copy_photos_and_videos_from_fire_tablet_7&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;19bmn8h&#x2F;backup_copy_photos_and_videos_from_fire_tablet_7&#x2F;&lt;&#x2F;a&gt; “No way of getting photos off of a Fire 7 Kids profile… Amazon Photos doesn’t back them up.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;1gv8t83&#x2F;fire_8_kids_photos_gone_after_nov_18_update&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;1gv8t83&#x2F;fire_8_kids_photos_gone_after_nov_18_update&#x2F;&lt;&#x2F;a&gt; “My daughter’s Fire 8 is no longer indexing the photos after yesterday’s update. They’re gone.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;1evpxyj&#x2F;photos_app_replaced_with_gallery&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;1evpxyj&#x2F;photos_app_replaced_with_gallery&#x2F;&lt;&#x2F;a&gt; “Amazon Photos app was removed and replaced with Gallery… which doesn’t auto-sync to the cloud.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;jxfkwx&#x2F;backing_up_photos_on_a_fire_7_kids_profile&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;kindlefire&#x2F;comments&#x2F;jxfkwx&#x2F;backing_up_photos_on_a_fire_7_kids_profile&#x2F;&lt;&#x2F;a&gt; “Found an Auto Save toggle buried in settings. Why isn’t this on by default?”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forums.digitalspy.com&#x2F;discussion&#x2F;2433516&#x2F;copying-files-from-amazon-fire-kids-tablet&quot;&gt;https:&#x2F;&#x2F;forums.digitalspy.com&#x2F;discussion&#x2F;2433516&#x2F;copying-files-from-amazon-fire-kids-tablet&lt;&#x2F;a&gt; “Wife checked Amazon Photos and nothing’s there. The tablet doesn’t show up as a drive either.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forums.moneysavingexpert.com&#x2F;discussion&#x2F;6280419&#x2F;kindle-fire-for-kids-would-like-to-backup-videos-onto-my-computer-not-onto-amazon-photos&quot;&gt;https:&#x2F;&#x2F;forums.moneysavingexpert.com&#x2F;discussion&#x2F;6280419&#x2F;kindle-fire-for-kids-would-like-to-backup-videos-onto-my-computer-not-onto-amazon-photos&lt;&#x2F;a&gt; “Trying to copy my kids’ videos off the Fire tablet — they’re hidden and Photos won’t back them up fully.”&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;failed-support-escalations&quot;&gt;Failed support escalations&lt;&#x2F;h2&gt;
&lt;p&gt;Having spent several hours on amazon&#x27;s chat support and got nowhere (they clearly don&#x27;t have a clue and have no escalation path) I turned to chat-gpt to help and it let me know that if you email a bunch of amazon executive email accounts you get fast-tracked to a non-idiot for better support. (Why they can&#x27;t just escalate from chat is beyond me, and yes I did ask both on chat and phone support to be put through to more senior folks, to no avail, complete dead end). These emails got a response from an intelligent and helpful human-being, who managed to fine a very obscure and gnarly way to at least upload the photos as a one-time upload. Seeing as it&#x27;s nigh on impossible to find I&#x27;ll document it here for anyone else who needs it, and for myself next time round. I hope the support person is able to knock heads together of the actual product teams as promised as they&#x27;ve really screwed up this one compared to the seamless background cloud upload folks have come to expect from their google and apple devices.&lt;&#x2F;p&gt;
&lt;p&gt;It has been confirmed that the amazon photos app has been killed in the android fire ecosystem, leaving only full android with a functioning photo sync.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-1-enable-parent-viewing-of-photos&quot;&gt;Step 1 - enable parent viewing of photos&lt;&#x2F;h2&gt;
&lt;p&gt;This was already enabled for me, but I&#x27;m assured this is a required step&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Switch to the child profile&lt;&#x2F;li&gt;
&lt;li&gt;Swipe [all the way] down from top, click the settings cog&lt;&#x2F;li&gt;
&lt;li&gt;Enter the adult pin&lt;&#x2F;li&gt;
&lt;li&gt;You then find a settings dashboard (not the android settings screen, this is a kindle fire thing)&lt;&#x2F;li&gt;
&lt;li&gt;Click &quot;Device Settings&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Check that &quot;Enable Camera &amp;amp; Photo Gallery&quot; toggle switch is enabled (i.e. yellow)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;pull-down.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;kids-settings.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;enable-camera.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(I&#x27;m not convinced this stacks up logically, but it was already enabled and working on mine, so whatever. Documented here as something to check.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;check-access-to-kids-photos-from-adult-profile&quot;&gt;Check access to kids photos from adult profile&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Go into the grown up profile&lt;&#x2F;li&gt;
&lt;li&gt;Open the gallery app&lt;&#x2F;li&gt;
&lt;li&gt;Verify that you can see the kid&#x27;s photos alongside those taken from the adult profile.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Tip: write adult&#x2F;kid on two pieces of paper, take a photo of each from the respective profile, that way you can see at a glance which photos are coming from which profile.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;profile-finder-photos.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-hidden-upload&quot;&gt;The hidden upload&lt;&#x2F;h2&gt;
&lt;p&gt;ℹ️ The following is for upload to Amazon Photos via the silk browser in the adult profile. This is the way I did it because this is what support showed me how to do, and because I was looking to Amazon for an end-to-end solution. I&#x27;ve since realised that the key insight here is that even though the file browser apps are unable to see the kids&#x27; photos, the web browser is able to select and upload them. I don&#x27;t know what magical back-door the browser and gallery are using to be able to see them, but the fact the file browser can&#x27;t completely threw me off the scent here.&lt;&#x2F;p&gt;
&lt;p&gt;You can actually use the website of any of the file storage services for this - dropbox, google drive, one drive etc. It&#x27;s the installed app versions that can&#x27;t access the photos. The browser however, has special magical access somehow.&lt;&#x2F;p&gt;
&lt;p&gt;⚠️ Before doing this, ensure you have &lt;em&gt;nothing&lt;&#x2F;em&gt; in the &quot;Folders &amp;gt; Pictures &amp;gt; Web&quot; folder of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;photos&quot;&gt;amazon photos&lt;&#x2F;a&gt;, otherwise they&#x27;ll all get mixed up. Move anything there out of the way first.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Go into the grown up profile&lt;&#x2F;li&gt;
&lt;li&gt;Open the &quot;Amazon Photos&quot; app, which will bounce you to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;photos&quot;&gt;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;photos&lt;&#x2F;a&gt; in the silk browser (or just open silk browser and navigate there yourself, same difference).&lt;&#x2F;li&gt;
&lt;li&gt;On the amazon photos website, click the &quot;+&quot; button
&lt;ol&gt;
&lt;li&gt;(Note this is &lt;em&gt;not&lt;&#x2F;em&gt; the identical &quot;+&quot; button in the &quot;Albums&quot; area of amazon photos.)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Click &quot;Upload photos&quot;
&lt;ol&gt;
&lt;li&gt;This should pop the option to choose which &quot;app&quot; to upload photos from&lt;&#x2F;li&gt;
&lt;li&gt;Note: This appears to be buggy, I had a lot of problems with this pop-up immediately vanishing again. Closing silk browser and starting again would solve it temporarily.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Select &quot;Files&quot;
&lt;ol&gt;
&lt;li&gt;This opens up the android file browser for file selection&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Click the hamburger menu (three horizontal lines)&lt;&#x2F;li&gt;
&lt;li&gt;Click &quot;Images&quot; (not &quot;photos&quot;, just to be different)&lt;&#x2F;li&gt;
&lt;li&gt;Long-press one of the images&lt;&#x2F;li&gt;
&lt;li&gt;Click the three tiny dots top-right (some kind of android options menu)&lt;&#x2F;li&gt;
&lt;li&gt;Click &quot;Select All&quot; in the menu that pops up (the only option)&lt;&#x2F;li&gt;
&lt;li&gt;Click &quot;Open&quot; (it&#x27;s not really open, it means &quot;upload&quot;)&lt;&#x2F;li&gt;
&lt;li&gt;Finally you should see the photos uploading one at a time with a progress bar in the amazon photos website&lt;&#x2F;li&gt;
&lt;li&gt;🚨 Repeat the above for Videos!! They are not in the &quot;images&quot; section. 🚨 - I very nearly lost all the kid&#x27;s videos because of this.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;silk-web-upload-button.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;silk-web-upload-options.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;silk-web-upload-gallery-hamburger.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;silk-web-upload-gallery-images-videos.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;silk-web-upload-select-one.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;silk-web-upload-select-all.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;silk-web-upload-open.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;silk-web-uploading.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note: the very tempting &quot;gallery&quot; option does &lt;em&gt;not&lt;&#x2F;em&gt; seem to manage to select and upload photos, so that&#x27;s no use. Stick to the top two images&#x2F;videos option in the hamburger menu.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;download-from-amazon-photos&quot;&gt;Download from amazon photos&lt;&#x2F;h2&gt;
&lt;p&gt;To exfiltrate your kids photos from the amazon walled garden:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-check-they-actually-uploaded&quot;&gt;1. Check they actually uploaded&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;On a laptop (preferably linux, because you learned your lesson about lock-in and walled gardens, right?)&lt;&#x2F;li&gt;
&lt;li&gt;Log in to &quot;Amazon Photos&quot; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;photos&quot;&gt;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;photos&lt;&#x2F;a&gt; with the same amazon account as the adult profile you&#x27;ve been using on the tablet.&lt;&#x2F;li&gt;
&lt;li&gt;Look in Folders &amp;gt; Pictures &amp;gt; Web&lt;&#x2F;li&gt;
&lt;li&gt;You should see all your kids photos in there, mixed with anything else you&#x27;ve already uploaded (lame)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;2-download-them&quot;&gt;2. Download them&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;web-photos.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;kindle-fire-photos&#x2F;web-download.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;footnotes&quot;&gt;Footnotes&lt;&#x2F;h2&gt;
&lt;p&gt;In the gallery app there&#x27;s a text-button that gives false-hope that reads &quot;Go to Amazon Photos for backup options&quot;, but ha! When you click it dutifully launches the &quot;Amazon Photos&quot; app... which... no longer is an actual app and just opens the silk browser on the amazon photos web page, which obviously can&#x27;t back up shit, especially in the background on a schedule, like backups are supposed to be, and there&#x27;s no &quot;backup&quot; options in the website, because, well, it&#x27;s a website not an app or tablet setting. Infuriating, like everything else to do with this.&lt;&#x2F;p&gt;
&lt;p&gt;If anyone from amazon is listening, this an absolute joke, and I know it&#x27;s been like this for years because I had exactly the same runaround from support and crazy workaround when the previous tablet needed replacing. Currently the choices are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Spend literally hours fighting amazon support, and more hours trying to figure out these hidden back doors, or&lt;&#x2F;li&gt;
&lt;li&gt;Accept that amazon have managed to lock all the kids photos in an impenetrable fortress and tell the kids that all their efforts are lost (fun).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As you can see from the above, plus the hidden hours I&#x27;ve spent to even be able to get to this point, this is the opposite of slick, seamless and effortless.&lt;&#x2F;p&gt;
&lt;p&gt;Oh yeah, and amazon confirmed that there is NO background sync capabilities. So when your kid drops the tablet in the lake and you haven&#x27;t done the above hour-long toil recently, well it&#x27;s just tough shit, and now you have to reasons for your kid to be upset not just one.&lt;&#x2F;p&gt;
&lt;p&gt;Honestly I&#x27;d throw these pieces of junk in the lake myself, but as far as I know none of the other tablet vendors provide an age-appropriate(ish) curated tablet experience for kids, with a range of downloadable apps and content that the kids can move around on their own. Last I checked apple only had a full ipad experience with the ability to lock the kids into a single app, which is a nightmare on a long trip because they constantly need you to change apps, or you give up and give them unfettered access, which given how even grown-ups are destroying their own mental health with tech these days is just a bad idea. If you know of better alternatives I&#x27;m all ears.&lt;&#x2F;p&gt;
&lt;p&gt;I need a lie down after that. Thanks to the amazon support person for spending two or so hours on the phone with me, including screensharing the tablet while we found the hidden options that actually worked.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NuGet libraries to avoid</title>
        <published>2025-05-08T00:00:00+00:00</published>
        <updated>2025-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/05/08/open-source-dotnet-library-choices/"/>
        <id>https://0x5.uk/2025/05/08/open-source-dotnet-library-choices/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/05/08/open-source-dotnet-library-choices/">&lt;p&gt;There has been a bout of &quot;commercialization&quot; of nuget packages in the dotnet world lately. There are now so many going that way I struggle to remember what&#x27;s useable and what isn&#x27;t.&lt;&#x2F;p&gt;
&lt;p&gt;I used to be able to grab the nearest nuget lib and with a quick glance at the license get coding, but now one has to tread carefully not to fall foul of license changes.&lt;&#x2F;p&gt;
&lt;p&gt;The .NET ecosystem has seen a notable shift with several NuGet libraries transitioning from open source to commercial models. This has impacted developers who now need to be more vigilant about the libraries they choose to incorporate into their projects. Below is a list of major NuGet libraries that have gone commercial, along with some alternatives.&lt;&#x2F;p&gt;
&lt;p&gt;This is definitely something to watch when using AIs&#x2F;LLMs for [Vibe] coding as they will happily add libraries for which you would be in violation of their license.&lt;&#x2F;p&gt;
&lt;p&gt;Note: being commercially licensed is not necessarily a reason not to use a library. For example, you probably don&#x27;t want to write an entire OpenId identity server from scratch just to avoid your company paying for Duende. This post is more about not walking unawares into something that at some point was FOSS, but has now shifted to something that might be difficult or impossible to use in the particular project you are working on. Some of these are more surprising than others depending on how long you have been around and how much you&#x27;ve been keeping up with the dramas of dotnet recently. The scope of this list is specifically dotnet projects that gained some traction while they were fully FOSS which later changed their license (or behaviour in the case of Moq) in ways that make them less universally usable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-nuget-hall-of-former-glory&quot;&gt;The NuGet Hall of Former Glory&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;moq&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;moq&#x2F;moq4&quot;&gt;Moq&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Introduced the SponsorLink spyware dependency, causing uproar and mass exodus.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;dotnet&#x2F;comments&#x2F;15ljdcc&#x2F;does_moq_in_its_latest_version_extract_and_send&#x2F;&quot;&gt;Reddit discussion&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;devlooped&#x2F;moq&#x2F;issues&#x2F;1372&quot;&gt;GitHub issue&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Alternatives:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;FakeItEasy&#x2F;FakeItEasy&quot;&gt;FakeItEasy&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nsubstitute&#x2F;NSubstitute&quot;&gt;NSubstitute&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Discussion: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;dotnet&#x2F;comments&#x2F;173ddyk&#x2F;now_that_the_controversy_from_moqs_dependencies&#x2F;&quot;&gt;reddit: &quot;Now that the controversy from Moq&#x27;s dependencies has had some time to settle, what are people moving to?&quot; : r&#x2F;dotnet&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;gitinfo&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;devlooped&#x2F;GitInfo&quot;&gt;GitInfo&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;GitInfo followed a similar path to Moq, and users should be cautious of libraries from the same author (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;devlooped&quot;&gt;devlooped, aka @kzu&lt;&#x2F;a&gt;) who has lost much trust after the SponsorLink debacle. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;profiles&#x2F;devlooped&quot;&gt;Anything else by kzu&lt;&#x2F;a&gt; should be considered tainted.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;devlooped&#x2F;GitInfo&quot;&gt;GitHub repository&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;This project uses SponsorLink to attribute sponsor status&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;masstransit-as-of-v9&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masstransit-project.com&#x2F;&quot;&gt;MassTransit&lt;&#x2F;a&gt; as of v9&lt;&#x2F;h3&gt;
&lt;p&gt;MassTransit&#x27;s commercialization was announced with version 9, prompting users to seek alternatives.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;dotnet&#x2F;comments&#x2F;1jpyczi&#x2F;masstransit_going_commercial&#x2F;&quot;&gt;Reddit discussion&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masstransit.io&#x2F;introduction&#x2F;v9-announcement&quot;&gt;Official announcement&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Alternatives:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BrighterCommand&#x2F;Brighter&quot;&gt;Brighter&lt;&#x2F;a&gt;&#x2F;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BrighterCommand&#x2F;Darker&quot;&gt;Darker&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rebus-org&#x2F;Rebus&quot;&gt;Rebus&lt;&#x2F;a&gt; - MIT license,
&lt;ul&gt;
&lt;li&gt;the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;udidahan.com&#x2F;2013&#x2F;09&#x2F;11&#x2F;on-mookid-joining-nservicebus-and-what-that-means-for-rebus&#x2F;&quot;&gt;original author briefly joined the NServiceBus owners in 2013&lt;&#x2F;a&gt; but &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;dotnet&#x2F;comments&#x2F;1khwsma&#x2F;comment&#x2F;mre8b5r&#x2F;&quot;&gt;left after a couple of months to support Rebus&lt;&#x2F;a&gt; (yay)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Raw &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;api&#x2F;overview&#x2F;azure&#x2F;messaging.servicebus-readme?view=azure-dotnet&quot;&gt;Service Bus SDK&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;del&gt;No better: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;particular.net&#x2F;nservicebus&quot;&gt;NServiceBus&lt;&#x2F;a&gt; (see below)&lt;&#x2F;del&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;nservicebus&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;particular.net&#x2F;nservicebus&quot;&gt;NServiceBus&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;strange non-FOSS dual licensing with restricted functionality. Avoid. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;5657809&#x2F;nservicebus-license&#x2F;5670707#5670707&quot;&gt;Apparently was once Apache licensed but changed circa 2011&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;mediatr-automapper&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jbogard&#x2F;MediatR&quot;&gt;MediatR&lt;&#x2F;a&gt; &amp;amp; Automapper&lt;&#x2F;h3&gt;
&lt;p&gt;Both libraries have moved towards a commercial model, as announced by their creator Jimmy Bogard.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jimmybogard.com&#x2F;automapper-and-mediatr-licensing-update&#x2F;&quot;&gt;Licensing update&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jimmybogard.com&#x2F;automapper-and-mediatr-going-commercial&#x2F;&quot;&gt;Commercial announcement&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jbogard&#x2F;MediatR&#x2F;discussions&#x2F;1105&quot;&gt;GitHub discussion&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;fluentassertions&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fluentassertions.com&#x2F;&quot;&gt;FluentAssertions&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;FluentAssertions also changed their licensing model, but a community fork remains available under Apache 2.&lt;&#x2F;p&gt;
&lt;p&gt;Alternatives:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AwesomeAssertions&#x2F;AwesomeAssertions&quot;&gt;Community fork &quot;AwesomeAssertions&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.shouldly.org&#x2F;&quot;&gt;Shouldly&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;duende-openid-server&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;Duende.IdentityServer&quot;&gt;Duende&lt;&#x2F;a&gt; OpenId server&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;leastprivilege.com&#x2F;2020&#x2F;10&#x2F;01&#x2F;the-future-of-identityserver&#x2F;#:~:text=This%20new%20product%20will%20remain,source%20community%20and%20our%20contributors&quot;&gt;&quot;This new product will remain open source but will be offered with a dual license (RPL and commercial)&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Alternatives&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.keycloak.org&#x2F;&quot;&gt;KeyCloak&lt;&#x2F;a&gt; - a Java based self-hostable open source identity server.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This one doesn&#x27;t really deserve the &quot;avoid&quot; label these days, as it&#x27;s been pretty clear for many years that this is a commercial offering, however it&#x27;s included here because I think it is interesting that a move from Apache to dual licensing is part of its history.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;imagesharp&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;SixLabors&#x2F;ImageSharp&quot;&gt;ImageSharp&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sixlabors.com&#x2F;posts&#x2F;license-changes&#x2F;#:~:text=The%20Six%20Labors%20Split%20License,Six%20Labors%20Commercial%20Use%20License&quot;&gt;&quot;The Six Labors Split License&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;a-word-on-licenses&quot;&gt;A word on licenses&lt;&#x2F;h2&gt;
&lt;p&gt;Several of these re-licensed projects were under the MIT license. While you can still get and use the code as it was at the point the license was changed, there is nothing in the MIT license to stop a library author accepting thousands of hours of effort in contributions and then flipping the license to something profiteering.&lt;&#x2F;p&gt;
&lt;p&gt;This should be a warning to all who care about the future benefit and use of their work to think carefully about what license to choose for their work, and the license of projects they contribute to. Notably this kind of relicense would be impossible with a GPL license without gaining consent from every single contributor as to do so would be removing rights, which is explicitly disallowed by the GPL.&lt;&#x2F;p&gt;
&lt;p&gt;This site has good explanations of choosing licenses: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;choosealicense.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;choosealicense.com&#x2F;&lt;&#x2F;a&gt;, plus a handy tool to pull-request a license to your github repo.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rpl-reciprocal-public-license&quot;&gt;RPL (Reciprocal Public License)&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;opensource.org&#x2F;license&#x2F;rpl-1-5&quot;&gt;RPL license&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Reciprocal_Public_License&quot;&gt;RPL on Wikipedia&lt;&#x2F;a&gt;) is a lesser-known license that you have to watch out for. It seems to be common in dual licensing because it effectively forbids commercial use due to the derivate works clauses. If you add an RPL library to a commercial project you&#x27;ll potentially be in big trouble.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s interesting to note that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;licenses&#x2F;license-list.en.html#RPL&quot;&gt;GNU considers RPL non-free&lt;&#x2F;a&gt; due to restrictions it imposes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;contributions-welcome&quot;&gt;Contributions welcome&lt;&#x2F;h2&gt;
&lt;p&gt;If you know of any that have gone south that I&#x27;ve missed here, and of good alternatives by all means open a PR for this post. I&#x27;m hoping there won&#x27;t be too many more that do this in the coming years.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;linux&#x2F;comments&#x2F;veeg4i&#x2F;permissive_licenses_are_counterintuitive&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;linux&#x2F;comments&#x2F;veeg4i&#x2F;permissive_licenses_are_counterintuitive&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Podcast: using AI for coding</title>
        <published>2025-04-02T00:00:00+00:00</published>
        <updated>2025-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/04/02/podcast:-using-ai-for-coding/"/>
        <id>https://0x5.uk/2025/04/02/podcast:-using-ai-for-coding/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/04/02/podcast:-using-ai-for-coding/">&lt;p&gt;🎙️ New episode of &#x27;&#x27;Software Should be Free&#x27;&#x27; just released&lt;&#x2F;p&gt;
&lt;p&gt;Tim+Jim sharing what we&#x27;ve learnt using AI to write real code. 🤖&lt;&#x2F;p&gt;
&lt;p&gt;🎧 Listen here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;s&#x2F;db1e52cc&quot;&gt;https:&#x2F;&#x2F;share.transistor.fm&#x2F;s&#x2F;db1e52cc&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We could have talked for several more hours, but for your sanity we managed to keep it under 40 mins.&lt;&#x2F;p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;180&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; seamless src=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;e&#x2F;db1e52cc&quot;&gt;&lt;&#x2F;iframe&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why is reading bad code so painful?!</title>
        <published>2025-01-31T00:00:00+00:00</published>
        <updated>2025-01-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/01/31/why-is-reading-bad-code-so-painful/"/>
        <id>https://0x5.uk/2025/01/31/why-is-reading-bad-code-so-painful/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/01/31/why-is-reading-bad-code-so-painful/">&lt;p&gt;🎙️ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pod.0x5.uk&#x2F;29&quot;&gt;Listen to the podcast episode here&lt;&#x2F;a&gt; 🎙️&lt;&#x2F;p&gt;
&lt;p&gt;I was reading some code recently that had a bunch of problems at various layers, and in spite of all my years of coding and the fact that it&#x27;s not even my project, I &lt;em&gt;still&lt;&#x2F;em&gt; find myself getting strong feelings of anguish and &quot;pain&quot;. I found myself wondering &lt;em&gt;why&lt;&#x2F;em&gt;. I understand what&#x27;s bad about the code, and these days can largely explain what properties of the code I&#x27;m looking at make it objectively &quot;bad&quot; (e.g. &quot;this violates the single-responsibility principle&quot;). But why it&#x27;s such an emotional reaction was still puzzling to me.&lt;&#x2F;p&gt;
&lt;p&gt;I did some internet searching, and the search engines generally thought I was really asking &quot;what makes code painfully bad&quot; rather than &quot;what makes bad code so painful&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;But wait, now we have the mighty AI in the sky that has consumed all human knowledge and compressed it into a statistical model, so I turned to that. What follows is a lightly edited output, which in my opinion does a good job of providing an explanation of why us cave-dwelling-flesh-bags-turned-programmers don&#x27;t just dispassionately observe the horrors unfolding in our IDE.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cognitive-dissonance-expectation-vs-reality&quot;&gt;Cognitive Dissonance (Expectation vs. Reality)&lt;&#x2F;h2&gt;
&lt;p&gt;Our brains expect &lt;strong&gt;logical, structured patterns&lt;&#x2F;strong&gt; in code.&lt;&#x2F;p&gt;
&lt;p&gt;Bad code &lt;strong&gt;violates&lt;&#x2F;strong&gt; these expectations, causing mental discomfort.&lt;&#x2F;p&gt;
&lt;p&gt;This dissonance triggers frustration, similar to hearing an off-key note in music or reading a grammatically incorrect sentence:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&quot;He go store buy apple now.&quot;&lt;&#x2F;em&gt; (What??!)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; function p(x)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; p&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;(Why does this function exist? What is it doing? Why?!!)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See also: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codegolf.stackexchange.com&#x2F;&quot;&gt;code golf&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mental-overload-cognitive-load-theory&quot;&gt;Mental Overload (Cognitive Load Theory)&lt;&#x2F;h2&gt;
&lt;p&gt;Bad code forces the brain to &lt;strong&gt;work harder than necessary&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Good code fits within our &lt;strong&gt;working memory&lt;&#x2F;strong&gt; and follows familiar patterns.&lt;&#x2F;p&gt;
&lt;p&gt;Bad code disrupts this, leading to &lt;strong&gt;cognitive exhaustion&lt;&#x2F;strong&gt;—like straining a muscle.&lt;&#x2F;p&gt;
&lt;p&gt;This overuse of mental resources can cause &lt;strong&gt;real physical discomfort&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;violation-of-pattern-recognition-the-ugly-code-effect&quot;&gt;Violation of Pattern Recognition (The &quot;Ugly Code&quot; Effect)&lt;&#x2F;h2&gt;
&lt;p&gt;The human brain &lt;strong&gt;loves patterns&lt;&#x2F;strong&gt;—in language, music, and visuals.&lt;&#x2F;p&gt;
&lt;p&gt;Good code follows &lt;strong&gt;established design principles&lt;&#x2F;strong&gt; (DRY, SOLID, clear naming conventions).&lt;&#x2F;p&gt;
&lt;p&gt;Bad code is &lt;strong&gt;chaotic and unpredictable&lt;&#x2F;strong&gt;, triggering a &lt;strong&gt;&quot;something is wrong&quot;&lt;&#x2F;strong&gt; reaction.&lt;&#x2F;p&gt;
&lt;p&gt;It’s like seeing a &lt;strong&gt;distorted face in a picture&lt;&#x2F;strong&gt;—our instinct is &lt;strong&gt;disgust or distress&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;emotional-attachment-to-code-quality&quot;&gt;Emotional Attachment to Code Quality&lt;&#x2F;h2&gt;
&lt;p&gt;Developers see &lt;strong&gt;clean code as a reflection of their intelligence and discipline&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The failure to follow good programming practices can feel like sacrilege to an experienced developer, much as it would feel if someone &lt;strong&gt;vandalized a work of art&lt;&#x2F;strong&gt;, or someone &lt;strong&gt;trashed a well-maintained house or religious temple&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you &lt;strong&gt;have to maintain&lt;&#x2F;strong&gt; the bad code, the emotional response intensifies:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&quot;Why did someone do this? Now I have to fix it?!&quot;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;fight-or-flight-response-biological-stress-reaction&quot;&gt;Fight-or-Flight Response (Biological Stress Reaction)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Confusion and unpredictability&lt;&#x2F;strong&gt; trigger mild &lt;strong&gt;stress responses&lt;&#x2F;strong&gt; in the brain.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;strong&gt;amygdala&lt;&#x2F;strong&gt; (which processes threats) &lt;strong&gt;doesn’t distinguish between &quot;bad code&quot; and actual danger&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This can cause:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Actual &lt;strong&gt;feelings of discomfort&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Increased heart rate&lt;&#x2F;li&gt;
&lt;li&gt;Full on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.simplypsychology.org&#x2F;amygdala-hijack.html&quot;&gt;amygdala hijack&lt;&#x2F;a&gt; where the rational brain is rendered helpless&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Just like bad user interface designs can frustrate users, bad code creates a negative physiological response.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-torture-by-a-thousand-paper-cuts-effect&quot;&gt;The &quot;Torture by a Thousand Paper Cuts&quot; Effect&lt;&#x2F;h2&gt;
&lt;p&gt;One small bad practice isn’t painful on its own.&lt;&#x2F;p&gt;
&lt;p&gt;But encountering &lt;strong&gt;hundreds of tiny problems&lt;&#x2F;strong&gt;—inconsistent naming, bad formatting, cryptic logic—builds up like an &lt;strong&gt;accumulation of tiny frustrations&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This leads to an almost &lt;strong&gt;physical sensation of irritation&lt;&#x2F;strong&gt;, like &lt;strong&gt;nails on a chalkboard&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;your-brain-is-screaming-no&quot;&gt;Your Brain is Screaming &quot;NO!!&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;Reading bad code &lt;strong&gt;feels painful&lt;&#x2F;strong&gt; because your brain recognizes disorder, struggles to process it, and instinctively &lt;strong&gt;resists it&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It’s a mix of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cognitive overload&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Emotional frustration&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Mild biological stress responses&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That pain? It’s your brain begging for &lt;strong&gt;clarity, familiarity, ease and structure&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Viewing git history for merged feature branches</title>
        <published>2025-01-26T00:00:00+00:00</published>
        <updated>2025-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/01/26/viewing-git-history-for-merged-feature-branches/"/>
        <id>https://0x5.uk/2025/01/26/viewing-git-history-for-merged-feature-branches/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/01/26/viewing-git-history-for-merged-feature-branches/">&lt;p&gt;I&#x27;ve been using git for nearly two decades now and yet I still seem to find new challenges and new things to learn on a regular basis.&lt;&#x2F;p&gt;
&lt;p&gt;One of things that makes me scratch my head more than I would like, is when an inexperienced developer creates &quot;interesting&quot; history in git because they don&#x27;t know how to use the tool in a way that creates easy to understand history for fellow developers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-git-jungle&quot;&gt;The git jungle&lt;&#x2F;h2&gt;
&lt;p&gt;One of the curious properties of git (and I guess computer code too) is that the more experienced developers create output which is &lt;em&gt;easier&lt;&#x2F;em&gt; to understand, and the less experienced developers create output which is &lt;em&gt;harder&lt;&#x2F;em&gt; to follow. With git logs, it goes to the point where an inexperienced developer using git can do some things that will completely stump even highly experienced developers for a good amount of time before understanding what they are looking at, and perhaps how it got into that state (I quite often never find out what they did that resulted in their unique flavour of mess).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;dall-e-git-log-exploration.webp&quot; alt=&quot;AI generated image of an intrepid developer with a machete hacking through a jungle of git commit logs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;first-parent&quot;&gt;&quot;First parent&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;One of the best tools I&#x27;ve found for simplifying a complex history that I use all the time is the &lt;code&gt;--first-parent&lt;&#x2F;code&gt; filter. This alone is worth a blog post as far fewer people than I would expect know about this, even though there&#x27;s options for this in many of the graphical git viewers now.&lt;&#x2F;p&gt;
&lt;p&gt;As I mentioned in &lt;a href=&quot;&#x2F;2021&#x2F;03&#x2F;15&#x2F;github-rebase-and-squash-considered-harmful&#x2F;&quot;&gt;my post about avoiding squash-merges&lt;&#x2F;a&gt; the ability to view the history of &lt;code&gt;origin&#x2F;main&lt;&#x2F;code&gt; with or without the full history of every feature branch that was merged in is immensely helpful. Especially if the feature branches that have been contributed are of varying quality, for example being based on extremely old commits, having repeated unecessary merges &lt;em&gt;from&lt;&#x2F;em&gt; main before being merged in, or just being a jumbled pile of &quot;wip&quot; and other assorted unstructured commit noise.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;anecdote&quot;&gt;Anecdote&lt;&#x2F;h2&gt;
&lt;p&gt;As a bit of an entertaining aside to this story, one of the most puzzling things I tripped over in a git log was something that completely destroyed the history produced by &lt;code&gt;--first-parent&lt;&#x2F;code&gt; resulting in no small amount of confusion. For a moment I thought a whole bunch of junk commits had been pushed straight to &lt;code&gt;main&lt;&#x2F;code&gt; bypassing the pull request and review process. After much studying of the logs and trying different tools to view the git logs I eventually figured out that the merge commit that pulled the feature branch into &lt;code&gt;main&lt;&#x2F;code&gt; had the &quot;parent&quot; commit sha1&#x27;s listed in the wrong order; so the previous commit on the main branch (&quot;Merged PR xxx&quot;) became the &lt;em&gt;second parent&lt;&#x2F;em&gt; of this merge, and the last commit on the feature branch became the &lt;em&gt;first parent&lt;&#x2F;em&gt;. Now of course git doesn&#x27;t actually care, and the final code is unchaged regardless, however all the tools that assume that &lt;code&gt;main&lt;&#x2F;code&gt; will always be the first parent are now confused, and follow the feature branch commits instead of the main branch commits. I still to this day don&#x27;t know how this developer managed to achieve this, and it will remain in that particular client&#x27;s git logs till the end of time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;understanding-git-logs&quot;&gt;Understanding git logs&lt;&#x2F;h2&gt;
&lt;p&gt;As you may have guessed by this point, it&#x27;s pretty much a matter of pride for me that no matter what state the other developers have managed to get into, I can at least tell for a fact what they pushed to &lt;code&gt;main&lt;&#x2F;code&gt; in the end. And maybe I can help them do something cleaner next time with a bit of education on how to use git. Git doesn&#x27;t make this easy, merge commits are pretty inpenetrable at times, and when you have a careless or ignorant group of developers the tramlines of branch history can look a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Effect_of_psychoactive_drugs_on_animals#Spiders&quot;&gt;spider on too much caffeine&lt;&#x2F;a&gt; created the history.&lt;&#x2F;p&gt;
&lt;p&gt;Something that&#x27;s been increasingly bothering me as a minor but irritating friction when trying to fathom what a developer contributed is that with only the tool of first-parent to hand, I can only either see the straight line history, or the full history of all branches that were merged in to main. That makes spotting the single line of commits from the merged in feature branch particularly tricky, especially if the developer didn&#x27;t know how to rebase, started their branch from a really old main, and repeatedly merged main (and maybe a few other branches) in to their feature branch.&lt;&#x2F;p&gt;
&lt;p&gt;I finally got fed up with this gap, having encountered a long-running branch that was repeatedly merged into main, had more commits added, merged main back into the feature branch, and then the whole thing repeated all on the same branch. I was utterly defeated by this one. By four or five commits down I could no longer follow the tangle of branches and merges and couldn&#x27;t tell what was on this developer&#x27;s branch and what was other people&#x27;s branches that had been merged in to main elsewhere.&lt;&#x2F;p&gt;
&lt;p&gt;So now for the exciting new bit. I think this might be completely novel, though please get in touch if you know of anyone who&#x27;s talked about this before, or any tools that can do this. I know of neither…&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-new-way-to-inspect-merged-feature-branches&quot;&gt;A new way to inspect merged feature branches&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a one-liner git command that allows you pass in the sha1 of any merge commit on &lt;code&gt;main&lt;&#x2F;code&gt; (usually a &quot;Merge PR xxx&quot; commit if you are following &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.github.com&#x2F;en&#x2F;get-started&#x2F;using-github&#x2F;github-flow&quot;&gt;github flow&lt;&#x2F;a&gt;) and shows a graphical log view of only the first-parent merge commits on main, and all the commits on the feature branch. Win.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;merge_commit=8eb7b69; feature_branch=$(git log -m --pretty=format:&amp;quot;%H %P&amp;quot; $merge_commit -1 | cut -f 3 -d &amp;quot; &amp;quot;); git log --graph --oneline --decorate --color --first-parent $(git rev-list $feature_branch ^$merge_commit^) $(git rev-list $merge_commit --first-parent)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can turn them into &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;blob&#x2F;63687515a344f3a1bbc1beb5b95859527cc917f5&#x2F;.gitconfig#L41-L42&quot;&gt;git aliases for easy use&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-global&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; alias.trm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;!f() { merge_commit=$1; feature_branch=$(git log -m --pretty=format:&amp;quot;%H %P&amp;quot; $merge_commit -1 | cut -f 3 -d &amp;quot; &amp;quot;); git log --graph --oneline --decorate --color --first-parent $(git rev-list $feature_branch ^$merge_commit^) $(git rev-list $merge_commit --first-parent); }; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-global&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; alias.ggm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;!f() { merge_commit=$1; feature_branch=$(git log -m --pretty=format:&amp;quot;%H %P&amp;quot; $merge_commit -1 | cut -f 3 -d &amp;quot; &amp;quot;); tig --first-parent $(git rev-list $feature_branch ^$merge_commit^) $(git rev-list $merge_commit --first-parent); }; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;break-down&quot;&gt;Break down&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s break down what how this works (oh no, I&#x27;m starting to write like gpt! halp!)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;store-merge-commit-ref&quot;&gt;Store merge commit ref&lt;&#x2F;h4&gt;
&lt;p&gt;Put the sha1 of the merge into a variable (because we need it more than once)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;merge_commit&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;find-last-feature-branch-commit-before-merge&quot;&gt;Find last feature branch commit before merge&lt;&#x2F;h4&gt;
&lt;p&gt;This subcommand uses log to show the parent commit sha1s, then uses cut to find the second parent sha1, i.e. the top commit of the feature branch that was merged in.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;feature_branch&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; log&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-pretty=format:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;%H %P&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;merge_commit&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;git-log-invocation&quot;&gt;Git log invocation&lt;&#x2F;h4&gt;
&lt;p&gt;Standard git log formatting to get a nice graph, can be replaced with &lt;code&gt;tig&lt;&#x2F;code&gt; for a prettier graph, which is what I&#x27;ve done for my graphs below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; log&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-graph&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-oneline&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-decorate&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-color&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;first-parent-filter-of-main&quot;&gt;First parent filter (of main)&lt;&#x2F;h4&gt;
&lt;p&gt;Show only &quot;first-parent&quot; commits. Normally git would follow all parents and include them all in the displayed graph. With this it will only follow the &quot;first&quot; parent (usually &lt;code&gt;main&lt;&#x2F;code&gt;, ignoring parent commits from the feature branch). This applies to everything shown, so if we didn&#x27;t do rev-parse later we only get first-parent on the feature branch too (obscure but can be an important difference if the feature branch had its own merge commits, something that is common with devs that use the evil &quot;sync&quot; button blindly).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;--first-parent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;find-commits-on-feature-branch&quot;&gt;Find commits on feature branch&lt;&#x2F;h4&gt;
&lt;p&gt;This uses &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;git-rev-list&quot;&gt;git rev-list&lt;&#x2F;a&gt; to list all the commit sha1s that are in the feature branch, filtering out all the commits that are reachable from the last mainline commit before the feature was merged in to main.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; rev-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;feature_branch&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; ^&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;merge_commit&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first argument, &lt;code&gt;$feature_branch&lt;&#x2F;code&gt;, just causes &lt;code&gt;rev-list&lt;&#x2F;code&gt; to list all the sha1s in the tree of parents of feature_branch (including feature branch itself).&lt;&#x2F;p&gt;
&lt;p&gt;The second parameter of rev-list would normally just add more sha1s to thie list, however…&lt;&#x2F;p&gt;
&lt;p&gt;The two carets (&lt;code&gt;^&lt;&#x2F;code&gt;) in the second argument are pretty confusing; they look like a pair but mean completely different things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The caret at the end &lt;code&gt;…^&lt;&#x2F;code&gt; means the [first] &lt;em&gt;parent&lt;&#x2F;em&gt; commit of the merge_commit&lt;&#x2F;li&gt;
&lt;li&gt;The caret at the start &lt;code&gt;^…&lt;&#x2F;code&gt; is an inversion&#x2F;negative filter, i.e. exclude all the sha1s that would have been included if they are also reachable from &lt;code&gt;$merge_commit^&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;From the rev-list docs:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;git rev-list [&amp;lt;options&amp;gt;] &amp;lt;commit&amp;gt;…​ [--] [&amp;lt;path&amp;gt;…​]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;List commits that are reachable by following the &lt;code&gt;parent&lt;&#x2F;code&gt; links from the given commit(s), but exclude commits that are reachable from the one(s) given with a &lt;code&gt;^&lt;&#x2F;code&gt; in front of them.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;If we put feature-branch-sha1 in the arg list for git-log then first-parent will filter that to only its first parents too. Seeing as we are trying to understand what the creator of the feature branch in its entirety we actually want to see all commits on that branch, even if it diverged and merged along the way. By using rev-list to list &lt;em&gt;all&lt;&#x2F;em&gt; the commits on that feature branch, and then feed that full list to git-log along with the merge commit sha1&#x2F;ref we cunningly sidestep the first-parent and show all the commits anyway.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;include-first-parent-commits-of-main&quot;&gt;Include first-parent commits of main&lt;&#x2F;h4&gt;
&lt;p&gt;This bit is optional, but it&#x27;s useful to see the branch in the context of the list of first-parent commits of main. This gives an idea of just how out of date the feature branch became (i.e. it should probably have been rebased before merging, a &quot;teachable moment&quot;).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; rev-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;merge_commit&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-first-parent&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;demo&quot;&gt;Demo&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve taken the time to create a demo repo that shows simplified version of a fairly typical git repository that uses the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.github.com&#x2F;en&#x2F;get-started&#x2F;using-github&#x2F;github-flow&quot;&gt;github flow&lt;&#x2F;a&gt; branching model: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;tramlines&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;tramlines&lt;&#x2F;a&gt;. So now let&#x27;s use that repo to demonstrate the use of this filtering:&lt;&#x2F;p&gt;
&lt;p&gt;The repo has two feature branches, A and B, that were worked on in parallel, and then both merged in to &lt;code&gt;main&lt;&#x2F;code&gt;. Feature B is fairly straigh forward branch, commit, merge. However feature A branched off while B was in progress, merged &lt;em&gt;after&lt;&#x2F;em&gt; B was merged in, had &lt;code&gt;main&lt;&#x2F;code&gt; merged into A along the way and for extra difficulty in following what happened it also split, had commit 2.1 and 2.2 done in parallel and then merged back together before finally merging in to &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-repo-history&quot;&gt;Example repo history&lt;&#x2F;h3&gt;
&lt;p&gt;This is the example in full up to the merge of feature A as rendered by tig:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ tig 8eb7b69 # Shows everything, including irrelevant feature-B branch comnmits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8eb7b69 ●─╮ Merge branch &amp;#39;feature-A&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7714120 │ ∙ Feature A commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6fc7ea7 │ ●─╮ Merge branch &amp;#39;feature-A-split&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5cb45d7 │ │ ∙ Feature A commit 2.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1cefe9d │ ∙ │ Feature A commit 2.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd5fdcd │ ●─┤ Merge branch &amp;#39;main&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c4d67c0 │ ∙ │ Feature A commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b1755ab │ ∙ │ Add feature A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eefde39 ∙ │ │ Mainline commit 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;51168ce ●─│─│─╮ Merge branch &amp;#39;feature-B&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b1cf72b │ │ │ ∙ Add feature B&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5d16553 ∙─│─╯ │ Mainline commit 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bf668c0 ∙ │ ╭─╯ Mainline commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;91c1da2 ∙─╯ │ Mainline commit 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;822449e ∙───╯ Mainline commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2282f5f ◎ Initial commit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;viewing-feature-a&quot;&gt;Viewing feature A&lt;&#x2F;h3&gt;
&lt;p&gt;Viewing feature A in isolation is not too hard, you can run a git log or tig on the last commit before it was merged in (&lt;code&gt;7714120&lt;&#x2F;code&gt;),&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ tig 7714120 # Missing context of main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7714120 ∙ Feature A commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6fc7ea7 ●─╮ Merge branch &amp;#39;feature-A-split&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5cb45d7 │ ∙ Feature A commit 2.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1cefe9d ∙ │ Feature A commit 2.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd5fdcd ●─┤ Merge branch &amp;#39;main&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5d16553 │ ∙ Mainline commit 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bf668c0 │ ∙ Mainline commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c4d67c0 ∙ │ Feature A commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b1755ab ∙ │ Add feature A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;91c1da2 ∙─╯ Mainline commit 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;822449e ∙ Mainline commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, I usually find it useful to see the log of &lt;code&gt;main&lt;&#x2F;code&gt; at the same time to see things like how out date the original branching off was, how &lt;code&gt;main&lt;&#x2F;code&gt; has progresses since, and get a feel for how the two relate.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unwanted-full-history&quot;&gt;Unwanted full history&lt;&#x2F;h3&gt;
&lt;p&gt;If you ask for a git log of main and the feature branch, you suddenly get every commit of every other branch that was merged in, which can be hard to follow even with really tidy teams.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ tig 8eb7b69 7714120 # Includes too much extraneous detail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8eb7b69 ●─╮ Merge branch &amp;#39;feature-A&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7714120 │ ∙ Feature A commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6fc7ea7 │ ●─╮ Merge branch &amp;#39;feature-A-split&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5cb45d7 │ │ ∙ Feature A commit 2.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1cefe9d │ ∙ │ Feature A commit 2.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd5fdcd │ ●─┤ Merge branch &amp;#39;main&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c4d67c0 │ ∙ │ Feature A commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b1755ab │ ∙ │ Add feature A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eefde39 ∙ │ │ Mainline commit 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;51168ce ●─│─│─╮ Merge branch &amp;#39;feature-B&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b1cf72b │ │ │ ∙ Add feature B     &amp;lt;===== UNWANTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5d16553 ∙─│─╯ │ Mainline commit 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bf668c0 ∙ │ ╭─╯ Mainline commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;91c1da2 ∙─╯ │ Mainline commit 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;822449e ∙───╯ Mainline commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2282f5f ◎ Initial commit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;over-eager-first-parent-filter&quot;&gt;Over-eager first-parent filter&lt;&#x2F;h3&gt;
&lt;p&gt;If you ask for first-parent with the sha1 of main and the branch you are no longer seeing everything that could be on the feature branch.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ tig 8eb7b69 7714120 --first-parent # Misses commits on feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8eb7b69 ∙ Merge branch &amp;#39;feature-A&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7714120 │ ∙ Feature A commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6fc7ea7 │ ∙ Merge branch &amp;#39;feature-A-split&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1cefe9d │ ∙ Feature A commit 2.2    &amp;lt;====== Where did 2.1 go?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd5fdcd │ ∙ Merge branch &amp;#39;main&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c4d67c0 │ ∙ Feature A commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b1755ab │ ∙ Add feature A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eefde39 ∙ │ Mainline commit 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;51168ce ∙ │ Merge branch &amp;#39;feature-B&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5d16553 ∙ │ Mainline commit 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bf668c0 ∙ │ Mainline commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;91c1da2 ∙─╯ Mainline commit 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;822449e ∙ Mainline commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-new-command-in-action&quot;&gt;The new command in action&lt;&#x2F;h3&gt;
&lt;p&gt;So now we use our magical new command, and suddenly we get everything we want:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ merge_commit=8eb7b69; feature_branch=$(git log -m --pretty=format:&amp;quot;%H %P&amp;quot; $merge_commit -1 | cut -f 3 -d &amp;quot; &amp;quot;); tig --first-parent $(git rev-list $feature_branch ^$merge_commit^) $(git rev-list $merge_commit --first-parent)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8eb7b69 ∙ Merge branch &amp;#39;feature-A&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7714120 │ ∙ Feature A commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6fc7ea7 │ ∙ Merge branch &amp;#39;feature-A-split&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5cb45d7 │ │ ∙ Feature A commit 2.1  &amp;lt;=== Note we get both of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1cefe9d │ ∙ │ Feature A commit 2.2  &amp;lt;=== commits from the split&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd5fdcd │ ∙─╯ Merge branch &amp;#39;main&amp;#39; into feature-A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c4d67c0 │ ∙ Feature A commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b1755ab │ ∙ Add feature A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eefde39 ∙ │ Mainline commit 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;51168ce ∙ │ Merge branch &amp;#39;feature-B&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5d16553 ∙ │ Mainline commit 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bf668c0 ∙ │ Mainline commit 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;91c1da2 ∙─╯ Mainline commit 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;822449e ∙ Mainline commit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And there it is, everything we need to know about feature A in the context of the progress of the &lt;code&gt;main&lt;&#x2F;code&gt; branch. Magic.&lt;&#x2F;p&gt;
&lt;p&gt;(tig doesn&#x27;t show the merges when it&#x27;s done this way, but it&#x27;s good enough to get an idea what&#x27;s going on in the maze of tramlines.)&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m afraid one particularly messy developer on one client did manage to create a history that defeated this approach by not only repeatedly merging to and from main along the way (which showed fine), but also cross merging with a different feature branch which was merged to main at a different point. As I say it never ceases to amaze me what people can come up with when not adhering to good branch hygeine. Hopefully that isn&#x27;t something I&#x27;ll run into again any time soon.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-merge-investigation-tools&quot;&gt;Bonus merge investigation tools&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s a couple of extra obscure git commands for looking at what messy&#x2F;inexperienced devs have concocted to confuse you:&lt;&#x2F;p&gt;
&lt;p&gt;By default &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;40986518&#x2F;how-to-git-show-the-diffs-for-a-merge-commit&quot;&gt;git doesn&#x27;t show everything in a merge commit&lt;&#x2F;a&gt; - this is very confusing to say the least, but equally I get why it only shows what changed that you wouldn&#x27;t expect if you just cleanly merged the two branches. Here&#x27;s two commands that will let you inspect the full diff of a merge:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git show --first-parent&lt;&#x2F;code&gt; - shows the patch of a merge commit&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git show --merge --patch&lt;&#x2F;code&gt; shows both sides of a merge commit&lt;&#x2F;p&gt;
&lt;p&gt;I also learned the existence of:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;--ancestry-path[=&amp;lt;commit&amp;gt;]&lt;&#x2F;code&gt;, which I still don&#x27;t understand well enough to explain&lt;&#x2F;p&gt;
&lt;p&gt;and &lt;code&gt;--fork-point&lt;&#x2F;code&gt; which apparently &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;git-merge-base#_discussion_on_fork_point_mode&quot;&gt;uses the local ref-log to try and find where a branch started&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The rabbit hole of advanced git tooling goes very deep indeed, far deeper than I&#x27;ve explored here.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;light-relief&quot;&gt;Light relief&lt;&#x2F;h2&gt;
&lt;p&gt;That was a bit much, so here&#x27;s some light relief that shows you&#x27;re not alone if you ever feel out of your depth with git: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;xkcd.com&#x2F;1597&#x2F;&quot;&gt;https:&#x2F;&#x2F;xkcd.com&#x2F;1597&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Don&#x27;t use Azure CosmosDB</title>
        <published>2025-01-14T00:00:00+00:00</published>
        <updated>2025-01-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2025/01/14/don't-use-azure-cosmosdb/"/>
        <id>https://0x5.uk/2025/01/14/don't-use-azure-cosmosdb/</id>
        
        <content type="html" xml:base="https://0x5.uk/2025/01/14/don&apos;t-use-azure-cosmosdb/">&lt;p&gt;Don&#x27;t use Azure CosmosDB for your next project.&lt;&#x2F;p&gt;
&lt;p&gt;I know it&#x27;s tempting, because global-web-scale, and CV-driven development, but it&#x27;s a trap that will mire you and your team in yaks, expensive azure bills, and lost productivity until the end of your time &#x2F; project &#x2F; contract &#x2F; company.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been on a series of teams that have chosen to use this technology from microsoft, and I&#x27;m sure it&#x27;s worth it if your project is the rare unicorn kind of hyper-scale global product that actually needs the specific unique properties it offers over a standard PaaS SQL database like sql server (shudder) or postgres (yay). (Seems unlikely though, stackoverflow still runs on mssql and that&#x27;s one of the biggest sites out there).&lt;&#x2F;p&gt;
&lt;p&gt;For the projects I&#x27;ve been on? The cost and dev overhead are just not worth it. It was there when I arrived, and caused nothing but trouble. Don&#x27;t forget to get your partition keys right at the start, because you&#x27;re fscked if you get that wrong. Do your devs all know how to do it well, or is it another excuse to make a whole bunch of new mistakes by using a shiny new tech with superb marketing hype now that we&#x27;re bored of SQL databases because we&#x27;ve got the hang of not fscking up that one.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve just about got a decent way of working with sql databases these days. Azure has perfectly good hosted sql for a fraction of the price. SQL Server and Postgres both have PaaS offerings, and decent local installs with and without docker.&lt;&#x2F;p&gt;
&lt;p&gt;You (or your client) had better have deep pockets for the Azure bills you are committing to, the number of times I hear &quot;oh don&#x27;t worry about the cloud bill, we have the money&quot; shortly followed by &quot;erm, could you bring the cloud bill down, when I said don&#x27;t worry I didn&#x27;t mean spaff £100k&#x2F;month up the wall on 42 environments running not-very-optimised code&quot;. (Don&#x27;t forget it&#x27;s not just production using it, you&#x27;ll also need UAT, Dev, QA, and one for &lt;em&gt;every&lt;&#x2F;em&gt; developer and CI pipeline). I&#x27;m sure Azure would love you to incur that bill.&lt;&#x2F;p&gt;
&lt;p&gt;You have two choices for dev and test with cosmos, both of them awful: 1) rely on real cloud instances of cosmos, 2) use the new local emulator. Using the cloud to run local tests is just a nightmare, it causes all sorts of reliability and config issues, causes developers to trip over each other, pushes up costs for something that should be free. Using the emulator requires a £5000 computer to not catch fire, and is flaky as f*ck in my growing experience with it.&lt;&#x2F;p&gt;
&lt;p&gt;I wrote this while waiting for the cosmos emulator to eat all my cpus on my monster desktop while running some integration tests. If I save even one person from falling into this tar pit I&#x27;ll consider this post worth the investment.&lt;&#x2F;p&gt;
&lt;p&gt;If you think that your system couldn&#x27;t possibly run in the constraints of a sql server, did you know that stackoveflow still runs on sql server, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nickcraver.com&#x2F;blog&#x2F;2016&#x2F;02&#x2F;17&#x2F;stack-overflow-the-architecture-2016-edition&#x2F;&quot;&gt;which ran 500 million sql queries &lt;em&gt;in one day&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; back in 2016.&lt;&#x2F;p&gt;
&lt;p&gt;Can you tell I&#x27;ll never be a Microsoft MVP, aside from my love of linux and the GPL.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;local-dev-pain&quot;&gt;Local dev pain&lt;&#x2F;h2&gt;
&lt;p&gt;For local development and tests there&#x27;s the CosmosDb emulator (available in docker, yay!) which has in my experience proved to be disappointingly slow and prone to just giving up and 429&#x27;ing everything or just failing to respond, even on a super powerful machine. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;how-to-develop-emulator&quot;&gt;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;how-to-develop-emulator&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It also has a built in expiry, which is a pain in the backside because docker is designed to cache &lt;code&gt;:latest&lt;&#x2F;code&gt; instead of constantly pulling from the registry. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Azure&#x2F;azure-cosmos-db-emulator-docker&#x2F;issues&#x2F;60&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Azure&#x2F;azure-cosmos-db-emulator-docker&#x2F;issues&#x2F;60&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mock-it-out&quot;&gt;Mock it out&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve been working on an in-memory test fake for CosmosDb which you can find here, which might ease the pain (or might make it worse, good luck and let me know in the github issues!) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;FakeCosmosDb&quot;&gt;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;FakeCosmosDb&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The RAID Log: Your Guide to Surviving Chaos, Politics, and Petty Office Wars</title>
        <published>2024-11-22T00:00:00+00:00</published>
        <updated>2024-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/11/22/the-raid-log/"/>
        <id>https://0x5.uk/2024/11/22/the-raid-log/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/11/22/the-raid-log/">&lt;p&gt;Ah, the RAID log—Risks, Assumptions, Issues, and Dependencies. To a bright-eyed project manager, it’s a shining beacon of order. To the rest of us? It’s corporate Mad Libs: half-blind guesses, blame-shifting masterpieces, and ominous warnings with no context.&lt;&#x2F;p&gt;
&lt;p&gt;To understand what to make of the whole charade I&#x27;ve spent some time coaxing the ever verbose ChatGPT into writing an entertaining piece that can help as all survive in a project where someone pulls onto their screenshare the dreaded and confusion inducing &quot;RAID Log&quot;. Enjoy!&lt;&#x2F;p&gt;
&lt;p&gt;If you’ve ever found yourself lost in the labyrinth of RAID log entries, you’ve probably met our key players: &lt;strong&gt;Non-Tech Nigel&lt;&#x2F;strong&gt;, &lt;strong&gt;Blaming Betty&lt;&#x2F;strong&gt;, &lt;strong&gt;Excessive Eddie&lt;&#x2F;strong&gt;, and &lt;strong&gt;Risk Bomb Rick&lt;&#x2F;strong&gt;. Together, they transform what should be a useful tool into a bureaucratic Hunger Games.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s meet these characters, laugh at their antics, and figure out how to navigate the chaos — whether you’re aiming to fix the project or just dodge the fallout.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;meet-the-usual-suspects&quot;&gt;Meet the Usual Suspects&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Non-Tech Nigel&lt;&#x2F;strong&gt; is your project lead who couldn’t explain a database if his life depended on it. But Nigel’s a master of buzzwords and will proudly log risks like &lt;em&gt;“Unexpected technical challenges”&lt;&#x2F;em&gt; to appear insightful. It’s Nigel’s way of saying, &lt;em&gt;“Something bad might happen, but I have no idea what or why.”&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Blaming Betty&lt;&#x2F;strong&gt; views the RAID log as a legal shield. Her entries all point fingers: &lt;em&gt;“Dependency on Team X for specs”&lt;&#x2F;em&gt; or &lt;em&gt;“Timeline delays due to QA team.”&lt;&#x2F;em&gt; If success has many parents, Betty’s here to make sure failure has an orphanage.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Excessive Eddie&lt;&#x2F;strong&gt; treats the RAID log like his personal diary, logging everything from &lt;em&gt;“Potential delays due to asteroid impacts”&lt;&#x2F;em&gt; to &lt;em&gt;“Low team morale after pizza ran out last week.”&lt;&#x2F;em&gt; His entries are so long you need a machete to cut through them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Risk Bomb Rick&lt;&#x2F;strong&gt; lives for ominous but useless warnings: &lt;em&gt;“Potential for critical failures in the system.”&lt;&#x2F;em&gt; Rick never explains what these failures are, but when things inevitably go wrong, he leans back and says, &lt;em&gt;“Well, I did flag it.”&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-they-turn-the-raid-log-into-a-battlefield&quot;&gt;How They Turn the RAID Log Into a Battlefield&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-nigel-s-magical-cover-your-assets-spell&quot;&gt;1. Nigel’s Magical Cover-Your-Assets Spell&lt;&#x2F;h3&gt;
&lt;p&gt;Nigel doesn’t understand tech, but he does understand plausible deniability. His favorite move? Logging vague risks that sound technical but mean nothing. “Potential delays due to unforeseen system complexities.”&lt;&#x2F;p&gt;
&lt;p&gt;At one meeting, Nigel solemnly pulled up the RAID log and pointed to an entry that just said “Integration concerns.” When pressed for details, he adjusted his glasses and said, “That’s what the team is investigating.” The team, of course, had never seen this “concern” until that moment.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-to-survive-nigel&quot;&gt;How to Survive Nigel&lt;&#x2F;h4&gt;
&lt;p&gt;Use his own vagueness against him. When he logs a risk with zero substance, reply with, “What mitigation steps do you suggest?” Watching Nigel scramble for an answer is its own reward.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-betty-s-blame-tennis-championship&quot;&gt;2. Betty’s Blame Tennis Championship&lt;&#x2F;h3&gt;
&lt;p&gt;Blaming Betty wields the RAID log like a tennis racket, lobbing problems into someone else’s court. “Deployment delayed due to Team A’s incomplete requirements.” Team A, naturally, didn’t even know they were supposed to provide requirements.&lt;&#x2F;p&gt;
&lt;p&gt;Betty once logged “QA blocked by unresolved dependencies” during a heated status meeting. When the QA lead (Rick, of course) asked for clarification, Betty smirked and said, “Well, it’s in the log.”&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-to-outplay-betty&quot;&gt;How to Outplay Betty&lt;&#x2F;h4&gt;
&lt;p&gt;Always specify your deliverables and timelines in your own RAID log entries. If Betty tries to blame you, you can counter with, “Actually, Betty, this was logged with an agreed deadline last week.” Serve, ace, point.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-eddie-s-flood-of-irrelevant-risks&quot;&gt;3. Eddie’s Flood of Irrelevant Risks&lt;&#x2F;h3&gt;
&lt;p&gt;Excessive Eddie logs everything. Every. Single. Thing. “Potential delays due to daylight savings time confusion.” “Risk of low team energy during Q3 due to insufficient snack variety.” It’s like he’s being paid by the word.&lt;&#x2F;p&gt;
&lt;p&gt;During one sprint planning session, Eddie insisted the team review his 36 “priority” risks. By the time we got to “Morale dip due to post-lunch fatigue,” nobody could remember why we were there.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-to-avoid-drowning-in-eddie-s-flood&quot;&gt;How to Avoid Drowning in Eddie’s Flood&lt;&#x2F;h4&gt;
&lt;p&gt;Politely suggest a RAID review. This is where you “prioritize high-impact risks” and quietly delete “Potential email server outages due to Mercury retrograde.”&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-rick-s-ominous-prophecies&quot;&gt;4. Rick’s Ominous Prophecies&lt;&#x2F;h3&gt;
&lt;p&gt;Risk Bomb Rick loves to drop cryptic warnings into the log. “Potential instability during high traffic.” What traffic? What instability? Rick doesn’t say—he’s too busy planning his “I told you so” moment.&lt;&#x2F;p&gt;
&lt;p&gt;Once, Rick logged “Performance concerns with System Y during load testing” and then went silent. When System Y exploded in production, Rick sighed theatrically in the meeting and said, “This was flagged months ago.”&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-to-defuse-rick-s-bombs&quot;&gt;How to Defuse Rick’s Bombs&lt;&#x2F;h4&gt;
&lt;p&gt;Ask for specifics the moment Rick logs a risk. “What exact tests showed performance concerns? Can we see the results?” Rick hates specifics almost as much as Nigel hates understanding tech.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;more-chaos-on-the-battlefield-how-raid-logs-go-off-the-rails&quot;&gt;More Chaos on the Battlefield: How RAID Logs Go Off the Rails&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;the-passive-aggressive-assumption&quot;&gt;The Passive-Aggressive Assumption&lt;&#x2F;h4&gt;
&lt;p&gt;Someone (probably Betty) logs an assumption like “Assume Team Y will meet the delivery deadline.” It sounds harmless—until Team Y inevitably doesn’t deliver. Then the entry becomes a smug “Well, we assumed you’d do your job” weapon in the next meeting.&lt;&#x2F;p&gt;
&lt;p&gt;How It Backfires: Team Y fights back with “We weren’t even aware of this assumption until five minutes ago.” Cue spiraling chaos as the assumption gets bounced around like a dodgeball.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-endless-dependency-loop&quot;&gt;The Endless Dependency Loop&lt;&#x2F;h3&gt;
&lt;p&gt;Eddie logs “Dependency on Team X to provide configurations,” while Team X logs “Dependency on Team Y for architecture approval.” Team Y logs “Dependency on external vendor for tool updates.” By the time you unravel it all, you realize the only real dependency is the coffee machine working properly.&lt;&#x2F;p&gt;
&lt;p&gt;How It Backfires: Nothing gets done because everyone’s waiting on everyone else. When someone finally asks “Can we clarify these dependencies?” Eddie sighs and adds “Dependency clarification risk” to the log.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-risk-that-ate-the-budget&quot;&gt;The Risk That Ate the Budget&lt;&#x2F;h3&gt;
&lt;p&gt;Rick logs a catastrophic risk like “System collapse during high traffic could result in $1M losses.” Leadership panics and reassigns half the team to mitigate this apocalyptic scenario. Meanwhile, the real risk—like a critical API not being developed—goes unnoticed until it’s too late.&lt;&#x2F;p&gt;
&lt;p&gt;How It Backfires: The risk Rick flagged turns out to be a 0.01% edge case, and leadership is furious about the wasted resources. Rick, of course, shrugs and says, “Better safe than sorry.”&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-meeting-black-hole&quot;&gt;The Meeting Black Hole&lt;&#x2F;h3&gt;
&lt;p&gt;Nigel, unsure of how to actually resolve risks, schedules recurring RAID log meetings. The log itself becomes a living entity, growing larger and less useful with every review. It’s now more of a &quot;Crisis Log&quot; because nobody can decide whether to act, escalate, or delete anything.&lt;&#x2F;p&gt;
&lt;p&gt;How It Backfires: People stop attending. The RAID log dies quietly in a forgotten shared folder, and Nigel announces a new “Alignment Tracker” initiative instead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;turning-the-chaos-to-your-advantage&quot;&gt;Turning the Chaos to Your Advantage&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-keep-a-shadow-log&quot;&gt;1. Keep a Shadow Log&lt;&#x2F;h3&gt;
&lt;p&gt;The RAID log may be full of nonsense, but your personal notes should capture the real risks and issues. When the project implodes, you’ll have the receipts.&lt;&#x2F;p&gt;
&lt;p&gt;One dev who worked with Betty kept a spreadsheet titled “Actual RAID Log” because Betty’s entries were so inaccurate. When Betty tried to blame his team, he calmly shared his notes, and Betty’s power-play crumbled like a stale donut.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-frame-risks-like-a-pro&quot;&gt;2. Frame Risks Like a Pro&lt;&#x2F;h3&gt;
&lt;p&gt;The trick to surviving the RAID log? Make yourself look proactive. When you log risks, include a mitigation plan. “Integration delay due to API changes—working with DevOps to adjust timelines.” Now you’re the hero, not the scapegoat.&lt;&#x2F;p&gt;
&lt;p&gt;If Nigel logs “Unforeseen challenges with deployment,” one-up him with: “Deployment delay risk flagged and escalated to leadership. Monitoring mitigation progress.” Boom—Nigel’s vague entry now sounds like your victory lap.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-deploy-strategic-ambiguity&quot;&gt;3. Deploy Strategic Ambiguity&lt;&#x2F;h3&gt;
&lt;p&gt;Sometimes, you need to play Rick’s game, but better. Log risks that make you look smart without pinning you down.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of Rick’s “Critical failures possible,” try: “Potential latency under peak loads due to infrastructure scaling—monitoring required.”&lt;&#x2F;p&gt;
&lt;p&gt;It’s technical enough to impress Nigel and vague enough to avoid blame.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-use-humor-to-control-the-room&quot;&gt;4. Use Humor to Control the Room&lt;&#x2F;h3&gt;
&lt;p&gt;When RAID meetings descend into chaos, a well-timed joke can shift the tone. Once, during one of Eddie’s infamous risk monologues, someone interrupted with: “Is this about the pizza again?” The room laughed, the tension broke, and Eddie’s risk log shrank by 20 items.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;more-ways-to-use-raid-logs-to-your-advantage&quot;&gt;More Ways to Use RAID Logs to Your Advantage&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;good-create-a-log-of-wins&quot;&gt;Good: Create a Log of Wins&lt;&#x2F;h4&gt;
&lt;p&gt;Don’t just flag risks—document your successes. When a risk is resolved, add a note like “Mitigation successful—delivered API integration ahead of schedule.” Now the log isn’t just a list of failures waiting to happen; it’s a record of your victories.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;evil-the-layered-blame-shield&quot;&gt;Evil: The Layered Blame Shield&lt;&#x2F;h4&gt;
&lt;p&gt;Log risks that subtly pass responsibility onto others while making you look proactive.&lt;&#x2F;p&gt;
&lt;p&gt;Example: “Vendor X tool updates delayed—flagged to procurement team for follow-up.”&lt;&#x2F;p&gt;
&lt;p&gt;If the delay causes issues, it’s on procurement. If it’s resolved smoothly, you’re the hero who escalated it.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;good-risk-triage-hero&quot;&gt;Good: Risk Triage Hero&lt;&#x2F;h4&gt;
&lt;p&gt;During chaotic RAID meetings, step up as the voice of reason. Say things like, “Let’s focus on the high-impact risks and save the smaller ones for offline discussion.” People will start associating you with clarity and efficiency.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;evil-risk-triage-saboteur&quot;&gt;Evil: Risk Triage Saboteur&lt;&#x2F;h4&gt;
&lt;p&gt;Use triage as a power move. Suggest deprioritizing risks logged by people you secretly want to undermine (cough Betty cough). Frame it as “streamlining,” and nobody will notice you’re sabotaging their credibility.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;good-the-raid-whisperer&quot;&gt;Good: The RAID Whisperer&lt;&#x2F;h4&gt;
&lt;p&gt;Offer to manage the RAID log for your team. Keep it accurate, concise, and aligned with project goals. You’ll gain trust and authority over the process, ensuring the log is actually useful.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;evil-the-puppet-master&quot;&gt;Evil: The Puppet Master&lt;&#x2F;h4&gt;
&lt;p&gt;Managing the log means you control the narrative. Frame risks and dependencies to subtly shift credit toward your team and accountability away from it. Example:&lt;&#x2F;p&gt;
&lt;p&gt;“Dependency resolved through proactive engagement from Team A.”&lt;&#x2F;p&gt;
&lt;p&gt;“Delay risk escalated due to Team Z’s lack of timely input.”&lt;&#x2F;p&gt;
&lt;h4 id=&quot;good-educate-the-non-techs&quot;&gt;Good: Educate the Non-Techs&lt;&#x2F;h4&gt;
&lt;p&gt;If Nigel logs vague risks, take a moment to educate him. Explain why “Integration challenges” isn’t actionable and suggest something like “Data format mismatch in endpoint integration.” It’s not glamorous, but it might make the RAID log slightly less infuriating.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;evil-nigel-whispering&quot;&gt;Evil: Nigel Whispering&lt;&#x2F;h4&gt;
&lt;p&gt;Instead of educating Nigel, feed him risks that align with your agenda. Suggest he log “Potential system inefficiencies with Vendor X” so leadership starts doubting the vendor you’ve always hated. Nigel will think you’re a genius, and you get plausible deniability.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;good-clarify-assumptions&quot;&gt;Good: Clarify Assumptions&lt;&#x2F;h4&gt;
&lt;p&gt;If assumptions are logged vaguely, clarify them in a way that benefits the team. Example: “Assume resource availability for Q4 testing.” If questioned later, you can point out that the assumption was clearly documented.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;evil-assumption-ambiguity&quot;&gt;Evil: Assumption Ambiguity&lt;&#x2F;h4&gt;
&lt;p&gt;Log assumptions so broad that they’re impossible to disprove. Example: “Assume smooth transition to production.” If anything goes wrong, shrug and say, “Well, we assumed everything would go right.”&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-a-raid-log-might-be-politicized&quot;&gt;Why a RAID Log Might Be Politicized&lt;&#x2F;h2&gt;
&lt;p&gt;Why does the RAID log bring out the worst in [fictional] people? It seems to me (the real me, not the ChatGPT ascii spewing machine that wrote most of this amusing sillyness) that there&#x27;s something about the RAID log that brings out the worst and most political behaviour in people. Of course I asked GPT to tell me what could be going on there, to help me understand the dynamics. I think the following is helpful in seeing what might be at play when people behave in odd ways, and might have negative feelings about this particular artifact of project management. See if you can see which of these underlie the behaviour of the above charlatans.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;risk-aversion-and-cya-cover-your-ass-ets&quot;&gt;Risk Aversion and CYA (Cover Your Ass[ets])&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Behavior: Individuals or teams log overly detailed risks and issues that might be unlikely but could protect them if things go wrong.&lt;&#x2F;li&gt;
&lt;li&gt;Motivation: If something fails, they can point to the RAID log and say, &quot;I warned you.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Impact: This creates noise and a culture of fear, making it harder to focus on genuinely significant risks.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;blame-shifting&quot;&gt;Blame Shifting&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Behavior: Risks, issues, or dependencies are deliberately framed to highlight failures of other teams or external factors.&lt;&#x2F;li&gt;
&lt;li&gt;Motivation: To protect their own reputation or gain leverage in cross-functional conflicts.&lt;&#x2F;li&gt;
&lt;li&gt;Impact: The log becomes a political battlefield, detracting from its intended purpose of fostering collaboration and solving problems.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;overloading-assumptions-to-push-agendas&quot;&gt;Overloading Assumptions to Push Agendas&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Behavior: Assumptions are crafted to justify a preferred course of action (e.g., &quot;Assuming budget approval by X date&quot; to pressure finance).&lt;&#x2F;li&gt;
&lt;li&gt;Motivation: To manipulate decisions or shift focus toward personal priorities.&lt;&#x2F;li&gt;
&lt;li&gt;Impact: It can distort the actual state of the project, leading to poorly informed decisions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;cherry-picking-risks-and-issues&quot;&gt;Cherry-Picking Risks and Issues&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Behavior: Only certain risks or issues are highlighted in the RAID log, depending on what aligns with a person’s agenda.&lt;&#x2F;li&gt;
&lt;li&gt;Motivation: To downplay problems in their area or exaggerate issues elsewhere.&lt;&#x2F;li&gt;
&lt;li&gt;Impact: Critical risks may be ignored, and the project team may lose trust in the log&#x27;s integrity.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;weaponizing-dependencies&quot;&gt;Weaponizing Dependencies&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Behavior: Teams strategically emphasize dependencies on others to exert pressure or avoid accountability.&lt;&#x2F;li&gt;
&lt;li&gt;Motivation: To deflect responsibility or create negotiating leverage.&lt;&#x2F;li&gt;
&lt;li&gt;Impact: Creates resentment and stalls cooperation, rather than encouraging proactive problem-solving.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;why-does-this-happen&quot;&gt;Why Does This Happen?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Organizational Culture: In highly political environments, people may prioritize self-preservation or career advancement over the success of the project.&lt;&#x2F;li&gt;
&lt;li&gt;Fear of Failure: RAID logs might be seen as a mechanism for postmortems rather than proactive tools, encouraging defensive behavior.&lt;&#x2F;li&gt;
&lt;li&gt;Lack of Clarity in Ownership: If RAID items are not tied to actionable responsibilities, they can be manipulated to avoid blame or effort.&lt;&#x2F;li&gt;
&lt;li&gt;Stakeholder Dynamics: RAID logs can be used to placate senior stakeholders or push decisions in a particular direction, even at the expense of project realities.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;signs-your-raid-log-is-being-politicized&quot;&gt;Signs Your RAID Log Is Being Politicized&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Overly Complex Entries: Risks or issues are framed in convoluted language to obscure accountability.&lt;&#x2F;li&gt;
&lt;li&gt;Finger-Pointing Language: Phrases like “caused by X team” or “waiting on Y team” dominate the log.&lt;&#x2F;li&gt;
&lt;li&gt;Focus on Low-Impact Risks: Trivial risks are highlighted while critical risks are ignored or minimized.&lt;&#x2F;li&gt;
&lt;li&gt;Frequent Revisions Without Progress: Items are frequently updated or rewritten, but little action is taken to resolve them.&lt;&#x2F;li&gt;
&lt;li&gt;Lack of Engagement by Teams: The RAID log is maintained by a single person or group without team-wide buy-in or collaboration.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;final-thoughts-tool-or-trap&quot;&gt;Final Thoughts: Tool or Trap?&lt;&#x2F;h2&gt;
&lt;p&gt;RAID logs can be incredible tools for project clarity—or an absolute mess of politics and nonsense. It all depends on how they’re used (or abused) and the context within which they exist.&lt;&#x2F;p&gt;
&lt;p&gt;So what’s your take? Are RAID logs the unsung heroes of project management, or just an elaborate game of CYA? Would you champion them, or weaponize them like Betty and Rick?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Should you create tickets for tech tasks?</title>
        <published>2024-10-07T00:00:00+00:00</published>
        <updated>2024-10-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/10/07/should-you-create-tickets-for-tech-tasks/"/>
        <id>https://0x5.uk/2024/10/07/should-you-create-tickets-for-tech-tasks/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/10/07/should-you-create-tickets-for-tech-tasks/">&lt;p&gt;In the manner of choosing the colour to paint the bikeshed, the decision of whether to create a ticket for every single tiny commit, no matter whether it&#x27;s a giant feature or the tiniest whitespace cleanup in the readme file continues to consume countless hours. This question is not really that important when it comes to delivering software, yet it still comes up from time to time and there is a right and wrong answer, which should be modified only with consideration for the current situation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;in-short&quot;&gt;In short&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Correct: create tickets only for features and larger technical work. Allow engineers to commit smaller improvements ad-hoc.&lt;&#x2F;li&gt;
&lt;li&gt;Incorrect: create an atmosphere of stifling bureaucracy where all attempts to keep the work area tidy will require sign-off from the CFO and approval from the product owner who has never written a line of code (some have, but that&#x27;s a rare wonder).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;who-cares&quot;&gt;Who cares?&lt;&#x2F;h2&gt;
&lt;p&gt;If anyone wonders why engineers get &lt;em&gt;so&lt;&#x2F;em&gt; bent out of shape about this seemingly harmless request, imagine if someone asked you to fill out a form and submit it for every single piece of your work that you currently don&#x27;t have to. Want to pick up the phone?… create a ticket. Want to send an email?… - create a ticket. Can you imagine that this might make you a) miserable, b) less productive, and c) give up trying to do more than the bare minimum.&lt;&#x2F;p&gt;
&lt;p&gt;By requesting tickets for everything you are introducing friction directly into the path of a programmer&#x27;s most important output - the codebase.&lt;&#x2F;p&gt;
&lt;p&gt;As experienced developers we instinctively know that fast iteration and short cycle times lead to better delivery of value to users, and instinctively dislike anything that gets in the way.&lt;&#x2F;p&gt;
&lt;p&gt;That the need for &quot;auditing&quot; and &quot;why it changed&quot; are already covered by source control history (git) and &quot;pull requests&quot; so adding a requirement for tickets is redundant toil with little additional benefit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;turning-to-gpt-for-explanations&quot;&gt;Turning to GPT for explanations&lt;&#x2F;h2&gt;
&lt;p&gt;And now, given that there can be reasons for adding a ticket link to everything (for example generating change logs from git), and in the modern tradition, we turn to ChatGPT for a properly argued discussion of both sides of the argument.&lt;&#x2F;p&gt;
&lt;p&gt;The following is an edited result of my discussion with ChatGPT on the subject. Should you find yourself in the situation where someone has decided that every brush stroke during the painting of the bikeshed should require a JIRA ticket then this article will provide a handy reference to all the arguments that can be made around this oh-so-trivial subject.&lt;&#x2F;p&gt;
&lt;p&gt;I particularly like the fact you can ask GPT to write in the styles of different personas, so first we have the curt &quot;lead dev&quot; version that gets to the point and is devoid of superfluous wording, empathy, and any other affordances to anyone who thinks in any other way than the tech lead; and then we have the more wordy default style of GPT that explains the points a bit more fully for the benefit of those who need a bit more explanation around the subject. Both are useful depending on the audience, so take your pick.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tech-lead-gpt-says&quot;&gt;Tech-lead-GPT Says…&lt;&#x2F;h2&gt;
&lt;p&gt;Following the usual wordy explanation I fed GPT this follow-up prompt:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;write it in the style of a busy lead dev engineer - still too fancy and formatted. plain ascii, missing capitalisation in places, nothing more than the bare facts&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;And got this straight-to-the-point explanation, lazy capitalization and all:&lt;&#x2F;p&gt;
&lt;p&gt;requiring a ticket for every tech improvement pr has upsides but will slow us down in key areas. here’s why:&lt;&#x2F;p&gt;
&lt;p&gt;pros:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;prioritization: a ticket makes sure we focus on impactful work. it forces us to ask if this improvement is really needed now or if it can wait.&lt;&#x2F;li&gt;
&lt;li&gt;consistency: everyone follows the same process. good for cross-team work or when other stakeholders need visibility.&lt;&#x2F;li&gt;
&lt;li&gt;accountability: tickets clarify why a change is being made, what the risks are, and who owns it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;cons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;overhead: creating tickets for minor improvements (e.g. small refactors or cleanup) adds unnecessary steps. this slows devs down and eats up time for actual coding.&lt;&#x2F;li&gt;
&lt;li&gt;discourages quick fixes: devs spot opportunities to fix things as they go. forcing them to stop and make a ticket breaks their flow and makes it less likely they’ll bother with small but important changes.&lt;&#x2F;li&gt;
&lt;li&gt;ticket bloat: if every tiny improvement needs a ticket, we’ll end up with a cluttered backlog full of minor stuff, making it harder to see what&#x27;s actually important.&lt;&#x2F;li&gt;
&lt;li&gt;developer autonomy: devs should be trusted to make small improvements without red tape. too many rules can kill morale and make them feel micromanaged.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;suggestion:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;use tickets for significant changes (major refactors, cross-team impact, etc.), not small things like code cleanup or minor improvements.&lt;&#x2F;li&gt;
&lt;li&gt;use pr descriptions to document and discuss small technical changes. keeps things lightweight without losing track of what&#x27;s been done.&lt;&#x2F;li&gt;
&lt;li&gt;let devs decide when a ticket is needed vs when a quick pr will do. they&#x27;ll know best.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;bottom line: tickets are useful for big changes but requiring them for every single tech improvement will slow us down more than it helps. let&#x27;s keep the process flexible where it makes sense.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;default-friendly-gpt-explains-fully&quot;&gt;Default friendly GPT explains fully&lt;&#x2F;h2&gt;
&lt;p&gt;This part is in GPT&#x27;s default style, with some editing of what points to include. It&#x27;s pretty much as it was generated, and I think does a good job of explaining the trade-offs for discussion:&lt;&#x2F;p&gt;
&lt;p&gt;Requiring a ticket for every technical improvement pull request is a policy with both advantages and drawbacks, and it’s important to weigh these carefully to ensure the team’s workflow is as efficient and effective as possible.
Pros of Requiring Tickets for Technical Improvements&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Improved Prioritization and Planning Tickets create a formal process for prioritizing work. When technical improvements require a ticket, it forces a discussion on whether the improvement is truly necessary or how urgent it is. This helps teams focus on the most impactful changes and avoid unnecessary or lower-priority adjustments, allowing better alignment with the overall project goals.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Consistency Across Teams In larger teams or organizations, requiring tickets for all work (including technical improvements) helps ensure consistency. Everyone follows the same process, which makes it easier to manage cross-team dependencies, ensure the necessary approvals, and communicate changes to stakeholders.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Clearer Communication and Accountability Tickets provide a clear space for discussing the reasoning behind technical improvements, including potential risks, trade-offs, or alternatives. This promotes better communication among developers, product managers, and other stakeholders, and helps ensure that everyone is on the same page. It also adds accountability, as each improvement is documented and has a clear owner.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Cons of Requiring Tickets for Technical Improvements&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Increased Administrative Overhead One of the biggest downsides is the added overhead. Many technical improvements are small, straightforward fixes or optimizations that don’t warrant the time and effort needed to create, manage, and track a ticket. Forcing developers to do this extra work can slow down progress and take time away from actual coding. Over time, this could lead to frustration or a slowdown in the pace of incremental improvements.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Discourages Quick, Organic Improvements Developers often spot opportunities for small technical improvements while they’re working on other tasks. Having to create a ticket for each of these can disrupt their workflow, making them less likely to act on these improvements when they notice them. This can lead to missed opportunities to clean up code, reduce technical debt, or optimize performance in small but meaningful ways.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Potential for Ticket Bloat In a fast-moving development environment, the requirement for tickets on small improvements could create a flood of minor issues in the ticketing system. This can make it harder to manage more critical work and obscure visibility into the progress of higher-priority features or bugs. The sheer volume of tickets can become difficult to sort through, adding cognitive load to project management.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Less Developer Autonomy Developers often thrive in environments where they can take initiative to improve the codebase. Requiring tickets for every small change might reduce their sense of ownership, as it introduces a layer of bureaucracy between identifying an issue and resolving it. This could dampen their motivation to take care of small, yet important, aspects of code quality.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A Balanced Approach&lt;&#x2F;p&gt;
&lt;p&gt;Given the pros and cons, there may be a middle ground that allows the team to capture the benefits of ticketing while avoiding its downsides:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ticketing for Significant Changes: Tickets could be required for larger technical improvements that have broader implications, such as major refactors, changes that affect multiple teams, or improvements that touch critical parts of the system. For smaller changes, like simple code cleanup, minor refactoring, or bug fixes, developers could be allowed to open a pull request without the overhead of a ticket.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Use Pull Requests for Tracking: The pull request itself can serve as a lightweight way to document and discuss technical improvements. Detailed PR descriptions, along with the review process, can provide enough visibility and communication for smaller improvements without the need for a formal ticket.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Developer Discretion: Allow developers to decide whether a ticket is needed based on the scope of the improvement. They are often best positioned to know whether a change is minor enough to be handled via a simple PR or whether it requires more discussion and prioritization through a ticket.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Conclusion&lt;&#x2F;p&gt;
&lt;p&gt;Requiring tickets for every technical improvement has clear advantages in terms of prioritization, consistency, and accountability, particularly in larger teams or complex projects. However, the added overhead, potential for slowing down minor improvements, and impact on developer autonomy are significant downsides to consider. A balanced approach that applies ticketing requirements more selectively, while still ensuring visibility and discussion through PRs, could be a better fit for fostering both productivity and quality in the development process.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why user stories should be shippable increments</title>
        <published>2024-09-12T00:00:00+00:00</published>
        <updated>2024-09-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/09/12/why-user-stories-should-be-shippable-increments/"/>
        <id>https://0x5.uk/2024/09/12/why-user-stories-should-be-shippable-increments/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/09/12/why-user-stories-should-be-shippable-increments/">&lt;p&gt;Sometimes I see people create work items &#x2F; jira tickets &#x2F; user- stories that if they were implemented and merged in to the codebase would leave the system in a half-finished state, either broken or inconsistent.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem-with-non-shippable-tickets&quot;&gt;The problem with non-shippable tickets&lt;&#x2F;h2&gt;
&lt;p&gt;This to me is instinctively a &quot;bad thing&quot;, however as not everyone has grokked this important fundamental of team software delivery, I turned to chat gpt for an explanation of why I think this is important, and I have to say it did a stellar job of clearly explaining the things that I have absorbed over my decades of commercial software development. So here you go, here&#x27;s why non-shippable tickets are a problem:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;incomplete-features-impact-user-experience&quot;&gt;Incomplete Features Impact User Experience&lt;&#x2F;h3&gt;
&lt;p&gt;A half-finished feature can confuse users or negatively impact their experience. If the feature is exposed to users before it&#x27;s fully functional, it may appear broken, resulting in dissatisfaction or mistrust in the system&#x27;s reliability.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;difficult-to-test-and-validate&quot;&gt;Difficult to Test and Validate&lt;&#x2F;h3&gt;
&lt;p&gt;Testing half-finished work is challenging, as it&#x27;s not in a stable or coherent state. Quality Assurance (QA) teams need a fully functional piece of work to validate it against the requirements. When a ticket is only partially completed, it’s hard to determine if it meets the intended functionality or introduces bugs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;complicates-future-development&quot;&gt;Complicates Future Development&lt;&#x2F;h3&gt;
&lt;p&gt;Leaving an unfinished task can create dependencies and conflicts with future work. If another developer later works on a related feature, they might have to deal with the incomplete state, which could introduce confusion or lead to mistakes in integrating related functionality.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;increases-technical-debt&quot;&gt;Increases Technical Debt&lt;&#x2F;h3&gt;
&lt;p&gt;Incomplete features often accumulate as technical debt, which means extra work will be needed later to finish, refactor, or fix them. This can slow down future progress, as more time will need to be spent revisiting and cleaning up the half-finished work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blocks-related-development&quot;&gt;Blocks Related Development&lt;&#x2F;h3&gt;
&lt;p&gt;A half-finished ticket can block progress on other features that depend on it. For example, if a partially completed feature introduces bugs or changes a shared system in an untested way, it could delay the development of other tickets or cause cascading issues across the system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reduces-team-efficiency&quot;&gt;Reduces Team Efficiency&lt;&#x2F;h3&gt;
&lt;p&gt;When a ticket is left in a half-finished state, developers may need to pick it up again later or pass it to another developer, leading to context-switching. This results in inefficiency, as time is wasted on re-clarifying the problem, re-understanding the code, and figuring out where the previous developer left off.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unclear-ownership-and-accountability&quot;&gt;Unclear Ownership and Accountability&lt;&#x2F;h3&gt;
&lt;p&gt;If a ticket is left unfinished, ownership and accountability become unclear. Other team members may not know who is responsible for completing it or what still needs to be done, which can cause confusion and reduce productivity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inconsistent-system-behavior&quot;&gt;Inconsistent System Behavior&lt;&#x2F;h3&gt;
&lt;p&gt;Partial implementation can cause the system to behave inconsistently. For example, a feature that&#x27;s half-completed might trigger errors, create discrepancies in data, or cause parts of the system to function incorrectly or unpredictably.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hinders-deployment-and-releases&quot;&gt;Hinders Deployment and Releases&lt;&#x2F;h3&gt;
&lt;p&gt;Half-finished tickets often disrupt deployment cycles, as incomplete features cannot be included in production. This results in unnecessary delays or the need to work around unfinished tickets, making releases more complex and error-prone.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wasted-effort-and-resources&quot;&gt;Wasted Effort and Resources&lt;&#x2F;h3&gt;
&lt;p&gt;When a ticket is not fully completed, there&#x27;s a risk that the work may be scrapped or need significant changes by the time it’s revisited. This can result in wasted development effort, resources, and time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unmet-stakeholder-expectations&quot;&gt;Unmet Stakeholder Expectations&lt;&#x2F;h3&gt;
&lt;p&gt;Leaving a ticket incomplete prevents stakeholders from seeing tangible progress, undermining confidence in the team&#x27;s ability to deliver. Stakeholders expect finished, usable deliverables that they can review and assess, not half-completed tasks that require further work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;difficult-to-manage-in-agile-processes&quot;&gt;Difficult to Manage in Agile Processes&lt;&#x2F;h3&gt;
&lt;p&gt;In Agile and Scrum methodologies, the goal is to deliver shippable increments of work at the end of each sprint. Leaving a ticket half-finished breaks this cycle, making it hard to close sprints successfully and creating spillover tasks that carry into future iterations.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;in-short&quot;&gt;In short&lt;&#x2F;h3&gt;
&lt;p&gt;Avoiding half-finished tickets ensures that the system remains stable, progress is clear, and each ticket represents a functional, complete deliverable. This promotes better workflow, higher quality, and more reliable software.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-create-small-shippable-batches&quot;&gt;How to create small shippable batches&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s all very well you say, but I don&#x27;t want to end up with giant, big-bang stories where engineering vanish for a month or six until every last thing works (if it ever does), so what to do?&lt;&#x2F;p&gt;
&lt;p&gt;Again I&#x27;ve turned to gpt as a starting point, and it&#x27;s not done a bad job, I&#x27;ve done a bit more editing to this set and added some of my own thoughts:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;use-vertical-slicing&quot;&gt;Use Vertical Slicing&lt;&#x2F;h3&gt;
&lt;p&gt;Vertical slicing means breaking down features into small, independent pieces that cut through all layers of the stack (UI, backend, database, etc.) and provide end-to-end functionality. Each slice delivers a fully functional piece of the feature, even if it’s a smaller or simpler version of the final product.
Example: Instead of building a complete &quot;user profile&quot; page, deliver a ticket for &quot;adding a profile picture&quot; with all the components needed (UI, API, storage).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;define-clear-acceptance-criteria&quot;&gt;Define Clear Acceptance Criteria&lt;&#x2F;h3&gt;
&lt;p&gt;Each ticket should have clear, well-defined acceptance criteria that detail exactly what constitutes a “done” state. These criteria ensure that the ticket can be completed independently and is deliverable as a unit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;focus-on-the-minimum-viable-product&quot;&gt;Focus on the minimum viable product&lt;&#x2F;h3&gt;
&lt;p&gt;Like the Minimal Viable Product (MVP) concept, you can apply the same thinking to individual product increments.&lt;&#x2F;p&gt;
&lt;p&gt;When designing features, focus on delivering the smallest possible version that is still valuable to users. This forces the team to identify the core functionality that is immediately useful, allowing for iterative improvement later.&lt;&#x2F;p&gt;
&lt;p&gt;Example: Instead of delivering a fully-featured analytics dashboard, start with a basic version that shows just the key metrics, and expand later.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;implement-feature-flags&quot;&gt;Implement Feature Flags&lt;&#x2F;h3&gt;
&lt;p&gt;Use feature flags to allow partially completed features to be merged into the main codebase without affecting the user experience. This ensures that work can be released incrementally but hidden or disabled until it is complete.&lt;&#x2F;p&gt;
&lt;p&gt;Example: A half-built &quot;comments section&quot; can be developed over several tickets but hidden from users until all parts are ready.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;break-down-complex-features&quot;&gt;Break Down Complex Features&lt;&#x2F;h3&gt;
&lt;p&gt;Complex features should be split into smaller sub-features that can each be delivered independently. Ensure that each sub-feature is fully functional, even if it doesn&#x27;t have all the final functionality.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;avoid-over-engineering&quot;&gt;Avoid Over-Engineering&lt;&#x2F;h3&gt;
&lt;p&gt;Start with the simplest solution to a problem, and iterate.&lt;&#x2F;p&gt;
&lt;p&gt;Avoid adding extra complexity upfront by sticking to what’s necessary to fulfill the ticket’s requirements for delivery.&lt;&#x2F;p&gt;
&lt;p&gt;This includes &quot;gold plating&quot; and &quot;future proofing&quot; when implementing the ticket. Just do the minimum high-quality code that you &lt;em&gt;know&lt;&#x2F;em&gt; you need now.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;make-use-of-stubs-and-mocks&quot;&gt;Make Use of Stubs and Mocks&lt;&#x2F;h3&gt;
&lt;p&gt;To avoid leaving a ticket half-finished when other dependencies aren’t ready, use stubs or mocks for parts of the system that are still under development. This allows you to complete and deliver your ticket while waiting for those dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;Example: If the backend API isn’t ready, a front-end ticket can use mock data to simulate responses, allowing the UI to be built and delivered without waiting.&lt;&#x2F;p&gt;
&lt;p&gt;This is more appropriate for very early product development rather than for modifying an established system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;communicate-dependencies-clearly&quot;&gt;Communicate Dependencies Clearly&lt;&#x2F;h3&gt;
&lt;p&gt;If a feature is dependent on other parts of the system, make sure the dependencies are identified and managed.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes it makes sense to coordinate related tickets so they’re developed together or in the right sequence.&lt;&#x2F;p&gt;
&lt;p&gt;Example: If a new API endpoint is needed for a UI feature, ensure the API ticket is prioritized so the front-end team isn&#x27;t blocked, or vice versa.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;collaborate-in-cross-functional-teams&quot;&gt;Collaborate in Cross-Functional Teams&lt;&#x2F;h3&gt;
&lt;p&gt;Ensure cross-functional teams collaborate on the entire stack of a feature (UI, backend, database, etc.) within the same sprint or ticket. This ensures no part of the feature is half-done or stuck waiting for another team to finish their part.&lt;&#x2F;p&gt;
&lt;p&gt;Example: A ticket to create a new form should include front-end developers, back-end developers, and testers working together to ensure it&#x27;s functional from end to end.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cross-functional-brainstorming-of-story-creation&quot;&gt;Cross-functional brainstorming of story creation&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;s nothing like all members of a team, including product, engineering, UX etc all sitting round a table and throwing around ideas to see if they can come up with a creative way to break down a problem into smaller but still shippable pieces.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve repeated this exercise with many clients and the flashes of inspiration that come out of it cannot be replicated by thinking harder on one&#x27;s own while starting at Jira.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;By structuring work this way, teams can maintain a balance between small, manageable batches of work and ensuring that each piece is fully deliverable and functional on its own.&lt;&#x2F;p&gt;
&lt;p&gt;This approach maximizes delivery velocity while maintaining system integrity and delivering value incrementally.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running xUnit Test Setup Only Once Across Multiple Test Classes</title>
        <published>2024-08-02T00:00:00+00:00</published>
        <updated>2024-08-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/08/02/running-xunit-test-setup-only-once/"/>
        <id>https://0x5.uk/2024/08/02/running-xunit-test-setup-only-once/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/08/02/running-xunit-test-setup-only-once/">&lt;p&gt;⚠️ There is a problem with the approach below. Yet again I&#x27;ve been fooled&#x2F;confused by the xUnit documentation, and this doesn&#x27;t actually  do quite what I expected it to do when I tested it out for real. Once again I learn the lesson that I shouldn&#x27;t rush things out the door because I&#x27;m running out of time in the moment, even though something doesn&#x27;t seem right. I thought the incorrect behaviour was some minor bug in my example code, but it seem that collection fixtures just don&#x27;t do what I (and the GPT it seems) thought they did.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll come back and rewrite this to be more accurate when I&#x27;ve finished researching the various behaviours and approaches within the example repo I&#x27;m working on - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;CollectionFixtureXUnitExample&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;CollectionFixtureXUnitExample&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the meantime, know that an extension published by a different author does indeed give us the &quot;setup once for all tests&#x2F;classes&quot; that we&#x27;re looking for here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;Xunit.Extensions.AssemblyFixture&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;Xunit.Extensions.AssemblyFixture&#x2F;&lt;&#x2F;a&gt; &#x2F; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;JDCain&#x2F;Xunit.Extensions.AssemblyFixture&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;JDCain&#x2F;Xunit.Extensions.AssemblyFixture&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Original post from here - still explains collection fixture usage, but they do not actually get re-used across multiple classes, only within a single class. Also watch out for thread safety as the fixtures instances seem to be used in parallel test runs so must be thread safe.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I don&#x27;t know about you, but I found the official &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;xunit.net&#x2F;docs&#x2F;shared-context#collection-fixture&quot;&gt;xUnit documentation on collection fixtures&lt;&#x2F;a&gt; endlessly confusing when I actually just want to get my test setup to run the right number of times.&lt;&#x2F;p&gt;
&lt;p&gt;The one that particularly trips me up is preventing a setup method from being run twice when running multiple test classes all at once.&lt;&#x2F;p&gt;
&lt;p&gt;xUnit is probably the best test framework out of MSTest (yuk), NUnit and xUnit, but suffers from slightly arcane terminology and okay but sometimes confusing documentation.&lt;&#x2F;p&gt;
&lt;p&gt;This post captures all the pertinent pieces of the puzzle in one place along with some human explanation of the concepts involved.&lt;&#x2F;p&gt;
&lt;p&gt;The example code can be found at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;CollectionFixtureXUnitExample&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;CollectionFixtureXUnitExample&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-1-create-a-fixture-class&quot;&gt;Step 1: Create a Fixture Class&lt;&#x2F;h2&gt;
&lt;p&gt;First, create a class that contains the setup code that should only run once.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);font-style: italic;&quot;&gt;summary&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; Setup &#x2F; teardown code that the tests need to work.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);font-style: italic;&quot;&gt;summary&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; SharedFixture&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; IDisposable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; SharedFixture&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        Console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;WriteLine&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;$&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Running &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;SharedFixture&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; constructor -  Setup code that runs once across all test classes.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Dispose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        Console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;WriteLine&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;$&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Running &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;SharedFixture&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; dispose -  Cleanup code that runs once after all tests are done&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;step-2-create-a-collection-definition&quot;&gt;Step 2: Create a Collection Definition&lt;&#x2F;h2&gt;
&lt;p&gt;You need to define a test collection that allows you to connect the fixture to the test classes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);font-style: italic;&quot;&gt;summary&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; This exists to prevent xUnit running the SharedFixture setup more than once&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; concurrently when multiple test classes are executed at once,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; and as a middle point in connecting the fixture to the test classes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);font-style: italic;&quot;&gt;summary&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;CollectionDefinition&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;SharedFixtureCollection&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; SharedFixtureCollection&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; ICollectionFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;SharedFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;step-3-decorate-your-test-classes&quot;&gt;Step 3: Decorate your test classes&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Add the &lt;code&gt;[Collection]&lt;&#x2F;code&gt; attribute to each test class to tie them to the shared collection.&lt;&#x2F;li&gt;
&lt;li&gt;Implement the &lt;code&gt;IClassFixture&amp;lt;TFixture&amp;gt;&lt;&#x2F;code&gt; interface in each test class that needs to use the shared fixture.&lt;&#x2F;li&gt;
&lt;li&gt;Optionally add a constructor to accept the fixture if you need access to it during your tests.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;By adding the &lt;code&gt;[Collection]&lt;&#x2F;code&gt; attribute, you associate the test classes with the shared collection, ensuring that the setup code in SharedFixture runs only once for all the classes in the collection.&lt;&#x2F;p&gt;
&lt;p&gt;By (optionally) adding the fixture as a constructor parameter xUnit will inject fixture object gives access to the fixture object.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Collection&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;SharedFixtureCollection&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; TestClass1&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; IClassFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;SharedFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;    SharedFixture&lt;&#x2F;span&gt;&lt;span&gt; _fixture&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; TestClass1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;SharedFixture&lt;&#x2F;span&gt;&lt;span&gt; fixture&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        _fixture&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; fixture&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; this is how you get access to the fixture from the tests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Fact&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Test2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        Console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;WriteLine&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;$&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;- Running &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TestClass1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TestClass1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Test2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; _fixture.DoSomething();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        Assert&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B58900, #B58900);&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Fact&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Test1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        Console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;WriteLine&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;$&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;- Running &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TestClass1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TestClass1&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Test1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        Assert&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B58900, #B58900);&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Collection&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;SharedFixtureCollection&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; TestClass2&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; IClassFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;SharedFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Fact&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Test3&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        Console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;WriteLine&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;$&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;- Running &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TestClass2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;nameof&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TestClass2&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Test3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        Assert&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B58900, #B58900);&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@codebob75&#x2F;unit-testing-in-c-with-xunit-complete-guide-18ee2b919b05#:~:text=you%20can%20actually%20remove%20the%20following&quot;&gt;According to Code Bob you can remove the inheritance of IClassFixture&lt;&#x2F;a&gt;. At this point I&#x27;m pretty much too superstitious about all this to even try it. I might come back to this later.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pieces-of-the-puzzle&quot;&gt;Pieces of the puzzle&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;per-class-setup-teardown&quot;&gt;Per-class setup&#x2F;teardown&lt;&#x2F;h3&gt;
&lt;p&gt;For a single test class, xUnit just uses the normal constructor of the test class &#x2F; fixture for setup, and by implementing &lt;code&gt;IDisposable&lt;&#x2F;code&gt; you can also implement a teardown, even for something expensive like clearing down or deleting a database or files.&lt;&#x2F;p&gt;
&lt;p&gt;If you don&#x27;t need to co-ordinate this across test classes you can just use this without all the stuff in this post.&lt;&#x2F;p&gt;
&lt;p&gt;Note that xUnit does not re-use the test class object, and will generate a new object for every test in the class resulting in the constructor being run for every test ran that once for all the tests in a class. (This is the opposite of NUnit, which initialized the test class once and uses it for each test in the class, which is faster but risks contaminated state).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;async-setup-teardown&quot;&gt;Async setup&#x2F;teardown&lt;&#x2F;h3&gt;
&lt;p&gt;If your setup&#x2F;teardown needs to use async method calls then you can implement &lt;code&gt;IAsyncLifetime&lt;&#x2F;code&gt; on your fixture to run the async tasks during setup&#x2F;teardown.&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;25519155&#x2F;await-tasks-in-test-setup-code-in-xunit-net&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;25519155&#x2F;await-tasks-in-test-setup-code-in-xunit-net&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;collection-fixtures&quot;&gt;Collection &quot;Fixtures&quot;&lt;&#x2F;h3&gt;
&lt;p&gt;The fixture would contain any code you need to create the correct state before the tests execute and cleanup afterwards.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;test-collections&quot;&gt;Test Collections&lt;&#x2F;h3&gt;
&lt;p&gt;Confusingly these serve two completely unrelated purposes, and come in the form of both an attribute with a string collection name, and a class you can inherit from.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;Collection&lt;&#x2F;code&gt; attribute can be used to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Provide a common setup class&lt;&#x2F;li&gt;
&lt;li&gt;Prevent multiple test classes running in parallel&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;test-collections-parallelism&quot;&gt;Test Collections - parallelism&lt;&#x2F;h4&gt;
&lt;p&gt;By default tests within a class run in series, and test classes are run in parallel. By adding a named collection all tests in that collection will run in series.&lt;&#x2F;p&gt;
&lt;p&gt;E.g.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Collection&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;NonParallelCollection&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; prevent parallel run with TestClass2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; TestClass1&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; ... &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Collection&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;NonParallelCollection&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; prevent parallel run with TestClass1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; TestClass2&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; ... &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Collection&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;OtherCollection&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; will still run in parallel with 1 &amp;amp; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; TestClass3&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; ... &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For this use of collections  you do &lt;em&gt;not&lt;&#x2F;em&gt; need a collection class, just all the string names to match up.&lt;&#x2F;p&gt;
&lt;p&gt;For stronger naming make sure to use &lt;code&gt;nameof&lt;&#x2F;code&gt; or a &lt;code&gt;const string&lt;&#x2F;code&gt; to show that the strings are not just coincidentally the same and allow future developers to use &quot;find references&quot; to see what is using it.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the other way to change it is with the &lt;code&gt;CollectionBehavior&lt;&#x2F;code&gt; assembly attribute: &lt;code&gt;[assembly: CollectionBehavior(...)]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;xunit.net&#x2F;docs&#x2F;running-tests-in-parallel#parallelism-in-test-frameworks&quot;&gt;https:&#x2F;&#x2F;xunit.net&#x2F;docs&#x2F;running-tests-in-parallel#parallelism-in-test-frameworks&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;test-collections-a-link-to-setup-code&quot;&gt;Test Collections - a link to setup code&lt;&#x2F;h4&gt;
&lt;p&gt;You can create a &quot;fixture&quot; class with setup&#x2F;teardown code in it, but without further code xUnit will not know that your tests need it run.&lt;&#x2F;p&gt;
&lt;p&gt;To tell xUnit to actually run the setup&#x2F;teardown, and this is one of the more mind-bending bits of xUnit, you have to pass your fixture class name as a generic parameter to the collection fixture interface when your &quot;collection&quot; class inherits from &lt;code&gt;ICollectionFixture&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I.e.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; SomeArbitraryCollection&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; ICollectionFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;YourSetupFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then finally to actually connect the fixture to the test class being run,&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Add a &lt;code&gt;CollectionDefinition&lt;&#x2F;code&gt; attribute to your collection class with an arbitrary string argument to give it a unique collection name&lt;&#x2F;li&gt;
&lt;li&gt;Annotated the test class(es) with a &lt;code&gt;Collection&lt;&#x2F;code&gt; attribute, **where the argument is the name&quot;&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I.e.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;CollectionDefinition&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;These Names Must Match&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; SomeArbitraryCollection&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; ICollectionFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;YourSetupFixture&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;Collection&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;These Names Must Match&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; TestClass3&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; ... &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In my view this is a weakness of the xUnit API design. It&#x27;s very hard to follow, and can fail at runtime if your constructor fixture doesn&#x27;t match the generic type of the collection.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;footnote-assembly-parallelization&quot;&gt;Footnote - Assembly Parallelization&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s also worth knowing that the xunit test runner can &lt;em&gt;also&lt;&#x2F;em&gt; run multiple test assemblies in parallel, which could cause problems with trying to make sure your setup only runs once per test run.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;xunit.runner.json&lt;&#x2F;code&gt; configuration file to enable assembly parallelization:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;parallelizeAssembly&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B58900, #B58900);&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;53955469&#x2F;dotnet-test-how-to-run-xunit-tests-projects-in-parallel&#x2F;53957938#53957938&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;53955469&#x2F;dotnet-test-how-to-run-xunit-tests-projects-in-parallel&#x2F;53957938#53957938&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;xunit.net&#x2F;docs&#x2F;running-tests-in-parallel#parallelism-in-runners&quot;&gt;https:&#x2F;&#x2F;xunit.net&#x2F;docs&#x2F;running-tests-in-parallel#parallelism-in-runners&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;xunit.net&#x2F;docs&#x2F;shared-context&quot;&gt;https:&#x2F;&#x2F;xunit.net&#x2F;docs&#x2F;shared-context&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;13829737&#x2F;run-code-once-before-and-after-all-tests-in-xunit-net&#x2F;33778396#33778396&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;13829737&#x2F;run-code-once-before-and-after-all-tests-in-xunit-net&#x2F;33778396#33778396&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;xunit&#x2F;samples.xunit&#x2F;tree&#x2F;main&#x2F;v2&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;xunit&#x2F;samples.xunit&#x2F;tree&#x2F;main&#x2F;v2&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@codebob75&#x2F;unit-testing-in-c-with-xunit-complete-guide-18ee2b919b05&quot;&gt;https:&#x2F;&#x2F;medium.com&#x2F;@codebob75&#x2F;unit-testing-in-c-with-xunit-complete-guide-18ee2b919b05&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hamidmosalla.com&#x2F;2020&#x2F;01&#x2F;26&#x2F;xunit-part-4-parallelism-and-custom-test-collections&#x2F;&quot;&gt;https:&#x2F;&#x2F;hamidmosalla.com&#x2F;2020&#x2F;01&#x2F;26&#x2F;xunit-part-4-parallelism-and-custom-test-collections&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tsuyoshiushio.medium.com&#x2F;controlling-the-serial-and-parallel-test-on-xunit-6174326da196&quot;&gt;https:&#x2F;&#x2F;tsuyoshiushio.medium.com&#x2F;controlling-the-serial-and-parallel-test-on-xunit-6174326da196&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;xunit&#x2F;xunit&#x2F;issues&#x2F;2099&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;xunit&#x2F;xunit&#x2F;issues&#x2F;2099&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jimmybogard.com&#x2F;integration-testing-with-xunit&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.jimmybogard.com&#x2F;integration-testing-with-xunit&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running a beefy virtualbox dev server</title>
        <published>2024-06-07T00:00:00+00:00</published>
        <updated>2024-06-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/06/07/running-a-beefy-virtualbox-dev-server/"/>
        <id>https://0x5.uk/2024/06/07/running-a-beefy-virtualbox-dev-server/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/06/07/running-a-beefy-virtualbox-dev-server/">&lt;h2 id=&quot;why&quot;&gt;Why&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes I have to work on hairy old sprawling legacy code bases in ye-olde c#, which means, unfortunately, no shiny new dotnet-core with Rider on linux and all the speed gains that brings.&lt;&#x2F;p&gt;
&lt;p&gt;So having fallen over another codebase that takes unbearably long to build and work on when combined with the need to run visual studio in a windows virtualbox vm on top of my linux box I&#x27;ve shelled out for a desktop pc with a top-end cpu to use as a dev box for those trickier builds. But who wants to give up the joy of a portable laptop, so here I am with the challenge of connecting to virtualbox from another machine. Turns out there&#x27;s a few non-obvious things and options that may or may not work for you, so here&#x27;s what worked for me.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gnu-s-not-unix-and-neither-is-windows&quot;&gt;GNU&#x27;s Not Unix and neither is Windows&lt;&#x2F;h3&gt;
&lt;p&gt;Aside - windows will never again have ownership of my computer, I relegated it to a VM for emergencies (i.e. clients paying money), where it can stay within those steely confines unable to bother me the rest of the time. But that&#x27;s another blog post really.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basic-setup&quot;&gt;Basic setup&lt;&#x2F;h2&gt;
&lt;p&gt;This is pretty simple:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linuxmint.com&#x2F;&quot;&gt;Linux Mint&lt;&#x2F;a&gt; because home servers are a lot easier to deal with when they&#x27;re actually just normal desktop operating systems that are switched on more.
&lt;ol&gt;
&lt;li&gt;Enable full disk encryption during setup (advanced &amp;gt; lvm &amp;gt; encrypt) (this is a bit of a nuisance for remote management but important for security if the machine is stolen)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Turn on automatic updates&lt;&#x2F;li&gt;
&lt;li&gt;Install virtualbox and openssh-server&lt;&#x2F;li&gt;
&lt;li&gt;Copy the &quot;Virtualbox VMs&quot; folder across by opening &lt;code&gt;sftp:&#x2F;&#x2F;ur-server-here&#x2F;&lt;&#x2F;code&gt; in nemo (the file browser) on the source machine. It&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;48399&#x2F;fast-way-to-copy-a-large-file-on-a-lan&quot;&gt;not the quickest&lt;&#x2F;a&gt; but it did 200gb in 5 hours, and I have other things to do in my life so that&#x27;s fine.&lt;&#x2F;li&gt;
&lt;li&gt;Fire it up on the desktop with the virtualbox gui just to check it&#x27;s fine&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;remote-access-linux&quot;&gt;Remote access - linux&lt;&#x2F;h2&gt;
&lt;p&gt;To get some remote control of the machine simple &lt;code&gt;ssh&lt;&#x2F;code&gt; and &lt;code&gt;ssh -X&lt;&#x2F;code&gt; are enough for cli actions and some gui actions respectively (&lt;code&gt;-X&lt;&#x2F;code&gt; tunnels x-windows over ssh, meaning you can launch graphical programs on the remote machine and they pop up on the local display. Magic.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remote-access-windows-vm&quot;&gt;Remote access windows vm&lt;&#x2F;h2&gt;
&lt;p&gt;This proved to be less obvious.&lt;&#x2F;p&gt;
&lt;p&gt;There are three possible layers to remote in:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Remote access to the host machine UI&lt;&#x2F;li&gt;
&lt;li&gt;Remote access to the virtualbox process&lt;&#x2F;li&gt;
&lt;li&gt;Remote access to the windows vm&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Only number 3, directly connecting to the guest windows vm with RDP worked for me.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-host-connection&quot;&gt;1. Host connection&lt;&#x2F;h3&gt;
&lt;p&gt;Remote desktop in linux is still a bit of a mess.&lt;&#x2F;p&gt;
&lt;p&gt;VNC is klunky old, and I don&#x27;t even know if it&#x27;s secure any more, it&#x27;s also not available out of the box. I didn&#x27;t even try.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s some more or less proprietary ones like nx (nomachine?), &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rustdesk.com&#x2F;&quot;&gt;rustdesk&lt;&#x2F;a&gt;, go-to-my-pc etc, which I either haven&#x27;t had any luck with previously or haven&#x27;t tried &#x2F; don&#x27;t trust.&lt;&#x2F;p&gt;
&lt;p&gt;I tried running the virtualbox command gui over ssh, but it had two problems:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;It was too laggy &#x2F; slow updating the screen to be useable for intense visual studio coding work&lt;&#x2F;li&gt;
&lt;li&gt;Disconnecting killed the virtualbox process and terminated the vm without proper shutdown&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I quickly gave up on this and tried #2...&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-remote-access-to-virtualbox&quot;&gt;2. Remote access to virtualbox&lt;&#x2F;h3&gt;
&lt;p&gt;Tantalizingly &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.virtualbox.org&#x2F;manual&#x2F;ch07.html&quot;&gt;virtualbox has RDP support available&lt;&#x2F;a&gt;.... but the punchline is that it&#x27;s not part of the open source project, and is a proprietary &quot;extension&quot; that requires agreement to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;146398&#x2F;virtualbox-puel-interpretation&#x2F;1315219#1315219&quot;&gt;a personal&#x2F;evaluation license that explicitly forbids commercial use&lt;&#x2F;a&gt;, so that was out. Darn. If you&#x27;re only doing personal things you could try this, but I&#x27;m not so can&#x27;t.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-remote-access-to-windows-vm&quot;&gt;3. Remote access to windows vm&lt;&#x2F;h3&gt;
&lt;p&gt;This was the winner in the end but requires a few steps to get set up:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Change the virtualbox vm network settings to &quot;bridged&quot; instead of the default &quot;NAT&quot; so that the vm is available directly on the network.&lt;&#x2F;li&gt;
&lt;li&gt;Grab the generated ipv6 address for the machine (or give it a static ip4 lease)&lt;&#x2F;li&gt;
&lt;li&gt;In the windows guest:
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;windows-server&#x2F;remote&#x2F;remote-desktop-services&#x2F;clients&#x2F;remote-desktop-allow-access&quot;&gt;Enable remote desktop&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Give the user account a password if it doesn&#x27;t already have one (you can&#x27;t connect remotely with a passwordless user).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Start the vm with the virtualbox cli instead of the gui (avoids it being terminated when the shell session ends):
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;vboxmanage startvm WinDev2404Eval --type headless&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;On the client laptop install the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;remmina.org&#x2F;&quot;&gt;remmina rdp client&lt;&#x2F;a&gt; with &lt;code&gt;apt&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Connect to the vm in remmina with the ip6 address of the guest machine (&lt;em&gt;not&lt;&#x2F;em&gt; the host desktop)&lt;&#x2F;li&gt;
&lt;li&gt;Enter the windows user&#x27;s username &amp;amp; password when prompted&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;remote-management-tips&quot;&gt;Remote management tips&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s some more useful commands for managing the server machine remotely over ssh:&lt;&#x2F;p&gt;
&lt;p&gt;List virtual machines (useful for getting the name):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;vboxmanage&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; list&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; vms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Start a virtual machines&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;vboxmanage&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; startvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; WinDev2404Eval&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; headless&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Shut down the host&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; shutdown&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;h&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; now&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;explainshell.com&#x2F;explain?cmd=shutdown+-h+now&quot;&gt;https:&#x2F;&#x2F;explainshell.com&#x2F;explain?cmd=shutdown+-h+now&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;Suspend the host:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;systemctl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; suspend&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(ref &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;1792&#x2F;how-can-i-suspend-hibernate-from-command-line&#x2F;1795#1795&quot;&gt;https:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;1792&#x2F;how-can-i-suspend-hibernate-from-command-line&#x2F;1795#1795&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;was-it-worth-it&quot;&gt;Was it worth it?&lt;&#x2F;h2&gt;
&lt;p&gt;Build time of a gnarly project on laptop:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========== Rebuild completed at 02:44 and took 20:08.230 minutes ==========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the same vm running the same full rebuild remoted into the new desktop:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========== Rebuild completed at 02:28 and took 04:15.142 minutes ==========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can even copy paste text like this straight out of the RDP&#x27;d VM which will be immensely useful.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-end&quot;&gt;The end&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s all for this one. An obscure technical thing, that was useful to me, and just tricky enough to be worth documenting for future-me and the rest of the interwebs in case anyone finds it useful. Hurrah for blogs and zero cost of replication.&lt;&#x2F;p&gt;
&lt;p&gt;Till next time. 👋&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Trunk based (mainline) development is (mostly) wrong</title>
        <published>2024-04-18T00:00:00+00:00</published>
        <updated>2024-04-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/04/18/trunk-based-development-is-wrong/"/>
        <id>https://0x5.uk/2024/04/18/trunk-based-development-is-wrong/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/04/18/trunk-based-development-is-wrong/">&lt;h2 id=&quot;mainlining&quot;&gt;Mainlining&lt;&#x2F;h2&gt;
&lt;p&gt;Some very experienced developers, some of whom I&#x27;ve heard it from in-person, strongly advocate what is often called &quot;mainline&quot; or &quot;trunk-based&quot; development, meaning that the git history is a series of commits directly to the main branch, with no pull requests, feature branches or merge commits in sight. This is often held up as the panacea for achieving fast, high-quality delivery.&lt;&#x2F;p&gt;
&lt;p&gt;Note that there is a bit of a terminology problem, and I am not talking about what is described at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;trunkbaseddevelopment.com&#x2F;&quot;&gt;trunkbaseddevelopment.com&lt;&#x2F;a&gt; which I actually agree with and think is excellent.&lt;&#x2F;p&gt;
&lt;p&gt;The absolute rule I&#x27;ve heard touted more than once of &quot;no merge commits on main&quot; (aka straight-line history), sometimes enforced by github configuration, is absolute balderdash. This assertion is typical of the black-and-white presentations of topics that seem oh-so-appealing when presented in the conference talk circuit where there is no room for nuance and actual trade-offs made in the trenches, and where big extreme statements win the game of attention.&lt;&#x2F;p&gt;
&lt;p&gt;There is a place for thoughtful, individual mainline commits, so don&#x27;t take this as saying the opposite extreme of &quot;only merge commits &#x2F; PRs on main&quot;. A small-to-medium internally consistent patch (say 1 to 200 lines of diff at most), can be quite a reasonable thing to just push to main.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;does-pairing-remove-the-need-for-prs&quot;&gt;Does pairing remove the need for PRs?&lt;&#x2F;h2&gt;
&lt;p&gt;For anything more than trivial changes in your production code and test code you probably want two pairs of eyes on it, and pairing is a great way to achieve that in real-time. But does pairing remove the need for a PR entirely? Some say yes, but I say it depends on the actual patch ...&lt;&#x2F;p&gt;
&lt;p&gt;The question of pairing and the question of &quot;mainline vs pull request&quot; are almost entirely orthogonal. Pairing fixes the async-review problem, and certainly reduces the need for PRs to achieve peer-review, but that doesn&#x27;t mean we should reflexively throw out feature branches, merge commits and PRs with the proverbial bath water.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-branches-and-merge-commits-matter&quot;&gt;Why branches and merge-commits matter&lt;&#x2F;h2&gt;
&lt;p&gt;Unconditionally mainlining everything loses some important capabilities:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The ability to group a series of related commits (e.g. reformat, refactor, add feature), into one coherent group by way of merging them to main in one hit. (With or without github and its PRs.) A future reader can use this to look at history at two levels of detail - using &lt;code&gt;git log --first-parent&lt;&#x2F;code&gt; to look first at the merges and commits to main, and then &lt;em&gt;only if it&#x27;s interesting&lt;&#x2F;em&gt; look at the series of patches in a feature branch that was merged in. And conversely it allows breaking down a patch that needs to go into main in one hit (to avoid breaking things by shipping half-finished work) into a series of easier to understand patches with meaningful commit messages.&lt;&#x2F;li&gt;
&lt;li&gt;The ability to check your changes with CI in github before merging to main to be sure you don&#x27;t break main for everyone else (plus the permanent record of another &quot;Fix main build, oopsie&quot; commit).&lt;&#x2F;li&gt;
&lt;li&gt;The ability to offload regression checks to github actions instead of having to always run all the tests locally.&lt;&#x2F;li&gt;
&lt;li&gt;The ability to create a series of commits, discover they are wrong several hours later, and throw them out or rewrite them before they ever hit main.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you think mainlining generates a clean history, how often have you made a series of commits before realising that the shape of code isn&#x27;t right and now you have another series of commits to get it into a different shape. With mainline development that completely irrelevant first attempt is now in history to confuse future readers for ever more. With branch based development you can throw it out and pretend it never happened.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-to-mainline-branch-or-pr&quot;&gt;When to mainline, branch or PR&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s a bit of an art, so here&#x27;s some rules of thumb to guide you through the mainline &#x2F; branch &#x2F; PR decisions as you write code:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Pair on everything you can, eliminating the need for a PR for peer-review. Only peel off to solo work when it&#x27;s painfully obvious that there&#x27;s zero value &#x2F; knowledge-transfer &#x2F; alignment to be gained by pairing (e.g. library upgrades).&lt;&#x2F;li&gt;
&lt;li&gt;Trivial, uncontroversial changes can be mainlined solo (if your org allows any solo pushes to main), especially if you run the tests locally before pushing. Watch out for linters and formatters in CI. Pre-commit &#x2F; pre-push checks can help you avoid breaking the build with silly mistakes.&lt;&#x2F;li&gt;
&lt;li&gt;Slightly bigger changes can be pushed directly to main if you are pairing, but they should still be restricted to smaller, simple to understand patches; not entire large features.&lt;&#x2F;li&gt;
&lt;li&gt;When working on a larger feature, try and peel off as many unrelated pieces as you can and mainline or PR them separately as you go instead of lumping them in to your feature patch&#x2F;branch, rebasing your feature patch&#x2F;branch onto the updated main.&lt;&#x2F;li&gt;
&lt;li&gt;If a piece of work requires a few logically coherent steps to make the change, that are related or build on each other, then group them together in a feature branch. If you are pairing then you can run your tests &amp;amp; lint locally, create a merge commit on main that merges your branch in, and push that to main. No PR needed as it&#x27;s already been reviewed.&lt;&#x2F;li&gt;
&lt;li&gt;You may opt to open a PR in any of the above circumstances anyway in order to:
&lt;ol&gt;
&lt;li&gt;Get a run of CI&lt;&#x2F;li&gt;
&lt;li&gt;Get some async input from the broader dev team or across team boundaries.&lt;&#x2F;li&gt;
&lt;li&gt;To put a novel idea&#x2F;technique into public and give it time to be considered by yourself and others. The draft PR feature of github can be useful for this. Also useful for &quot;spikes&quot; (experiments in code to learn something or try something out that aren&#x27;t necessarily production quality or ready to merge).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Beware of long running branches with many commits, even if they are lots of well crafted commits. It&#x27;s a sign your deliverable increment is too large (at feature branch and&#x2F;or story level), and you should look to take a step back and break it down into smaller increments; maybe even ditching the branch and starting again from main.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that you need to be constantly considering these rules of thumb as you make every change to the code because in the fluid development flow it&#x27;s normal to range across all sorts of types of changes in one coding session (e.g. cleanup, refactoring, bug fixes, feature changes, quality improvements, ci fixes, editor config changes, massive file&#x2F;folder renames, and the actual features, etc etc), and each of these might require a separate approach to generating a high-quality history.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;split-up-commits-before-you-write-more-code&quot;&gt;Split up commits &lt;em&gt;before&lt;&#x2F;em&gt; you write more code&lt;&#x2F;h2&gt;
&lt;p&gt;Flipping to main and making a separate commit when you realise you want&#x2F;need a change that is unrelated to your feature branch is a great habit&#x2F;skill to build. It does however take discipline and practice.&lt;&#x2F;p&gt;
&lt;p&gt;I see many developers who default to branch-based development and just pile any old thing they need into their current branch, ending up with mammoth PRs that change far too much in one go. They often then complain that splitting it back up is too hard so they should just squash it. As the old saying goes &quot;if I wanted to get to there I wouldn&#x27;t have started from here&quot;; it&#x27;s far better to split into commits as you go rather than struggling with git&#x27;s tricky-but-powerful &lt;code&gt;git rebase --interactive&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve had devs say to me that &quot;it&#x27;s not worth the time&quot; to create a series of atomic coherent and well described commits. And for evidence they often point to their massive commit that does too many things, or their pile of incoherent &quot;wip&quot; commits to a branch, combined with the effort it takes to split and recombine commits into something better. In commercial projects I often relent because at that point the horse has bolted, and they are right that it isn&#x27;t worth spending that much client&#x2F;employer time rescuing their history aside from the opportunity to demonstrate rebase-interactive to them. (Besides, it&#x27;s their name on that commit forever, not mine). That doesn&#x27;t however make it good enough, or the correct conclusion. The correct answer is that you should work on getting the series of patches right as you go, and the cost of interactive rebases largely goes away.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;feature-flags-do-not-replace-feature-branches&quot;&gt;Feature flags DO NOT replace feature branches&lt;&#x2F;h2&gt;
&lt;p&gt;Some claim that feature flags (the ability to toggle capabilities on and off at runtime) are the reason you no longer need branches.&lt;&#x2F;p&gt;
&lt;p&gt;To be sure, they are a useful thing, and an answer to long-lived feature branches that can&#x27;t be merged because the feature isn&#x27;t ready to ship yet.&lt;&#x2F;p&gt;
&lt;p&gt;But just because you know how to use feature flags, still doesn&#x27;t mean you should throw out the richness and tools available to you with merge commits to main and PRs. The fact that some teams have painted themselves into a corner of PR-hell doesn&#x27;t mean you should throw out PRs entirely. You can have feature flags &lt;em&gt;and&lt;&#x2F;em&gt; the option to use branches, merge commits and PRs when it is the right tool for the job.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-no-one-cares-about-the-history&quot;&gt;&quot;But no-one cares about the history&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;Someone said this to me today. They aren&#x27;t the first person to say it to me either. This is empirically wrong. A friend of mine calls people with this mindset pejoratively &quot;BSBITS devs - Big Save Button In The Sky Developers&quot; meaning that they think that the only thing that matters is the current production code, and that source control is a fancy save&#x2F;share system.&lt;&#x2F;p&gt;
&lt;p&gt;Here are some of the ways that I have seen first-hand many many developers including myself &quot;care&quot; about history:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Understanding why the current code is how it is in order to know how&#x2F;whether to change it.&lt;&#x2F;li&gt;
&lt;li&gt;Understanding the changes another developer made in order to replicate those changes in a different microservice in a different team.&lt;&#x2F;li&gt;
&lt;li&gt;Reviewing a large PR with 1000+ lines of code changed, where some of it is refactoring and reformatting and some is functional changes - looking at the commits of the PR&#x2F;branch allows you to see the intended functional change (sometimes just a few lines) separately from large rote refactors etc.&lt;&#x2F;li&gt;
&lt;li&gt;To judge the capabilities and productivity of a developer with a view to hiring&#x2F;firing. Yes this actually happens, I&#x27;ve seen it. And guess what, that developer doesn&#x27;t get to explain their poor quality history, &lt;strong&gt;and they can be judged harshly for it&lt;&#x2F;strong&gt;. Are you really sure no-one cares?&lt;&#x2F;li&gt;
&lt;li&gt;To get a feel for the capabilities of a co-worker.&lt;&#x2F;li&gt;
&lt;li&gt;To keep up to date with changes to a project that you are either involved in directly or indirectly, perhaps a repo belonging to another team.&lt;&#x2F;li&gt;
&lt;li&gt;Principle developers that operate cross-team looking for best&#x2F;worst practices that they need to take action on. (They often have significant HR influence, do you want them judging your poor history badly because &quot;no-one cares&quot;?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ironically I&#x27;ve even seen some of the people who&#x27;ve said to me &quot;no-one cares about history&quot; then go on at a later date to look at the git history in order to figure something out while I&#x27;m on a screenshare with them. It&#x27;s all I can do not to point out the hypocrisy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;build-that-habit&quot;&gt;Build that habit&lt;&#x2F;h2&gt;
&lt;p&gt;In the end, a lot of the arguments I see come from people who haven&#x27;t mastered the skill of creating high-quality history with commits, branches and thoughtful merges.&lt;&#x2F;p&gt;
&lt;p&gt;The answer in my eyes is not to declare half of the tooling we have off-limits, and to claim that the generated history is unimportant, it is instead to get really good at creating good history as you go so that it become effortless.&lt;&#x2F;p&gt;
&lt;p&gt;Treat generation of history just like generation of code. It&#x27;s the most visible and permanent record of what you do as a developer of software, and you should treat it with the same pride and diligence as you do the code that runs in production.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fin&quot;&gt;Fin&lt;&#x2F;h2&gt;
&lt;p&gt;Coding is not just computers running things, it&#x27;s inter-person communications. Quality history, and the richness that branches and merges give us is part of that tapestry of communication with persons past, present and future.&lt;&#x2F;p&gt;
&lt;p&gt;Become good at it and the objections melt away.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;For a balanced view of PRs and related topics have a read of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;christopher-bimson.github.io&#x2F;2024&#x2F;07&#x2F;pull-request-theatre&#x2F;&quot;&gt;&quot;Pull Request Theatre&quot; by Chris Bimson&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why do automated tests matter?</title>
        <published>2024-03-27T00:00:00+00:00</published>
        <updated>2024-03-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/03/27/why-do-automated-tests-matter/"/>
        <id>https://0x5.uk/2024/03/27/why-do-automated-tests-matter/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/03/27/why-do-automated-tests-matter/">&lt;p&gt;It might seem a bit odd to write a post on software tests after so many years and so much content, yet to this day I see well meaning developers writing software without adequate test coverage. In fact I will share that I myself have been &lt;em&gt;very&lt;&#x2F;em&gt; late to enlightenment on this front. Sure I&#x27;ve been &quot;writing tests&quot; for well over a decade, but I was missing the mental framework that would make those efforts coherent, complete and effective.&lt;&#x2F;p&gt;
&lt;p&gt;In my view the mental model of why we would write tests is more important than the detailed &quot;how&quot; of writing unit&#x2F;integration tests, because without that it can only be at best haphazard whether the testing really serves its true purpose.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll share with you here the keystone ideas that make it all sit together properly, just like the keystone in a stone archway. Then from there, all the tests you write will sit in their true and proper place within that framework, or be obviously either waste or missing.&lt;&#x2F;p&gt;
&lt;p&gt;👉 🎙️ This topic is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pod.timwise.co.uk&#x2F;25&quot;&gt;also covered on my podcast&lt;&#x2F;a&gt; 🎙️&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;archway_IMG_20231109_135436.jpg&quot; alt=&quot;Photo: the shard through a brick archway&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yes I&#x27;m aware this particular archway in the photo doesn&#x27;t actually have a keystone, but I took the pic and I rather like it so it&#x27;s staying.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-before-time-tdd-unit-testing&quot;&gt;The Before Time: TDD &amp;amp; Unit Testing&lt;&#x2F;h2&gt;
&lt;p&gt;I started my career in software development way back in 2000 when only a few very forward thinking people were doing high quality automated testing, and it really hadn&#x27;t reached the broader consciousness off the software development community.&lt;&#x2F;p&gt;
&lt;p&gt;Like a large number of software devs of that era, I became aware of &quot;software testing&quot; through the &quot;TDD&quot; movement (test-driven development). I believe a lot of the noise about this came out of the Ruby on Rails community (no coincidence, there&#x27;s no compile step so there&#x27;s more reliance on good tests in ruby&#x2F;rails than in compiled languages). My experience of this was that it was largely talked about and taught as a bottom-up approach to testing:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&quot;Here&#x27;s how you write a unit test for a class.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Here&#x27;s how you do assertions.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Here&#x27;s why you should write the test before the code (red-green-refactor).&quot;&lt;&#x2F;li&gt;
&lt;li&gt;And in C# land &quot;here&#x27;s how you do dependency injection&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This is all good and important to know but is not enough in itself.&lt;&#x2F;p&gt;
&lt;p&gt;This was also a time when SOLID was big in the OO consciousness, so classes, isolation, encapsulation and all the small pieces of the machine you were building was the focus, and testing those pieces was often enough to claim you were &quot;doing testing&quot;. Interviews often being more about &quot;do you TDD&quot; than &quot;will your system break for end users&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Integration Testing&quot; (i.e testing more than one piece together) was certainly in my awareness, but mostly as a TDD++, and was usually missing any kind of coherent &quot;why&quot;. You might test some code with a real database instead of a mocked persistence layer, or check that all your pure code classes didn&#x27;t blow up when they were wired back together. In C# world a lot of mental overhead was created by trying to work out how to test code that used Microsoft&#x27;s not very test-friendly .NET Framework standard library code.&lt;&#x2F;p&gt;
&lt;p&gt;So I bumbled along, more or less successfully writing tests for my software, but always feeling like I didn&#x27;t have a really solid argument for the big picture. For me it was mostly &quot;aim for 100% test coverage&quot; and you&#x27;ll catch&#x2F;prevent lots of bugs, plus it was good at driving software architecture in the minutia by preventing things being too coupled together.&lt;&#x2F;p&gt;
&lt;p&gt;More recently I&#x27;ve had the pleasure on working with people who are super-keen on &quot;outside-in&quot; testing and considerably less keen on acres of unit tests, and it finally dawned on me what I&#x27;ve been missing all these years. What follows is the missing piece:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-why-of-testing&quot;&gt;The &quot;Why&quot; of Testing&lt;&#x2F;h2&gt;
&lt;p&gt;So let&#x27;s take a step back for a moment. Why do we write tests at all, what is the big goal that makes this all worthwhile.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s long been discussions of the &quot;cost&#x2F;benefit&quot; of tests, and there is research that shows &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Test-driven_development#Benefits&quot;&gt;teams that write tests are more productive&lt;&#x2F;a&gt;, which is good, but a bit abstract when it comes to what we actually need to write to be effective.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;preventing-regressions&quot;&gt;Preventing Regressions&lt;&#x2F;h3&gt;
&lt;p&gt;The goal of writing any software is working software for users and businesses; and they aren&#x27;t going to be too happy when something that worked fine on Monday is now broken on Tuesday.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t think it&#x27;s news to anyone that the goal of software tests is to prevent regressions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;axioms&quot;&gt;Axioms&lt;&#x2F;h3&gt;
&lt;p&gt;There are two pieces of the testing puzzle that &quot;preventing regressions&quot; alone didn&#x27;t make immediately clear to me, and these are they key reasons I&#x27;m taking the time to write this post at all. They drive a subtle but foundational shift in what our writing of tests actually looks like and the magnitude of their effectiveness.&lt;&#x2F;p&gt;
&lt;p&gt;They may seem trivial and obvious at first sight, but do not ignore them so quickly as they are the axioms upon which the whole approach rests. They are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;What matters is not whether your class has &quot;tests&quot; but whether the software as perceived by the user does the job they need.&lt;&#x2F;li&gt;
&lt;li&gt;When you add your &lt;em&gt;first&lt;&#x2F;em&gt; feature it&#x27;s easy to manually verify it&#x27;s behaviour. When you write your &lt;em&gt;ninety-ninth&lt;&#x2F;em&gt; feature you still want to be &lt;em&gt;certain&lt;&#x2F;em&gt; that the other ninety-eight features are &lt;em&gt;all&lt;&#x2F;em&gt; still intact.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Most systems have many thousands of &quot;features&quot;, especially if you include &quot;non-functional&quot; cross-cutting requirements such as acceptable performance for each capability.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;full-automated-coverage&quot;&gt;Full, Automated Coverage&lt;&#x2F;h2&gt;
&lt;p&gt;Every time you touch your software, there is a non-zero risk that something that used to work will no longer work. Anyone who&#x27;s written software for any length of time will laugh at the idea that &quot;a change in component A has no possibility of breaking something unrelated in component B&quot;. And as a more rigorous colleague pointed out, we have problem of &quot;emergence&quot; in complex systems which makes it increasingly hard to predict behaviour. A good measure of your tests is how afraid you are of upgrading third-party dependencies, running you tests and immediately shipping the result without further manual verification.&lt;&#x2F;p&gt;
&lt;p&gt;The only sustainable solution to the presented axioms combined with the need to add more features over time is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Ensure &lt;em&gt;every&lt;&#x2F;em&gt; feature the user cares about has a test.&lt;&#x2F;li&gt;
&lt;li&gt;The software is tested from the perspective of the user.&lt;&#x2F;li&gt;
&lt;li&gt;The software is tested after every change.&lt;&#x2F;li&gt;
&lt;li&gt;This testing is fully automated.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;insufficient-test-automation&quot;&gt;Insufficient Test Automation&lt;&#x2F;h3&gt;
&lt;p&gt;If you write insufficient automated tests there are only two things that can happen, both bad:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;You spend exponentially more time manually verifying all expected behaviour before any change is passed on for the user to use; bugs get through anyway. Or&lt;&#x2F;li&gt;
&lt;li&gt;You give up trying to test what was supposed to work, and some of it stops working.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Full automated test coverage of &lt;em&gt;all&lt;&#x2F;em&gt; delivered features to date is the &lt;em&gt;only&lt;&#x2F;em&gt; solution to this problem. Any shortcoming in this coverage is a subclass of the generalized &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;charmconsulting.co.uk&#x2F;2020&#x2F;11&#x2F;27&#x2F;leaders-guide-to-technical-debt&#x2F;&quot;&gt;technical debt&lt;&#x2F;a&gt;&quot; problem that quickly results in a catastrophic drop-off of ability to delivery anything at all if it is allowed to grow:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;charmconsulting.co.uk&#x2F;2020&#x2F;11&#x2F;27&#x2F;leaders-guide-to-technical-debt&#x2F;&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;charmconsulting.co.uk&#x2F;assets&#x2F;blog&#x2F;graph-debt-vs-delivery.png&quot; alt=&quot;Graph delivery speed plummeting as tech debt piles up&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-kind-of-tests&quot;&gt;What Kind of Tests&lt;&#x2F;h2&gt;
&lt;p&gt;So, if you accept all of the above, what does that mean when you actually fire up your editor and wonder what test to write?&lt;&#x2F;p&gt;
&lt;p&gt;You already write unit tests, that&#x27;s enough, right? ... Bzzzzt, Wrong! That fails the &quot;from the user perspective&quot; need.&lt;&#x2F;p&gt;
&lt;p&gt;If the only thing that matters is that a feature works &lt;em&gt;from the users perspective&lt;&#x2F;em&gt; then the only automated test that matters is one that tests a feature from the users perspective. In practice that means things like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;End to end tests&lt;&#x2F;li&gt;
&lt;li&gt;Browser automation&lt;&#x2F;li&gt;
&lt;li&gt;Smoke tests&lt;&#x2F;li&gt;
&lt;li&gt;Platform tests&lt;&#x2F;li&gt;
&lt;li&gt;Performance tests&lt;&#x2F;li&gt;
&lt;li&gt;Outside-in tests&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And what doesn&#x27;t matter a hoot is things like unit tests, integration tests and component tests, i.e. the very things that we were taught in &quot;TDD school&quot;, and then left to figure out &quot;the real world&quot; on our own. (I&#x27;m not bitter, just wish I&#x27;d figured this out 20 years earlier).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pushing-tests-down-the-pyramid&quot;&gt;Pushing Tests Down the Pyramid&lt;&#x2F;h3&gt;
&lt;p&gt;In an ideal world these fully-integrated end-to-end tests of entire features from the user&#x27;s perspective would run instantly and reliably on the developer&#x27;s machine the moment the code was written to disk, and we could have vast numbers of them at no extra cost of effort or speed. Here in the real world as we know from bitter experience, the most valuable tests are also the most troublesome. They are the slowest, most fragile, most prone to flap, they have the most difficult dependencies to unpick, and are the most subject to the combinatorial explosion in numbers as soon as there&#x27;s a few possible code paths to take or inputs to handle.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore as a matter of pragmatism we are forced to push some of our testing down the testing pyramid towards component, integration and unit tests.&lt;&#x2F;p&gt;
&lt;p&gt;If we do not lose sight of the highest goal of software testing, then this practically turns out to be be fine, and we can continuously tune the balance between the layers.&lt;&#x2F;p&gt;
&lt;p&gt;If however we do lose sight, and retreat into the lower levels of testing because it&#x27;s hard or slow to create the necessary full system coverage, then we start to slide up the technical debt scale, and will pay the price sooner than we&#x27;d like.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;on-business-driven-development-bdd&quot;&gt;On Business Driven Development (BDD)&lt;&#x2F;h3&gt;
&lt;p&gt;This is one that went off the rails as a concept. I see so many teams entirely miss the point of this movement, which is conceptually a good thing, but: IT&#x27;S NOT ABOUT GHERKIN SYNTAX, AND IT&#x27;S NOT ABOUT BROWSER AUTOMATION. Teams constantly get the technology confused with the intent and cargo-cult their way to an unholy mess of low quality high volume waste.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s actually about writing down what the users expect of your software, in terms they&#x27;d understand, and making sure that those expectations are never broken unintentionally, which is actually a very good thing.&lt;&#x2F;p&gt;
&lt;p&gt;BDD ends up using gherkin and browser automation because gherkin allows plain English explanations that can be turned into executable tests, and users often interact with software via a browser these days.&lt;&#x2F;p&gt;
&lt;p&gt;Gherkin (specflow etc) and browser automation test frameworks are tools for achieving BDD, not the definition of BDD.&lt;&#x2F;p&gt;
&lt;p&gt;Sadly by its nature the gherkin tools end up requiring maintenance of &quot;step definitions&quot; which is a hard cost to bear unless you are very careful what you use it for.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;outside-in-testing&quot;&gt;Outside-In Testing&lt;&#x2F;h3&gt;
&lt;p&gt;Outside-In testing is a term and concept that I came across recently that really aligns with what I have laid out here. It emphasises what the user experiences (even if it&#x27;s an API user rather than a web user).&lt;&#x2F;p&gt;
&lt;p&gt;I think once the concepts in this blog post are internalised, then outside-in is a good shorthand for a good approach to achieving the regression testing goals that have been laid out in this post.&lt;&#x2F;p&gt;
&lt;p&gt;These are a couple of good posts on the concept:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thoughtbot.com&#x2F;blog&#x2F;testing-from-the-outsidein&quot;&gt;https:&#x2F;&#x2F;thoughtbot.com&#x2F;blog&#x2F;testing-from-the-outsidein&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.obeythetestinggoat.com&#x2F;book&#x2F;chapter_outside_in.html&quot;&gt;https:&#x2F;&#x2F;www.obeythetestinggoat.com&#x2F;book&#x2F;chapter_outside_in.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;mindset-and-culture&quot;&gt;Mindset and Culture&lt;&#x2F;h2&gt;
&lt;p&gt;In the end, whether the right sort of automated regression tests are written comes down to the core beliefs of your individual engineers writing the systems and the teams they operate in.&lt;&#x2F;p&gt;
&lt;p&gt;If there is &lt;em&gt;any&lt;&#x2F;em&gt; part of them then that isn&#x27;t 110% on-board with what I&#x27;ve written here, then test coverage ends up being haphazard and incomplete, and over time gets steadily less able to prevent regressions.&lt;&#x2F;p&gt;
&lt;p&gt;If there is not a full belief in the need for high quality automated testing then even a small friction in the way (e.g. a difficult 3rd party dependency, or the need for complex multi-team multi-service regression test), then teams will generally quietly give up on full feature coverage from the user&#x27;s perspective and satisfy themselves with unit or component level tests. Unhelpfully, to the untrained eye a large quantity of tests looks similar to &quot;good coverage&quot;, and its less obvious whether it actually tests anything users care about. We must be constantly vigilant for this as the message on this is still relatively weak in the industry, and often confused by the (valuable) talk of detailed test approaches.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hero-culture&quot;&gt;Hero culture&lt;&#x2F;h3&gt;
&lt;p&gt;If you are particularly unlucky, or have set up perverse incentives, you risk a harder problem to resolve which is the embedding of a self-perpetuating &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;scalablehuman.com&#x2F;2023&#x2F;10&#x2F;19&#x2F;the-dangers-of-hero-culture-in-development-teams&#x2F;&quot;&gt;hero culture&lt;&#x2F;a&gt;&quot; whereby engineers take the fastest path to delivering &lt;em&gt;percieved&lt;&#x2F;em&gt; value (whilst incurring significant technical debt and unseen bugs), and then take credit again by rushing to highly visibly fixing the problems that they themselves created.&lt;&#x2F;p&gt;
&lt;p&gt;Good regression coverage, like much good engineering, takes time to build in the short term for a payoff of peace, reliability and sustained velocity in the long term. Which is incompatible with hero-ing it.&lt;&#x2F;p&gt;
&lt;p&gt;Beware the &quot;rock star&quot; programmer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;programmer-excuses&quot;&gt;Programmer Excuses&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;i-don-t-have-time&quot;&gt;&quot;I don&#x27;t have time&quot;&lt;&#x2F;h4&gt;
&lt;p&gt;The client&#x2F;boss is paying for your time, and the boss&#x2F;client would like the long term benefits, mkay?&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-boss-client-manager-won-t-let-me&quot;&gt;&quot;The boss&#x2F;client&#x2F;manager won&#x27;t let me&quot;&lt;&#x2F;h4&gt;
&lt;p&gt;The &quot;should I do a good job&quot; question, as I like to call it.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Which is quicker? Do that one.&quot;&lt;br &#x2F;&gt;
~ Your client &#x2F; boss&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I often see all but the most experienced software engineers falling into the trap of confusing authority with expertise.&lt;&#x2F;p&gt;
&lt;p&gt;I often hear engineers complaining that &quot;they aren&#x27;t given the time&quot; to write tests, or do a proper job on some aspect of the software they are writing.&lt;&#x2F;p&gt;
&lt;p&gt;In reality what has always happened is the engineer has presented two options to a client&#x2F;employer who doesn&#x27;t know or care about how software is built:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;I can do this feature properly with all the tests and great architecture etc etc (client glazes over) it&#x27;ll be amazing, or&lt;&#x2F;li&gt;
&lt;li&gt;I can just do the feature without any of that proper stuff. Which one do you want?&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The client &#x2F; boss &#x2F; project manager responds [whilst thinking &quot;I have no idea what you are talking about, or why you are asking] &quot;Which is quicker? Do that one.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Then the engineer gets the hump that they can&#x27;t do a good job.&lt;&#x2F;p&gt;
&lt;p&gt;Or worse, the engineer assumed the answer for them without even asking.&lt;&#x2F;p&gt;
&lt;p&gt;Put it this way, if a plumber came to a house, should they ask the homeowner whether to earth the pipes, or should they just do it as part of the cost of the job. The homeowner might not understand why that&#x27;s part of the job, but they probably also don&#x27;t want to be electrocuted by the radiator.&lt;&#x2F;p&gt;
&lt;p&gt;It is perfectly reasonable for an experienced software engineer, who is the expert in &lt;em&gt;their&lt;&#x2F;em&gt; trade, to just include automated regression tests as part of the job of feature delivery. To &lt;strong&gt;not even bring it up in conversation&lt;&#x2F;strong&gt;. The client&#x2F;employer NEVER wants to pay for a feature, think its done, only to have it break again four features later. From their point of view, and quite rightly, that&#x27;s just shoddy software.&lt;&#x2F;p&gt;
&lt;p&gt;This is not to say I&#x27;m secretive - I work in the open and am open to people asking why things are done the way they they are, and am happy to explain to the client why it&#x27;s in their best interest. But whether it happens is not up for discussion.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hiring-a-qa-team-just-don-t&quot;&gt;Hiring a QA team - Just Don&#x27;t&lt;&#x2F;h2&gt;
&lt;p&gt;Some organisations seem to think the answer is to take the regression test problem off developer&#x27;s plates by hiring less skilled individuals to do this apparently mundane work. Some even hire SDETs to write automated tests for the developers.&lt;&#x2F;p&gt;
&lt;p&gt;This is a fundamentally flawed approach in the same way that hiring an Operations teams as a separate function was accepted as a bad idea and replaced with an integrated DevOps product team. (Well, apart from the anti-pattern of a &quot;DevOps&quot; role, but that&#x27;s another post).&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s flawed in at least the following ways:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;It embeds the &quot;manual testing is okay&quot; approach in the culture, but adds some extra brute force people-power in the hope that this will prevent the eventual arrival of the 99th-feature problem. (The number just gets bigger, it&#x27;s still there). This is pretty much like trying to outrun your own shadow.&lt;&#x2F;li&gt;
&lt;li&gt;It encourages developers to consider testing (automated or otherwise) &quot;that other team&#x2F;role&#x27;s problem&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;It adds significant delays and an additional silo between writing code and delivering value to users and getting valuable feedback. Lengthening feedback cycles. This goes against &lt;em&gt;everything&lt;&#x2F;em&gt; we have learned from toyota&#x2F;kanban&#x2F;lean etc.&lt;&#x2F;li&gt;
&lt;li&gt;QA people &lt;em&gt;cannot&lt;&#x2F;em&gt; actually improve &quot;quality&quot; - they are not the developers working on the actual code, and can at best catch the worst errors.&lt;&#x2F;li&gt;
&lt;li&gt;The people who could improve quality (developers who actually write the code) lose extremely important feedback signals on how their software behaves when tested and used.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I have also seen QAs used as a &quot;minimum quality gate&quot; that &quot;allows&quot; an organisation to hire an army of poor-to-mediocre programmers. Fairly quickly that goes spectacularly badly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;So the important take-away here is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Tests must test what your users actually care about.&lt;&#x2F;li&gt;
&lt;li&gt;Those tests must be automated to sustain your velocity.&lt;&#x2F;li&gt;
&lt;li&gt;The testing pyramid is good and valid.&lt;&#x2F;li&gt;
&lt;li&gt;Start from the outside with your testing and work in only as much as you must.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;And why we do it that way is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The features for users is more important than the internal workings.&lt;&#x2F;li&gt;
&lt;li&gt;Without full-automated coverage we cannot continue to confidently add features.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Templated repos with dotnet new</title>
        <published>2024-03-06T00:00:00+00:00</published>
        <updated>2024-03-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/03/06/templated-repos-with-dotnet-new/"/>
        <id>https://0x5.uk/2024/03/06/templated-repos-with-dotnet-new/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/03/06/templated-repos-with-dotnet-new/">&lt;p&gt;I&#x27;ve been digging in to making &lt;code&gt;dotnet new&lt;&#x2F;code&gt; templates and it turns out to be a remarkably capable bit of tooling.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s particularly useful when you want to build a load of similar microservices with their own git repos.&lt;&#x2F;p&gt;
&lt;p&gt;It can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Rename files.&lt;&#x2F;li&gt;
&lt;li&gt;Rename strings (variables, class names etc).&lt;&#x2F;li&gt;
&lt;li&gt;Preserve case style of renamed strings (through &quot;derived&quot; replacements).&lt;&#x2F;li&gt;
&lt;li&gt;Create named command line arguments for your template string replacements, e.g. &lt;code&gt;donet new mytemplate --myswitch MyReplacementValue&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Exclude entire blocks of code and files based on switches that user can provide.&lt;&#x2F;li&gt;
&lt;li&gt;Be installed an tested from a local folder with &lt;code&gt;dotnet new install &amp;lt;path&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Be built into a nuget package and published on private or public feeds.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Importantly, there&#x27;s nothing in the way that it works that stops you from making your template code build&#x2F;test&#x2F;run.&lt;&#x2F;p&gt;
&lt;p&gt;And because it&#x27;s a CLI tool, if you want to an update an existing generated repo with a new version of a template you can just run it again with &lt;code&gt;--force&lt;&#x2F;code&gt;, and use git to pick through what changes you want to take into the generated repo.&lt;&#x2F;p&gt;
&lt;p&gt;This really takes a lot of the toil out of the copy-paste-modify you would have to do otherwise.&lt;&#x2F;p&gt;
&lt;p&gt;Learn more:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;core&#x2F;tools&#x2F;custom-templates&quot;&gt;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;core&#x2F;tools&#x2F;custom-templates&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;dotnet&#x2F;how-to-create-your-own-templates-for-dotnet-new&#x2F;&quot;&gt;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;dotnet&#x2F;how-to-create-your-own-templates-for-dotnet-new&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;See also:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;copier.readthedocs.io&#x2F;&quot;&gt;https:&#x2F;&#x2F;copier.readthedocs.io&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New tool: sln-items-sync for Visual Studio solution folders</title>
        <published>2024-01-13T00:00:00+00:00</published>
        <updated>2024-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2024/01/13/new-tool-sln-items-sync-for-visual-studio-solution-folders/"/>
        <id>https://0x5.uk/2024/01/13/new-tool-sln-items-sync-for-visual-studio-solution-folders/</id>
        
        <content type="html" xml:base="https://0x5.uk/2024/01/13/new-tool-sln-items-sync-for-visual-studio-solution-folders/">&lt;p&gt;How and why I created &lt;code&gt;sln-items-sync&lt;&#x2F;code&gt;  - a &lt;code&gt;dotnet tool&lt;&#x2F;code&gt; to generate SolutionItems from filesystem folders.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to skip the backstory head over: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sln-items-sync&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sln-items-sync&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;15-years-of-minor-irritation&quot;&gt;15 years of minor irritation&lt;&#x2F;h2&gt;
&lt;p&gt;Faced with another set of microservice repos written in dotnet-core, with &lt;code&gt;.sln&lt;&#x2F;code&gt; files in various states of tidiness I found my self for the 1000th time in 15+ years manually pointy clicky adding fake solution-items folders and subfolders and then toiling away adding files &lt;strong&gt;just&lt;&#x2F;strong&gt; so I could search them, click them and view them from within Visual Studio or Rider.&lt;&#x2F;p&gt;
&lt;p&gt;There must be a better way by now I thought, so I went hunting.&lt;&#x2F;p&gt;
&lt;p&gt;All I turned up was a lot of people asking the same thing and some dead tooling from years ago. Here&#x27;s the stackoverflow from 2008 with 90k views and 180 upvotes: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;267200&#x2F;visual-studio-solutions-folder-as-real-folders&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;267200&#x2F;visual-studio-solutions-folder-as-real-folders&lt;&#x2F;a&gt;, which didn&#x27;t really help in spite of having 23 answers. Not to mention the slew of linked questions where people are asking the same thing with different words.&lt;&#x2F;p&gt;
&lt;p&gt;(Solution folders aren&#x27;t to be confused with adding files to a &lt;em&gt;project&lt;&#x2F;em&gt; which used to be an equal nightmare before Microsoft saw sense and just included &lt;em&gt;what&#x27;s on the filesystem&lt;&#x2F;em&gt;. There are many old stackoverflow questions on that too from frustrated devs around the world.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;sln-items.png&quot; alt=&quot;screenshot of example solution items folder in Rider&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So with the programmer war cry of &quot;how hard can it be, I&#x27;ll knock this out in a couple of evenings...&quot; I set about on what turned out to be a significant exercise in yak-shaving in order to sort it out myself once and for all.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;How hard can it be, I&#x27;ll knock this out in a couple of evenings...&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Me. Again.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;what-to-build&quot;&gt;What to build?&lt;&#x2F;h2&gt;
&lt;p&gt;I did briefly look at writing an IntelliJ (aka Rider) plugin but that turned out quickly to be a daunting thing so I put that idea down sharpish.&lt;&#x2F;p&gt;
&lt;p&gt;I use Rider in preference to Visual Studio and VSCode for C# so didn&#x27;t even look at that side. VSCode didn&#x27;t even bother with .sln files last I checked.&lt;&#x2F;p&gt;
&lt;p&gt;Next step was to write a CLI (command-line interface, aka terminal) tool to do it. (sln + filesystem in, mutated sln out, easy...)&lt;&#x2F;p&gt;
&lt;p&gt;I have recently written command line tools in both GoLang and Rust, but given this is a tool that would only be useful to Microsoft developers I figured I&#x27;d do this one in C#. I do actually like C# as a language for all my interest in other things, and thanks to dotnet-core and Rider I can actually write the whole thing on Linux Mint Cinnamon where I like to be.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;parsing-and-writing-sln-files&quot;&gt;Parsing and writing .sln files&lt;&#x2F;h2&gt;
&lt;p&gt;I then hunted around for any nuget packages that might do the grunt work of reading&#x2F;writing the sln format. Surely after 20-something years there must be something, right? Well, kinda. The VS parsing code is locked away in some windows dll nastyness, probably in C++ and COM or something evil. It even predates XML as a format, never mind JSON.&lt;&#x2F;p&gt;
&lt;p&gt;What I did find was the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;SlnParser&quot;&gt;SlnParser nuget package&lt;&#x2F;a&gt;, which someone had kindly written and open-sourced, and after quick test I could see it did a decent job of turning .sln files into an in-memory C# object model (a &lt;code&gt;Solution&lt;&#x2F;code&gt; class, with lists of things as properties).&lt;&#x2F;p&gt;
&lt;p&gt;So major yak number one was to fork SlnParser and turn it into a two-way tool. This I did with a lot of hackery and created &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;SlnEditor&#x2F;&quot;&gt;SlnEditor nuget package&lt;&#x2F;a&gt; which I published on nuget and github with the same Unlicense licensing as the original. Perhaps others will find this gift to the world useful in its own right.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creating-sln-items-sync&quot;&gt;Creating sln-items-sync&lt;&#x2F;h2&gt;
&lt;p&gt;Finally with that working I was able to create the CLI tool I wanted, which I named &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sln-items-sync&quot;&gt;sln-items-sync&lt;&#x2F;a&gt;. This was more work than I expected, but I got a first cut working reasonably quickly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tests&quot;&gt;Tests&lt;&#x2F;h2&gt;
&lt;p&gt;I put a good amount of effort into good end to end test coverage on both the parser and the tool itself because I am now a true believer that &lt;strong&gt;without tests&lt;&#x2F;strong&gt; you will be &lt;strong&gt;unable to make future changes and dependency upgrades with speed and confidence&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I.e. lack of tests is the epitome of technical debt.&lt;&#x2F;p&gt;
&lt;p&gt;In fact let me give that a block quote because it&#x27;s such an important point:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Lack of tests is the epitome of technical debt.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;(p.s. why is Epitome spelled that way but pronounced epitomy. English. Sigh.)&lt;&#x2F;p&gt;
&lt;p&gt;This has paid off in spades as the amount of work to get it satisfactorily &quot;done&quot; grew and grew the closer I got to finished.&lt;&#x2F;p&gt;
&lt;p&gt;The tests in both projects focus on &quot;outside-in&quot; testing rather than mockist unit testing. As such you can see at a glance the overall behaviour, spot any unexpected&#x2F;unwanted output, and easily write new tests for new desired behaviour, being able to eyeball them easily for correctness. I won&#x27;t include one here as they are a bit lengthy, but you can go and look at the source repos on github.&lt;&#x2F;p&gt;
&lt;p&gt;This is made a bit easier on this tool because the only interfaces to the world are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a text format (easy to string-compare expected versus actual)&lt;&#x2F;li&gt;
&lt;li&gt;a filesystem (I went for creating real file trees in tests which worked well and gives even more confidence)&lt;&#x2F;li&gt;
&lt;li&gt;the command line interface (for the sync tool)&lt;&#x2F;li&gt;
&lt;li&gt;the API (for the parser lib)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;first-contact-with-real-sln-files&quot;&gt;First contact with real .sln files&lt;&#x2F;h2&gt;
&lt;p&gt;As I am doing some work for a C# contracting client currently I was able to try it out on gnarly real solution files, with a view to submitting some small cleanup pull requests that could created really quickly.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;stable-ordering&quot;&gt;Stable ordering&lt;&#x2F;h3&gt;
&lt;p&gt;The first attempt was a complete failure because the generated patch re-wrote the entire sln file in a completely different order, resulting in a sea of red&#x2F;green lines full of GUIDs and other cryptic changes in the git diff. While the solution items were updated as intended and could be seen in Rider etc., this was not a patch that could be submitted to the team, or that I would put my name to.&lt;&#x2F;p&gt;
&lt;p&gt;Getting stable ordering between parsing and writing turned out to be a huge amount of work and refactoring, largely in the SlnEditor lib.&lt;&#x2F;p&gt;
&lt;p&gt;The key to making stable-ordering work was to add an &lt;code&gt;int sourceLine&lt;&#x2F;code&gt; property to almost everything when parsing, and to sort by that before rendering back out again. This had the desired effect of keeping everything in the original order no matter how it was mutated, and new items are added to the end (by replacing default &lt;code&gt;0&lt;&#x2F;code&gt; with &lt;code&gt;Int.MaxValue&lt;&#x2F;code&gt; before sorting).&lt;&#x2F;p&gt;
&lt;p&gt;Phew, another yak shaved, lost count now, but got more xmas hols so keep going....!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;many-bugs-and-gaps&quot;&gt;Many bugs and gaps&lt;&#x2F;h2&gt;
&lt;p&gt;It surprised me a bit just how many &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sln-items-sync&#x2F;issues?q=is%3Aissue+is%3Aclosed&quot;&gt;little niggles, edge cases, and small omissions&lt;&#x2F;a&gt; there were that had to be sorted out before I could use it to submit quality patches to client .sln files for real. Even the ever present byte-order-marker (BOM) was causing unwanted diffs because I hadn&#x27;t included it in the render, but .sln files seem to have them.&lt;&#x2F;p&gt;
&lt;p&gt;Pleasingly I&#x27;ve resolved everything I came across, apart from making the parent&#x2F;child guid mapping order stable which didn&#x27;t seem to be worth the effort seeing as they are completely incomprehensible anyway.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;making-a-dotnet-tool&quot;&gt;Making a dotnet-tool&lt;&#x2F;h2&gt;
&lt;p&gt;Once it was working, it was only a couple of rounds of building and copying the exe to &lt;code&gt;bin&#x2F;&lt;&#x2F;code&gt; before I got fed up with that approach to distribution.&lt;&#x2F;p&gt;
&lt;p&gt;Amazingly it turns out to be pretty simple to build and publish tools to the &lt;code&gt;dotnet tool&lt;&#x2F;code&gt; ecosystem, they are actually just slightly special nuget packages, and you only have to add a couple of properties to the &lt;code&gt;.csproj&lt;&#x2F;code&gt; file.&lt;&#x2F;p&gt;
&lt;p&gt;Making a dotnet-tool worked great, and is a great user experience for installing and running the tool. It even does updates for no extra effort!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;github-actions&quot;&gt;Github-actions&lt;&#x2F;h2&gt;
&lt;p&gt;To make both of these tools even easier to work on and maintain longer term, I wanted to have a good github action (aka CI) to build and run the tests.&lt;&#x2F;p&gt;
&lt;p&gt;Build and test is trivial, you can pretty much click the default workflow button for .net in an empty github actions page and it just works.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to also automate the nuget publishing of both from github-actions, as although I had a sh file to upload them from my machine that&#x27;s a faff and tends to stop working after a few machine rebuilds. Amazingly the author of SlnParser has taken an interest and provided a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sln-items-sync&#x2F;pull&#x2F;15&quot;&gt;PR that gave me a ready-made github-action to push to nuget&lt;&#x2F;a&gt; for every release tag! So that&#x27;s now in place, and to release a new version I can just &lt;code&gt;git tag v1.2.3 &amp;amp;&amp;amp; git push --tags&lt;&#x2F;code&gt; and github does the rest.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-end-i-need-a-lie-down&quot;&gt;The end, I need a lie down&lt;&#x2F;h2&gt;
&lt;p&gt;So after all that, I&#x27;m not sure it was all worth it, but it&#x27;s done and I&#x27;m justifying it as a holiday hobby project and a gift to the dotnet developers of the world. I will certainly enjoy it every time I find an out of sync &lt;code&gt;SolutionItems&lt;&#x2F;code&gt; folder in future and run my tool so that I can ship a patch for it in seconds flat. I also learned a few things and got kata-like practice on shipping quality things at speed.&lt;&#x2F;p&gt;
&lt;p&gt;So with that, Merry Xmas and a happy new 2024. May all your solution folders be tidy and complete.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New rust and ssbf podcast episodes</title>
        <published>2023-10-26T00:00:00+00:00</published>
        <updated>2023-10-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/10/26/new-rust-and-ssbf-podcast-episodes/"/>
        <id>https://0x5.uk/2023/10/26/new-rust-and-ssbf-podcast-episodes/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/10/26/new-rust-and-ssbf-podcast-episodes/">&lt;p&gt;Hello readers,&lt;&#x2F;p&gt;
&lt;p&gt;Two new podcast episodes recorded and published. 🎙️🎧&lt;&#x2F;p&gt;
&lt;p&gt;Listen and subscribe here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;s&#x2F;1fdbe313&quot;&gt;Software Should be Free - Episode 23 - &quot;Git merges, regression testing, hexagonal architecture blog-to-rss-to-email&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;s&#x2F;33eafe07&quot;&gt;The Rust Workshop Podcast - Episode 4 - &quot;Consulting, Web projects, Regression tests, TWIR, Rustacean Station, Meetups&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Just me on these ones. Hope you find some value in them, I always try to share some useful things along with thoughts and updates. If you like them then please do share with others.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m looking for possible guests so if you would like to be a guest or know someone I should have on then let me know.&lt;&#x2F;p&gt;
&lt;p&gt;Keep shipping! 🚢&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>git - what do &#x27;base&#x27; &#x27;local&#x27; &#x27;remote&#x27; mean?</title>
        <published>2023-10-20T00:00:00+00:00</published>
        <updated>2023-10-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/10/20/git---what-do-'base'-'local'-'remote'-mean/"/>
        <id>https://0x5.uk/2023/10/20/git---what-do-'base'-'local'-'remote'-mean/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/10/20/git---what-do-&apos;base&apos;-&apos;local&apos;-&apos;remote&apos;-mean/">&lt;p&gt;The terminology for 3-way git merge, rebase and cherry-pick conflict files is very confusing, particularly because they flip direction between rebase and merge.&lt;&#x2F;p&gt;
&lt;p&gt;When you run &lt;code&gt;git mergetool&lt;&#x2F;code&gt; it will spit out 4 files that look like this, and then pass them as arguments to your merge tool of choice:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ gs &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;## HEAD (no branch)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;UU src&#x2F;gitopolis.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;?? src&#x2F;gitopolis_BACKUP_1585963.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;?? src&#x2F;gitopolis_BASE_1585963.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;?? src&#x2F;gitopolis_LOCAL_1585963.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;?? src&#x2F;gitopolis_REMOTE_1585963.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In kdiff3 (by far the best 3-way merge algorithm out there) it looks like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;git-kdiff-3way-merge.png&quot; alt=&quot;kdiff 3-way merge screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;here-s-how-i-think-of-it&quot;&gt;Here&#x27;s how I think of it&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;merge&quot;&gt;Merge&lt;&#x2F;h3&gt;
&lt;p&gt;You are on the target branch (local), and the patches are coming from the branch you are merging in (remote), kinda like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git checkout local-branch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git merge remote-branch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;cherry-pick&quot;&gt;Cherry-pick&lt;&#x2F;h3&gt;
&lt;p&gt;Same direction as merge.&lt;&#x2F;p&gt;
&lt;p&gt;You are on the target branch (local), and the patch is coming from the commit you are cherry-picking (remote), kinda like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git checkout local-branch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git cherry-pick some-remote-commit-ref&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;rebase&quot;&gt;Rebase&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;Opposite&lt;&#x2F;em&gt; direction to merge.&lt;&#x2F;p&gt;
&lt;p&gt;You start on your own branch that you want to rebase, but...&lt;&#x2F;p&gt;
&lt;p&gt;When you start the rebase you end up temporarily while the rebase is running in &quot;detached HEAD&quot; on the branch you are rebasing onto (often &lt;code&gt;origin&#x2F;main&lt;&#x2F;code&gt;), so:
You are on the target branch (local), and commits to rebase are coming from the branch you are rebasing (remote), kinda like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git checkout your-remote-branch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git rebase target-local-branch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;terminology&quot;&gt;Terminology&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&quot;&lt;strong&gt;BASE&lt;&#x2F;strong&gt;&quot;: before anyone changed it (in all cases)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When &lt;strong&gt;merging&lt;&#x2F;strong&gt; (other branch coming to me):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LOCAL&lt;&#x2F;strong&gt;:  branch I&#x27;m on&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;REMOTE&lt;&#x2F;strong&gt;: branch I&#x27;m merging in&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When &lt;strong&gt;cherry-picking&lt;&#x2F;strong&gt; (other commit coming to me):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LOCAL&lt;&#x2F;strong&gt;:  branch I&#x27;m on&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;REMOTE&lt;&#x2F;strong&gt;: commit I&#x27;m merging in&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When &lt;strong&gt;rebasing&lt;&#x2F;strong&gt; (my own branch coming to me):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LOCAL&lt;&#x2F;strong&gt;:  branch I&#x27;m rebasing on to (checked out as detached head mid-rebase)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;REMOTE&lt;&#x2F;strong&gt;: my commits on branch I&#x27;m rebasing&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;refs&quot;&gt;Refs&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;20381677&#x2F;in-a-git-merge-conflict-what-are-the-backup-base-local-and-remote-files-that&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;20381677&#x2F;in-a-git-merge-conflict-what-are-the-backup-base-local-and-remote-files-that&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Use kdiff3 for merge conflict resolution</title>
        <published>2023-10-20T00:00:00+00:00</published>
        <updated>2023-10-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/10/20/use-kdiff3-for-merge-conflict-resolution/"/>
        <id>https://0x5.uk/2023/10/20/use-kdiff3-for-merge-conflict-resolution/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/10/20/use-kdiff3-for-merge-conflict-resolution/">&lt;p&gt;I agree with Dermon: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@damon.lundin&#x2F;you-should-be-using-3-way-merging-4824400bae7&quot;&gt;&quot;You should be doing 3-way merges&quot;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I also see most developers I work with (that&#x27;s a lot as a contractor over the years) don&#x27;t even know what a 3-way merge is, let alone have it correctly configured and are using it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-a-3-way-diff-it-s-not-what-you-think&quot;&gt;What is a 3-way diff (it&#x27;s not what you think)&lt;&#x2F;h2&gt;
&lt;p&gt;A 3-way merge is &lt;em&gt;&lt;strong&gt;not&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt; that 3-pane view you get in some diff viewers which has:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;yours&lt;&#x2F;li&gt;
&lt;li&gt;theirs&lt;&#x2F;li&gt;
&lt;li&gt;result&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;That&#x27;s a two way diff, we&#x27;re not counting the &lt;em&gt;output&lt;&#x2F;em&gt; here.&lt;&#x2F;p&gt;
&lt;p&gt;A proper 3-way diff is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;before anyone changed it (base)&lt;&#x2F;li&gt;
&lt;li&gt;yours&lt;&#x2F;li&gt;
&lt;li&gt;theirs&lt;&#x2F;li&gt;
&lt;li&gt;result&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;(still not counting the output)&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what a full 3-way diff looks like in kdiff:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;images&#x2F;blog&#x2F;git-kdiff-3way-merge.png&quot;&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;git-kdiff-3way-merge.png&quot; alt=&quot;kdiff 3-way merge screenshot&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For proper terminology see &lt;a href=&quot;&#x2F;2023&#x2F;10&#x2F;20&#x2F;git-what-do-&amp;#x27;base&amp;#x27;-&amp;#x27;local&amp;#x27;-&amp;#x27;remote&amp;#x27;-mean&#x2F;&quot;&gt;git - what do &#x27;base&#x27; &#x27;local&#x27; &#x27;remote&#x27; mean?&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-as-a-developer-you-must-set-up-3-way-diffs&quot;&gt;Why as a developer you MUST set up 3-way diffs&lt;&#x2F;h2&gt;
&lt;p&gt;&quot;Who cares&quot;, you say. In fact I&#x27;ve heard devs say it.&lt;&#x2F;p&gt;
&lt;p&gt;And those devs that say this, I then see doing two things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Manually trawling through conflicts that kdiff could resolve correctly instantly&lt;&#x2F;li&gt;
&lt;li&gt;Actually getting merges wrong because they chose the wrong things &lt;em&gt;when the tool could algorithmically get it right&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you think about it, given only the information of &quot;more lines this side than that&quot;, how can you know whether they were added in one or removed in the other? You have to rely on additional context (such as a hunch for what the other devs might be up to). But if you add the missing 3rd piece of information, which git already has, &quot;what did it look like before anyone changed it&quot; (aka &quot;base&quot;), then you and the algorithm can both nail it.&lt;&#x2F;p&gt;
&lt;p&gt;With the full 3-way merge all you are left with is genuine conflicts to deal with (they changed the same line as you, damnnnn).&lt;&#x2F;p&gt;
&lt;p&gt;You even find kdiff immediately exit because it has a &quot;better&quot; merge algorithm than git (or at least less conservative), allowing it to instantly resolve many conflicts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-use-kdiff3-and-not-tool-of-choice&quot;&gt;Why use kdiff3 and not [tool of choice]&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;killer-algorithm&quot;&gt;Killer algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve (repeatedly) looked for better tools than kdiff3. It has a 20 year old not entirely intuitive user interface. But it has one &lt;em&gt;killer&lt;&#x2F;em&gt; feature: it has by far the best merge conflict resolution algorithm out there.&lt;&#x2F;p&gt;
&lt;p&gt;If someone could create a merge tool that can do merges like kdiff3 but with nicer UX and I&#x27;d jump (well, and open source of course), but nothing holds a candle to this algorithm.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;open-source&quot;&gt;Open source&lt;&#x2F;h3&gt;
&lt;p&gt;You have 3 choices:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Commercial software&lt;&#x2F;li&gt;
&lt;li&gt;Freeware&lt;&#x2F;li&gt;
&lt;li&gt;Open source&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I will always prefer open source by default because it just tends to stick around and not change all the time on you. KDiff3 is an excellent example of this, it does a job well, and is still available and basically unchanged in 20 years. Freeware cannot be taken over by a new maintainer, and has no funding so in the end is often short lived. Commercial software often doesn&#x27;t last, or is changed to something you didn&#x27;t want in the end. There are few companies that have provided stable software over 5+ years.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hidden-features&quot;&gt;Hidden features&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s really not that easy to use, but learn how to use the following and you can get very quick and accurate:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;keyboard shortcuts for jumping around conflicts and choosing which side to pick&lt;&#x2F;li&gt;
&lt;li&gt;configure &quot;escape&quot; key to exit (under integrations for some reason)&lt;&#x2F;li&gt;
&lt;li&gt;manual diff alignment - select a line, hit ctrl-y, repeat for other diffs (zero ui feedback), when you do the second and third you&#x27;ll see the diff jump, and often immediately figure out a conflict it hadn&#x27;t understood before&lt;&#x2F;li&gt;
&lt;li&gt;character-level diff highlighting (highlights bits of a line that are different)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;missing-features&quot;&gt;Missing features&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Good UX&lt;&#x2F;li&gt;
&lt;li&gt;Syntax highlighting&lt;&#x2F;li&gt;
&lt;li&gt;Native chrome (i.e. look like an app from your operating system)&lt;&#x2F;li&gt;
&lt;li&gt;Good UX&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;you-re-doing-it-wrong&quot;&gt;You&#x27;re doing it wrong&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;If you &lt;em&gt;ever&lt;&#x2F;em&gt; edit those &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;  &amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;&#x2F;code&gt; conflict markers you are just editing git&#x27;s non-attempt at merging the files. You&#x27;re doing it wrong, get a real tool (kdiff).&lt;&#x2F;li&gt;
&lt;li&gt;If you use your IDE&#x27;s built in merge conflict tooling, they are universally only 2-way at best, and not very good at that. You&#x27;re doing it wrong, get a real tool and learn to use it (kdiff).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;configuring-kdiff3&quot;&gt;Configuring kdiff3&lt;&#x2F;h2&gt;
&lt;p&gt;One from the archives - &lt;a href=&quot;&#x2F;2010&#x2F;09&#x2F;03&#x2F;configuring-kdiff3-as-mergetool-in&#x2F;&quot;&gt;configuring kdiff3 as a mergetool&lt;&#x2F;a&gt; - I still have to do this occasionally on windows, though git has better defaults now so might just work if you pick kdiff3 as a difftool without the detailed config.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-other-tools&quot;&gt;Finding other tools&lt;&#x2F;h2&gt;
&lt;p&gt;There aren&#x27;t any open source tools as good as kdiff. I wish they were.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;alternativeto.net&#x2F;feature&#x2F;3-way-merge&#x2F;&quot;&gt;https:&#x2F;&#x2F;alternativeto.net&#x2F;feature&#x2F;3-way-merge&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Prove me wrong and I&#x27;ll either thank you or find you a harder conflict to solve.&lt;&#x2F;p&gt;
&lt;p&gt;If you don&#x27;t mind paying for a commercial tool, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.scootersoftware.com&#x2F;&quot;&gt;Beyond Compare&lt;&#x2F;a&gt; is actually even better at 3-way merges than kdiff, and has a marginally better UI. It&#x27;s been around a long time.&lt;&#x2F;p&gt;
&lt;p&gt;Other tools that have 3-way merge capabilities to look at are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.perforce.com&#x2F;products&#x2F;helix-core-apps&#x2F;merge-diff-tool-p4merge&quot;&gt;Perforce&#x27;s p4merge&lt;&#x2F;a&gt; (Proprietary freeware)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.araxis.com&#x2F;merge&#x2F;index.en&quot;&gt;Araxis merge&lt;&#x2F;a&gt; (Paid)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;dangerous-hidden-changes&quot;&gt;Dangerous hidden changes&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s also worth noting that merge commits are the &lt;em&gt;least&lt;&#x2F;em&gt; well reviewed commits. I think a lot of devs don&#x27;t even realise that they can contain anything you like, not just what was in the two source branches. Combine that with bad tooling and it&#x27;s a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20140225140816&#x2F;https:&#x2F;&#x2F;nakedsecurity.sophos.com&#x2F;2014&#x2F;02&#x2F;24&#x2F;anatomy-of-a-goto-fail-apples-ssl-bug-explained-plus-an-unofficial-patch&#x2F;&quot;&gt;recipe for disaster&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What is Hexagonal Architecture, aka &quot;Ports and Adapters&quot;</title>
        <published>2023-09-28T00:00:00+00:00</published>
        <updated>2023-09-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/09/28/what-is-hexagonal-architecture/"/>
        <id>https://0x5.uk/2023/09/28/what-is-hexagonal-architecture/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/09/28/what-is-hexagonal-architecture/">&lt;h2 id=&quot;hexagonal-architecture-uh-what&quot;&gt;Hexagonal Architecture? Uh... what?&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;d largely ignored hexagonal architecture thus far in my career. I&#x27;d heard of it at some point. Read a bit about it and not really grokked it. I talked to some people and got the impression it wasn&#x27;t that good&#x2F;relevant&#x2F;useful and as such never looked much closer. From my brief skim of the material out there I hadn&#x27;t bridged the gap between the vague concepts outlined and the realities of applying such a pattern. Given the reaction of others I&#x27;d left it at that.&lt;&#x2F;p&gt;
&lt;p&gt;After reading and watching everything I could find on the subject it &lt;em&gt;still&lt;&#x2F;em&gt; seemed like a pointless abstraction to me that encourages over-engineering. Good design and isolating dependencies are something that any decent programmer would &quot;just do&quot; by using interfaces in C# or some equivalent in other languages. It is also normal in my experience of high-performing engineering teams that business needs and testing would drive out the right &quot;shape&quot; for these interfaces&#x2F;abstractions over time without needing someone to say &quot;let&#x27;s use hexagonal architecture&quot; and seeing who understands the shibboleth or at least pretends to.&lt;&#x2F;p&gt;
&lt;p&gt;If like me you haven&#x27;t grokked this odd-ball &quot;pattern&quot; then hopefully this post will help you. I put this post together having consumed absolutely everything I could find on the subject, discussed it with friends and generally having spent a lot of time mystified. Perhaps I can explain the common understanding of the pattern amongst those who like it and use it in a way that the pre-existing material failed to do for me. I&#x27;m still not 100% convinced by this &quot;pattern&quot;, but at least I feel like I understand the intent now.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-rude-awakening&quot;&gt;A rude awakening&lt;&#x2F;h3&gt;
&lt;p&gt;Then the other day I bumped into hexagonal architecture &lt;em&gt;HARD&lt;&#x2F;em&gt; in an initial meeting with a potential consulting client, which went something like this:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Client&lt;&#x2F;em&gt;: &quot;Tell me about hexagonal architecture.&quot;&lt;br &#x2F;&gt;
&lt;em&gt;Me&lt;&#x2F;em&gt;: &quot;Uh, I&#x27;ve heard of it but don&#x27;t know that much about it... I heard it&#x27;s mostly rubbish.&quot;&lt;br &#x2F;&gt;
&lt;em&gt;Client&lt;&#x2F;em&gt;: &quot;We use it here, you are the weakest link, goodbye. [&lt;em&gt;Click!&lt;&#x2F;em&gt;]&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Not particularly being a fan of this kind of interaction I went on a mission to &lt;em&gt;really&lt;&#x2F;em&gt; understand what the hell it is.&lt;&#x2F;p&gt;
&lt;p&gt;Having discovered that the view of hexagonal being largely pointless was not actually universal amongst programmers, but still skeptical, I &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;feed&#x2F;update&#x2F;urn:li:activity:7083072166547595264&#x2F;&quot;&gt;posted my disdain on LinkedIn&lt;&#x2F;a&gt;.
A key point that I picked up from these discussions is that &lt;em&gt;the pattern is more generalized than &quot;interfaces in C#&quot;&lt;&#x2F;em&gt; (or Java), it&#x27;s seen as a &lt;em&gt;generic&lt;&#x2F;em&gt; pattern with the intent of isolating one or more pieces of pure code from the messy world around it in all directions. It can be used as a mental model regardless of the technology choices in place and the layer of technology under discussion.&lt;&#x2F;p&gt;
&lt;p&gt;For example you can use the terminology to describe a piece of pure Ruby, C#, Rust, PHP etc. being isolated from UI and network concerns and independently testable, or you can can describe a microservice being isolated from other microservices with http and&#x2F;or messaging boundaries (or so I&#x27;m led to believe, reach out if you know different). The discussion on LinkedIn and further questioning of other devs made it clear I still had a bit of an understanding gap; this prompted me to dig further. Clearly enough developers out there believe this is a valid and useful pattern, rightly or wrongly.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll now attempt to save you the same journey of pain, confusion and archaeology that it took me to get to my current understanding. I&#x27;ll then present my opinions on the strengths and weaknesses of this so-called pattern.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hexagonal-architecture-explained&quot;&gt;Hexagonal Architecture Explained&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s my take on what &quot;hexagonal architecture&quot; means in 2023 to developers who wish to have a shared understanding and easy communication of this &quot;pattern&quot;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;history&quot;&gt;History&lt;&#x2F;h3&gt;
&lt;p&gt;The term &quot;hexagonal architecture&quot; was apparently coined by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;alistaircockburn&#x2F;&quot;&gt;Alistair Cockburn&lt;&#x2F;a&gt; (pronounced &quot;co-burn&quot;) circa 2005, and was made popular by his article of the same name, which you can still find at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;alistair.cockburn.us&#x2F;hexagonal-architecture&#x2F;&quot;&gt;https:&#x2F;&#x2F;alistair.cockburn.us&#x2F;hexagonal-architecture&#x2F;&lt;&#x2F;a&gt;. It may originally have been presented in an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;acm.org&#x2F;&quot;&gt;Association for Computing Machinery (ACM)&lt;&#x2F;a&gt; paper before that (I have not been able to find the paper, if you have access please let me know).&lt;&#x2F;p&gt;
&lt;p&gt;The alternative name &quot;ports and adapters&quot; is included in the original 2005 article title. Both names are still in popular usage amongst developers with &quot;ports and adapters&quot; perhaps being the more &quot;precise&quot; term.&lt;&#x2F;p&gt;
&lt;p&gt;This named pattern was born out of frustration with logic being entangled with untestable user-interface code in Java systems.&lt;&#x2F;p&gt;
&lt;p&gt;The pattern was proposed at a time when &quot;N-Tier layers&quot; in Java were king, so was intended to be in contrast with that.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;visual-representation&quot;&gt;Visual Representation&lt;&#x2F;h3&gt;
&lt;p&gt;The &quot;hexagon&quot; in the name refers to the visual representation, drawn something like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;hexagonal&#x2F;hexagonal.svg&quot; alt=&quot;My diagram of hexagonal architecture&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The visual representation of the pattern shows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;the isolated core logic inside a hexagon,&lt;&#x2F;li&gt;
&lt;li&gt;ports around the edge of the core,&lt;&#x2F;li&gt;
&lt;li&gt;adapters around the edge,&lt;&#x2F;li&gt;
&lt;li&gt;optionally an outer hexagon,&lt;&#x2F;li&gt;
&lt;li&gt;outside of which is the things that interact with the core logic via these &quot;adapters&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The hexagon shape was chosen to give many surfaces on which to draw ports and adapters.&lt;&#x2F;p&gt;
&lt;p&gt;The pattern evokes an image of a honeycomb of hexagonal logic units all collaborating, but this wasn&#x27;t actually part of the original pattern and doesn&#x27;t seem to be a common way of talking about it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;defining-features&quot;&gt;Defining features&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Isolation of a core of logic from:
&lt;ol&gt;
&lt;li&gt;things that make use of the logic, and&lt;&#x2F;li&gt;
&lt;li&gt;things that the logic depends on.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Testability of the logic in isolation from all dependencies.&lt;&#x2F;li&gt;
&lt;li&gt;Terminology:
&lt;ol&gt;
&lt;li&gt;The interfaces that the core logic exposes are named &quot;&lt;strong&gt;ports&lt;&#x2F;strong&gt;&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Code (if any) that connects ports to real &#x2F; alternative &#x2F; test &#x2F; fake implementations of related systems and logic are called &quot;&lt;strong&gt;adapters&lt;&#x2F;strong&gt;&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Connections to things that &lt;strong&gt;depend on the core logic&lt;&#x2F;strong&gt; such as a user-interface are named &quot;&lt;strong&gt;primary&lt;&#x2F;strong&gt; ports&#x2F;adapters&quot;. (Generally drawn on the left.)&lt;&#x2F;li&gt;
&lt;li&gt;Connections to things that &lt;strong&gt;the core logic depends on&lt;&#x2F;strong&gt; such as a database are named &quot;&lt;strong&gt;secondary&lt;&#x2F;strong&gt; ports&#x2F;adapters&quot;. (Generally drawn on the right.)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Technology agnostic;
&lt;ul&gt;
&lt;li&gt;can be applied to Java, C#, Ruby, Golang, ASM, F#, Javascript etc.,&lt;&#x2F;li&gt;
&lt;li&gt;can be applied in the context of Web, Embedded, Punched Card, Mainframes, Serverless, Desktop Apps, Mobile Apps, etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Agnostic to implementation details of how boundaries are actually defined, e.g.:
&lt;ul&gt;
&lt;li&gt;C# interfaces,&lt;&#x2F;li&gt;
&lt;li&gt;Arbitrary boundaries between code in Ruby,&lt;&#x2F;li&gt;
&lt;li&gt;HTTP across microservices,&lt;&#x2F;li&gt;
&lt;li&gt;Message passing systems (in code or across networks),&lt;&#x2F;li&gt;
&lt;li&gt;Rust traits&lt;&#x2F;li&gt;
&lt;li&gt;npm packages&lt;&#x2F;li&gt;
&lt;li&gt;etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;critique&quot;&gt;Critique&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;an-imprecise-pattern&quot;&gt;An imprecise pattern&lt;&#x2F;h3&gt;
&lt;p&gt;Okay, I get it now, but I still don&#x27;t &lt;em&gt;like&lt;&#x2F;em&gt; it as a pattern.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s far too imprecisely defined to be useful in clearly and precisely communicating a design idea.&lt;&#x2F;p&gt;
&lt;p&gt;Before you can use the pattern name to helpfully describe a particular architecture you are communicating, first you have to explain exactly what you mean by the name. It&#x27;s not at all clear how you would code up this pattern in any modern codebase just from reading Alistair&#x27;s original post. There are many youtube videos on the architecture, but given the imprecision of the original post I&#x27;m left wondering if these videos are people&#x27;s own spin and extension of the original article or whether they have access to sources that I do not. If you know of any other primary sources for this then let me know, has he ever spoken on the subject? Was it recorded?&lt;&#x2F;p&gt;
&lt;p&gt;The detailed context in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20051124130845&#x2F;http:&#x2F;&#x2F;alistair.cockburn.us&#x2F;crystal&#x2F;articles&#x2F;hpaaa&#x2F;hexagonalportsandadaptersarchitecture.htm&quot;&gt;Alistair&#x27;s original description of hexagonal architecture&lt;&#x2F;a&gt; from 2005 (which has changed little since then) is so far removed from what we actually deal with these days that it is of little help in figuring out how it communicates intent when someone declares they wish to apply it to a modern system (it speaks of the ancient FIT test framework and the legendary Java Factory classes that are a primary reason for modern developers laughing at Java).&lt;&#x2F;p&gt;
&lt;p&gt;Hexagonal architecture, or ports and adapters, is nothing more than a fancy way of saying &quot;isolate your business logic from all the real world mess of dependencies&quot;. It&#x27;s a generic way of describing keeping pure beautiful logic code out of the tangled web of UI, database and other messy concerns. Some people use it to mean pure code boundaries, some use it to talk about microservice boundaries and the like. I&#x27;ve had a few people mention &quot;hexagonal&quot; to me over the years, and I read the original article many years ago, but I could never connect the name with &lt;em&gt;what that really meant in code&lt;&#x2F;em&gt;. I&#x27;ve had to go on quite a journey to get to the point where I could say a piece of code does or doesn&#x27;t &quot;implement&quot; hexagonal architecture. That seems like long way around to &quot;isolate your code from its dependencies&quot;, which is what I would normally have said. The &lt;em&gt;concept&lt;&#x2F;em&gt; of the named pattern is valid, but I don&#x27;t think I can recommend using the names &quot;hexagonal&quot; or &quot;ports and adapters&quot; to anyone else.&lt;&#x2F;p&gt;
&lt;p&gt;I think it&#x27;s actually better communication to just describe the actual architecture in clearer and less obfuscated words than to use the &quot;hexagonal&quot; or &quot;ports &amp;amp; adapters&quot; names; and after all inter-developer communication is big part of the value of named patterns.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-so-popular&quot;&gt;Why so popular?&lt;&#x2F;h3&gt;
&lt;p&gt;The pattern was created for a narrow reason (entagled UI code, reaction to n-tier), and for some reason has spread as a meme (in the Richard Dawkins sense of the word) to minds far and wide in many diverse contexts, and in my view is proving to cause as much confusion as benefit. I suspect it&#x27;s the attractiveness of the name &quot;hexagonal architecture&quot; which has such a pleasing ring to it that has carried it thus far, rather than its merits as a pattern per se.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;when-should-we-apply-the-pattern&quot;&gt;When should we apply the pattern?&lt;&#x2F;h3&gt;
&lt;p&gt;As with a lot of patterns this pattern is often presented without much context as to when it would be appropriate to apply it and when it would be inappropriate or &quot;over-engineering&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;We have a bit of an epidemic of over-engineering in our industry, so I&#x27;d like to see more incremental and appropriate application of the various patterns, and more explaining of the context where they are and are not useful presented alongside them.&lt;&#x2F;p&gt;
&lt;p&gt;The original article talks of Java UI systems, but is not completely explicit on the intended use case, presumably assuming the reader is operating in a similar context to the author. This pattern has spread far beyond that original domain, being now held up as a panacea for all systems of all shapes and sizes without limitation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;poor-explanations&quot;&gt;Poor explanations&lt;&#x2F;h3&gt;
&lt;p&gt;There are a lot of explanations of this pattern out there that, in my opinion, don&#x27;t really do the job of giving even an experienced programmer a good understanding of the intended concept to a level that allows them in turn to effectively pass on that understanding to others and apply it to real systems.&lt;&#x2F;p&gt;
&lt;p&gt;I had to talk to several people before I got the understanding I currently have, even after digesting much of what is out there, and I&#x27;m not exactly new to programming.&lt;&#x2F;p&gt;
&lt;p&gt;I think this is likely because there isn&#x27;t actually that much to the original post. It describes a fairly simple problem (entangled, untestable code) and solution (isolate from your dependencies), with the addition of a choice of polygon to use when drawing diagrams and some imaginative naming. So when people came along afterwards and attempt to to extend the pattern into some kind of grand, overarching theory of everything their explanations are necessarily either wooly or reach far beyond the original definition resulting in further confusion.&lt;&#x2F;p&gt;
&lt;p&gt;The naming certainly lends itself to a certain grandiosity - &quot;are you applying the &lt;em&gt;hexagonal&lt;&#x2F;em&gt; architecture?&quot; certainly sounds more impressive to the untrained ear than it actually is. The grandiosity of the way it is named, presented and discussed, like some kind of magical panacea that I wasn&#x27;t privy to certainly made me think I must be missing something beyond &quot;decouple your dependencies&quot; when I looked into it (I wasn&#x27;t).&lt;&#x2F;p&gt;
&lt;p&gt;Hopefully this blog post will help bridge the gap, and help you truly grok the thing more quickly than I was able to, even if I wouldn&#x27;t necessarily recommend the name itself.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;an-identity-crisis-why-two-names&quot;&gt;An Identity Crisis - Why Two Names?&lt;&#x2F;h3&gt;
&lt;p&gt;It seems the &quot;hexagonal&quot; name has stuck, even though no-one really wants it. Apparently &quot;Ports and Adapters&quot; actually describes it better. I suspect neither name has emerged victorious because neither name completely covers it, and &quot;ports and adapters&quot; although marginally more descriptive is more of a mouthful than &quot;hex arch&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Which name should we use?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Hexagonal&quot; hints at the idea that there&#x27;s an inside (logic) and an outside (everything else), and that it has multiple surfaces (ports). It fails to convey much more than that, particularly the &quot;adapter&quot; part of the pattern, why you&#x27;d care, or what it might be for.&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Ports and adapters&quot; nicely captures the detail of abstracting away a single dependency, but completely fails to convey the idea that we&#x27;re isolating pure logic from messy dependencies.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Once you &lt;em&gt;know&lt;&#x2F;em&gt; what it means, and so does your whole team then it doesn&#x27;t really matter much what the name is as humans are quite good at connecting random collections of phonemes with abstract concepts and remembering them, but patterns are definitely a bit more useful when there isn&#x27;t such a steep curve to grok them and keep them in your head.&lt;&#x2F;p&gt;
&lt;p&gt;It would be nice if there was one term but whatever. Hopefully this post will help others who were confused by the whole charade get the concept into a concrete form in their head, wire up the two terms for it and get back to coding; whether or not they use it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-good-bits&quot;&gt;The Good Bits&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s not all obfuscation and bad ideas. There&#x27;s a core of good in the hexagonal &#x2F; ports &amp;amp; adapters pattern.&lt;&#x2F;p&gt;
&lt;p&gt;If you have any business logic of any reasonable complexity, then there&#x27;s a lot to be said for writing that in pure, unit-testable code that is not entangled with any of the workings of the outside world. And the hexagonal architecture, once understood by all involved, is a good shorthand for drawing that circle (sorry, hexagon) around the core logic and being able to easily discuss with peers whether that bright line has been crossed by any of the code.&lt;&#x2F;p&gt;
&lt;p&gt;By declaring this to be the pattern in use (don&#x27;t forget to put it in your &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;adr.github.io&#x2F;&quot;&gt;ADR&lt;&#x2F;a&gt;), it becomes easy to spot and discuss violations such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;business logic hiding in code that deals with specific technologies (such as stored procedures, shudder, or aspnet MVC controllers)&lt;&#x2F;li&gt;
&lt;li&gt;specific technology concerns leaking into the core business logic (such as knowledge of specific storage such as for example code that&#x27;s specific to Azure Blob Storage).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Chris put it nicely in our LinkedIn back-and-forth:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;What [ports and adapters] does is provide a separation of concerns between the essential complexity of your application (the domain model, if you want to use DDD terminology) and the accidental complexity of how it interacts with the outside world via strong abstractions.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Chris Bimson (LinkedIn comment, 2023)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This keeps code with the same reason to change together (business rules), and code with different reason to change separate (technology shifts).&lt;&#x2F;p&gt;
&lt;p&gt;Just be aware of the costs of ditching other abstractions blindly in the name of &quot;architecture&quot; (see section on repository patterns). Agility matters.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;too-much-architecture&quot;&gt;Too much &quot;Architecture&quot;?&lt;&#x2F;h3&gt;
&lt;p&gt;Beware the added complexity (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=bDWApqAUjEI&amp;amp;t=377s&quot;&gt;as mentioned by Alex Hyett in his youtube explanation of Hexagonal Architecture&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t add this pattern if you don&#x27;t actually &lt;em&gt;need&lt;&#x2F;em&gt; it.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve seen code where blindly applying &quot;hexagonal architecture&quot; (or some unholy bastardization of it) resulted in ten times the code that should actually have been needed to solve the business problem, throwing away perfectly good abstractions like entity-framework in favour of miles of toil-inducing code and &quot;repository&quot; classes as far as the eye can see. Curiously, a long time ago, and in a very similar vein, I saw a team cripple themselves by creating no less than &lt;em&gt;seven&lt;&#x2F;em&gt; &quot;layers&quot; in their code where &lt;em&gt;none&lt;&#x2F;em&gt; would have been better... velocity slowed to an absolute crawl.&lt;&#x2F;p&gt;
&lt;p&gt;Like so many patterns, people talk about the pattern&#x27;s strengths but fail to mention when you shouldn&#x27;t use them, leaving you to deduce the context for appropriate application yourself.&lt;&#x2F;p&gt;
&lt;p&gt;What we want is not &quot;no architecture&quot;, but it also isn&#x27;t dogmatic and incorrect architecture. I don&#x27;t think throwing in hexagonal because you can use it to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=r6tH55syq0o&quot;&gt;flex on the other developers&lt;&#x2F;a&gt; is the right balance.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I also don&#x27;t think you should YAGNI architecture to that extent, unless what you are doing is genuinely throw away. Architecture isn&#x27;t optional - you&#x27;ll get one whatever happens - it pays to think about it in advance so everybody shares a common technical vision and is pulling in the same direction.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Chris Bimson (LinkedIn comments, 2023)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;If you know in advance that there will be sufficient complexity in the application and that this pattern is likely a good fit then put it in place early on and you&#x27;ll be in a good place for robust evolution of the code in the long run without dissolving into a spaghetti mess later.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;oh-no-the-repository-pattern&quot;&gt;Oh No, The Repository Pattern&lt;&#x2F;h3&gt;
&lt;p&gt;Something that I really didn&#x27;t like in the canonical article was the mention of the repository pattern. To be fair it&#x27;s of it&#x27;s time, but I&#x27;ve been burned by a C# project that cargo-culted the pattern. The result was an incredibly slow to iterate on system.&lt;&#x2F;p&gt;
&lt;p&gt;From the hex arch article:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;From the application’s perspective, if the database is moved from a SQL database to a flat file or any other kind of database, the conversation across the API should not change.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Alistair Cockburn&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Which made me think: Oh god, that old engineering anti-pattern, hello repository pattern bye bye EF &amp;amp; LINQ for things that were simple enough that it would be better.&lt;&#x2F;p&gt;
&lt;p&gt;In the days when you had to hand craft SQL for all CRUD, and embed it directly in your PHP code, the &quot;repository pattern&quot; seemed like a good idea. But I have personally seen train-wreck over-engineering projects where there was an attempt to brute-force a repository layer into something that would have been better without it.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s why you shouldn&#x27;t do &quot;repository&quot; layers in modern applications:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Your ORM &lt;em&gt;is&lt;&#x2F;em&gt; a repository pattern. Hiding the ORM in some custom &lt;code&gt;IRepository&lt;&#x2F;code&gt; is nothing more than toil for a net-negative benefit. More layers are not always better, each layer costs you agility.&lt;&#x2F;li&gt;
&lt;li&gt;As query systems have got more powerful (see LINQ in dotnet, GraphQL, etc.) the idea of predefining every shape of query you might want to run and encoding it in an API or interface becomes a huge unnecessary drag on development speed, resulting in massive additional cost to the business in exchange for reduced agility.&lt;&#x2F;li&gt;
&lt;li&gt;The idea that you need to support switching data stores is just baloney. Unless your business tells you up front that they need Oracle + MSSQL + MySql then introducing an expensive abstraction on the off-chance is ludicrous, and not giving your client&#x2F;employer good value for money. If you really do have to shift tech someday, then you&#x27;ll be doing a lot more work than just swapping out an adapter; that&#x27;s just naïve wishful thinking.&lt;&#x2F;li&gt;
&lt;li&gt;Swapping out storage for testing:
&lt;ol&gt;
&lt;li&gt;So many bugs come from the integration of code, ORM and database that you should be including it in the majority of your test coverage, not mocking it out.&lt;&#x2F;li&gt;
&lt;li&gt;There are better ways to solve this problem, such as in-memory versions of real databases, and tooling that allows easy resetting of the persisted state.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Of course sometimes it will be the right pattern to apply having considered the above, but as with all patterns, don&#x27;t just slam it in because &quot;you can never have enough architecture&quot; (see also &quot;CV-driven-development&quot;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unit-testing-good-but-not-enough&quot;&gt;Unit Testing - Good, But Not Enough&lt;&#x2F;h3&gt;
&lt;p&gt;An example I recently saw of hexagonal architecture allegedly being used in a C# codebase was a good example of the weakness of unit testing as the sole bastion of regression testing. It had acres of unit tests for the individual over-simplified pieces dictated by their interpretation of this pattern, but zero end-to-end tests and thus basically no confidence in being able to make changes to the overall system without regressions.&lt;&#x2F;p&gt;
&lt;p&gt;It was also a metric ton of code and interfaces that could be largely eliminated giving more agility and less to maintain.&lt;&#x2F;p&gt;
&lt;p&gt;By mocking out things like storage, your tests only cover a fraction of what&#x27;s important to the business.&lt;&#x2F;p&gt;
&lt;p&gt;If quality end to end tests (or Component tests as they were called in the last place I was at) are in place then you can have more confidence in the whole thing, but at that point the highly mocked unit tests that hexagonal architecture implies might become far less valuable, being more about testing many variations and reducing feedback time than being your only source of confidence.&lt;&#x2F;p&gt;
&lt;p&gt;Unit testing has its place in the pyramid of tests (particularly for testing many variations and combinations of scenarios quickly, i.e. &quot;shift-left&quot;), but if you have endless unit tests but don&#x27;t know if anything works when integrated and shipped then you&#x27;re doing it wrong (standard example in dotnet is forgetting to configure dependency injection in the non-test startup code).&lt;&#x2F;p&gt;
&lt;p&gt;Lately I&#x27;ve been seeing a welcome swing away from unit-testing-only in dotnet land towards an emphasis on &quot;component testing&quot;, integration testing, end-to-end testing and a general eye towards preventing regressions in what the business and users actually care about rather than some microscopic detail when all around is fragile.&lt;&#x2F;p&gt;
&lt;p&gt;As ever, all things in balance. Use your brains. Caveat emptor.&lt;&#x2F;p&gt;
&lt;p&gt;I keep meeting people promoting either one extreme (unit tests!) or the other (black box &quot;component&quot; tests only!!) and either extreme seems a bit too absolute to me. (Perhaps I&#x27;d be a better conference speaker if I just declared an unreasonable extreme, lol).&lt;&#x2F;p&gt;
&lt;p&gt;The reason that the existence of &quot;hexagonal architecture&quot; bothers me in this context, is that someone has clearly used the term as: &quot;it&#x27;s a pattern therefore I must be right and you can&#x27;t argue with me (p.s. I&#x27;m superior to you because I know this magic incantation of architecture and the non-technical folk lap it up)&quot;. If the pattern had never existed, it would be one less opportunity for this destructive behaviour.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;going-deeper&quot;&gt;Going deeper&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-original-pain-ui-entanglement&quot;&gt;The Original Pain: UI Entanglement&lt;&#x2F;h3&gt;
&lt;p&gt;The current version of the hex arch article says it is a way of preventing mingling of logic with UI code:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;… infiltration of business logic into the user interface code …&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So the original article was actually motivated by sloppy UI programming where logic and presentation were combined into an amorphous blob (I have seen this first hand myself too), and then the concept was extended to also cover the problem of tight coupling to dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;Throw in a sprinkle of dubiously helpful analogies (ports like on physical computers, hexagons like because it needed a shape) and we have a &quot;named architecture&quot;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-hexagons&quot;&gt;Why Hexagons?&lt;&#x2F;h3&gt;
&lt;p&gt;To slightly butcher the original for brevity and clarity:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The hexagon is intended … to get away from the one-dimensional layered [architecture] picture … and … [to accommodate] the presence of … [any] number of different ports … to allow the people doing the drawing to have room to insert ports and adapters as they need …&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Alistair Cockburn&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So that&#x27;s why it&#x27;s not circles (Onions), or layers (N-Tier), or boxes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;primary-and-secondary&quot;&gt;&quot;Primary&quot; and &quot;Secondary&quot;&lt;&#x2F;h3&gt;
&lt;p&gt;According to Alistair these come straight out of UML nomenclature. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.softwareideas.net&#x2F;primary-and-secondary-actor-use-case-diagram&quot;&gt;https:&#x2F;&#x2F;www.softwareideas.net&#x2F;primary-and-secondary-actor-use-case-diagram&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Primary&lt;&#x2F;strong&gt; (usually drawn on the left by convention) are things that will actively use the core logic, such as GUIs, HTTP APIs for customers to use etc.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Secondary&lt;&#x2F;strong&gt; (usually drawn on the right) are things that the core logic will make use of such as data storage, outbound messaging, subservient APIs etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The original article explains:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;… ports and adapters show up in two flavors, which I’ll call ‘’primary’’ and ‘’secondary’’, ... idea from use cases of “primary actors” and “secondary actors”. A ‘’primary actor’’ is an actor that drives the application (takes it out of quiescent state to perform one of its advertised functions). A ‘’secondary actor’’ is one that the application drives …&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Alistair Cockburn&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;See this &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.softwareideas.net&#x2F;primary-and-secondary-actor-use-case-diagram&quot;&gt;explanation of UML primary&#x2F;secondary actors&lt;&#x2F;a&gt; for context of these terms in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Unified_Modeling_Language&quot;&gt;Unified Modeling Language (UML)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hexagons-versus-n-tier&quot;&gt;Hexagons versus N-Tier&lt;&#x2F;h3&gt;
&lt;p&gt;Hexagonal architecture emerged at a time when N-Tier was the defacto standard for all software architecture, which is worth bearing in mind when trying to grok what on earth the hexagons are all about.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Perhaps the other key difference is how dependencies are orientated. So in your classic N-Tier architecture, even with good abstractions between loosely coupled layers, they frequently look like this:&lt;br &#x2F;&gt;
&lt;code&gt;Presentation -&amp;gt; Logic -&amp;gt; Persistence&lt;&#x2F;code&gt;&lt;br &#x2F;&gt;
… The difference can be subtle, but P&amp;amp;A places much more emphasis on explicit abstractions with a defined role than n-tier descriptions generally do.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Chris Bimson (LinkedIn comments, 2023)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;hexagonal-and-domain-driven-design-ddd&quot;&gt;Hexagonal and Domain Driven Design (DDD)&lt;&#x2F;h3&gt;
&lt;p&gt;I heard it said at some point that hexagonal architecture was an enabler for domain driven design. It took me a while to understand that statement. In some ways hexagonal and DDD say the same thing in different ways - that there should be a rich central model &#x2F; logic which encapsulates the businesss logic.&lt;&#x2F;p&gt;
&lt;p&gt;The need for hexagonal architecture to &quot;enable&quot; DDD may be a reaction to the &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.martinfowler.com&#x2F;bliki&#x2F;AnemicDomainModel.html&quot;&gt;anemic domain model&lt;&#x2F;a&gt;&quot; problem. The description of hexagonal architecture encourages thinking of a rich piece of logic at the centre, not just a collection of inert nouns; and the &quot;ports&quot; around the edge (in whatever form they take) give access to that logic through more than just &quot;get&quot; and &quot;set&quot; methods, and this definitely pushes in the same direction as DDD.&lt;&#x2F;p&gt;
&lt;p&gt;Having looked into this, I wouldn&#x27;t say you have to have or even know about hexagonal architecture to do DDD well, but I can see how the two concepts can be used together when discussing conceptual designs amongst engineers so that&#x27;s something worth being aware of at least.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pattern-archaeology&quot;&gt;Pattern Archaeology&lt;&#x2F;h3&gt;
&lt;p&gt;The historical context of this pattern is important to understand to get where it is coming from.&lt;&#x2F;p&gt;
&lt;p&gt;The whole thing makes more sense if you think of the Java N-Tier Big Architecture world that I believe it emerged from, rather than the more sensible C# that I&#x27;ve seen better teams do without such concepts.
It&#x27;s not clear when this terminology was created, and who came up with it first. I did some digging but didn&#x27;t really get to the bottom of it.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;trends.google.co.uk&#x2F;trends&#x2F;explore?date=all&amp;amp;q=hexagonal%20architecture&amp;amp;hl=en-GB&quot;&gt;search on google trends&lt;&#x2F;a&gt; indicates that it&#x27;s probably been in use in some form since as early as 2005&#x2F;2006. I don&#x27;t know what the earlier spikes are and whether they are relevant or something unrelated. Perhaps the early spikes are from the CM paper, or maybe even his own checking for the term as it&#x27;s only in 100s not 10,000s.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;hexagonal&#x2F;hexagonal-trends.png&quot; alt=&quot;google trends screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The oldest reference I could find on Alistair&#x27;s website is from 14th Nov 2005: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20051124130845&#x2F;http:&#x2F;&#x2F;alistair.cockburn.us&#x2F;crystal&#x2F;articles&#x2F;hpaaa&#x2F;hexagonalportsandadaptersarchitecture.htm&quot;&gt;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20051124130845&#x2F;http:&#x2F;&#x2F;alistair.cockburn.us&#x2F;crystal&#x2F;articles&#x2F;hpaaa&#x2F;hexagonalportsandadaptersarchitecture.htm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The heading claims an even older date of 4th September 2005:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Hexagonal (Ports &amp;amp; Adapters) Architecture&lt;br &#x2F;&gt;
Alistair Cockburn, Humans and Technology, arc@acm.org,&lt;br &#x2F;&gt;
HaT TR 2005.02, Sept. 04, 2005,&lt;br &#x2F;&gt;
©Alistair Cockburn&lt;br &#x2F;&gt;
(v 0.9 to be updated after reader comments)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This rather implies that it was published somewhere in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.acm.org&#x2F;&quot;&gt;Association for Computing Machinery (ACM)&lt;&#x2F;a&gt; but I can find no record of it. That fits in my experience as the ACM seems a peculiarly out of touch and academic institution from my perspective as a doer. (I tried their podcast lately, some great names being interviewed by an awful interviewer). If anyone can find a record of that publication let me know. I contacted ACM by email and they say they have no publication by the name of &quot;Humans and Technology&quot; so the trail is cold for now. I&#x27;ll possibly give Alastair a shout on LinkedIn for more info as he seems to still be active.&lt;&#x2F;p&gt;
&lt;p&gt;Following the internet archives of Alistair&#x27;s site, the original page was moved when he was running the mediawiki software on it. It appears in the archives on 11 July 2006: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20060711221010&#x2F;http:&#x2F;&#x2F;alistair.cockburn.us&#x2F;index.php&#x2F;Hexagonal_architecture&quot;&gt;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20060711221010&#x2F;http:&#x2F;&#x2F;alistair.cockburn.us&#x2F;index.php&#x2F;Hexagonal_architecture&lt;&#x2F;a&gt;. This one is worth a look as it has context that appears to be missing from more recent versions.&lt;&#x2F;p&gt;
&lt;p&gt;It was interesting to run a diff on the oldest and newest copies of the article to see how much has changed in 18 years. The answer is not a lot apart from a bit of formatting and whitespace noise. I put a cache of the original in a gist and then overwrote it with a cache of the latest as a mirror, so you can see the diff here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;4f6b6d222b7742f4784b3b306a0cfd43&#x2F;revisions?diff=split&quot;&gt;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;4f6b6d222b7742f4784b3b306a0cfd43&#x2F;revisions?diff=split&lt;&#x2F;a&gt;. I only spotted two changes, a typo fix, and that for some reason &quot;event&quot; has been replaced with &quot;driver&quot;, presumably to broaden it from event based UI programming, to anything that might want to use the core logic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alistair-on-video&quot;&gt;Alistair on video&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=AOIWUPjal60&quot;&gt;Rodrigo Branas: Hexagonal Architecture (Ports and Adapters) with Alistair Cockburn &#x2F;&#x2F; Live #98&lt;&#x2F;a&gt; - May 2022 interview with Alistair, digging in to the history.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;footnotes&quot;&gt;Footnotes&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;references-further-reading&quot;&gt;References &amp;amp; further reading&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;alistair.cockburn.us&#x2F;hexagonal-architecture&#x2F;&quot;&gt;The original article on hex arch by Alistair Cockburn&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20230418161402&#x2F;https:&#x2F;&#x2F;alistair.cockburn.us&#x2F;hexagonal-architecture&#x2F;&quot;&gt;Archive of Alistair&#x27;s hex arch article on archive.org&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;cWCZms92-1g?t=964&quot;&gt;A talk on Rust Crux that follows the hex arch&lt;&#x2F;a&gt; - no coincidence that Crux is also business logic interfacing with a user-interface layer and keeping the two concerns separated&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wiki.c2.com&#x2F;?HexagonalArchitecture=&quot;&gt;c2 wiki on hex arch&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wiki.c2.com&#x2F;?PortsAndAdaptersArchitecture=&quot;&gt;c2 wiki on ports and adapters&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.softwareideas.net&#x2F;primary-and-secondary-actor-use-case-diagram&quot;&gt;Explanation of UML primary&#x2F;secondary actors&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;feed&#x2F;update&#x2F;urn:li:activity:7083072166547595264&#x2F;&quot;&gt;The LinkedIn discussion where everyone tells me hex arch is &lt;em&gt;not&lt;&#x2F;em&gt; irrelevant mumbo jumbo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Someone else trying to explain it: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;idealo-tech-blog&#x2F;hexagonal-ports-adapters-architecture-e3617bcf00a0&quot;&gt;https:&#x2F;&#x2F;medium.com&#x2F;idealo-tech-blog&#x2F;hexagonal-ports-adapters-architecture-e3617bcf00a0&lt;&#x2F;a&gt; (my apologies for linking to the horror that is medium).&lt;&#x2F;li&gt;
&lt;li&gt;And another explanation: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dev.to&#x2F;timhub&#x2F;learn-to-build-a-hexagonal-architecture-micro-service-l1h&quot;&gt;https:&#x2F;&#x2F;dev.to&#x2F;timhub&#x2F;learn-to-build-a-hexagonal-architecture-micro-service-l1h&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=bDWApqAUjEI&quot;&gt;&quot;Hexagonal Architecture: What You Need To Know - Simple Explanation&quot; by Alex Hyett on YouTube&lt;&#x2F;a&gt;. - This was nice and clear, and touched on the pros and cons.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vaadin.com&#x2F;blog&#x2F;ddd-part-3-domain-driven-design-and-the-hexagonal-architecture&quot;&gt;vaadin - DDD Part 3: Domain-Driven Design and the Hexagonal Architecture&lt;&#x2F;a&gt; - an exceptionally long piece with one person&#x27;s opinions on using hexagonal with DDD.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;questions&#x2F;386102&#x2F;arent-domain-driven-design-hexagonal-architecture-with-real-world-constraints&quot;&gt;https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;questions&#x2F;386102&#x2F;arent-domain-driven-design-hexagonal-architecture-with-real-world-constraints&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jmgarridopaz.github.io&#x2F;&quot;&gt;Hexagonal Me&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;attack-ideas-not-people&quot;&gt;Attack Ideas not People&lt;&#x2F;h3&gt;
&lt;p&gt;To be absolutely clear here, I applaud Alistair for taking the time to express and communicate a concept, and push the state of the art forward at the time. My critique of &quot;hexagonal architecture&quot; above should be taken as an assessment of current usage and value, and in no way be inferred to imply that anyone should hesitate to publish whatever ideas they think will be of value to the world. Put your ideas into the world and let them stand or fall on their own merits.&lt;&#x2F;p&gt;
&lt;p&gt;Alistair was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;157709.157750&quot;&gt;publishing papers when I was still in school&lt;&#x2F;a&gt; and copying BASIC programs into an Amstrad in my holidays.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;broken-urls&quot;&gt;Broken URLs&lt;&#x2F;h3&gt;
&lt;p&gt;While I was researching this the original author had &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20230606080030&#x2F;https:&#x2F;&#x2F;alistair.cockburn.us&#x2F;coming-soon&#x2F;&quot;&gt;unhelpfully ripped down their entire website&lt;&#x2F;a&gt; so I was left searching archive.org for the true source. Pretty poor show for anyone in software imho, websites really aren&#x27;t hard to keep running these days. So with that battle scar in mind here&#x27;s an archive link to the current version of the original hexagonal architecture post in case it happens again: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20230418161402&#x2F;https:&#x2F;&#x2F;alistair.cockburn.us&#x2F;hexagonal-architecture&#x2F;&quot;&gt;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20230418161402&#x2F;https:&#x2F;&#x2F;alistair.cockburn.us&#x2F;hexagonal-architecture&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m pretty shocked that anyone who claims to be in tech, a programmer no less, thinks it&#x27;s okay to just redirect everything on their site to a coming soon page in the name of a &quot;rebuild&quot;. There is no excuse for this. It is not at all hard to build a new site offline, check all the redirects if you wish to change urls, and then flip the DNS when it&#x27;s a-okay. At time of writing he&#x27;s put back the hex arch url, but all the links on it are broken as everything else is redirecting to the stupid kitch coming-soon page with the idiotic grinning ronald mcdonald image who sits their taunting anyone who actually wanted to know anything and proving that this was for whatever reason a 100% intentional act of destruction. Thank goodness for archive.org.&lt;&#x2F;p&gt;
&lt;p&gt;Alistair, if you&#x27;re reading this, then please also read &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;Provider&#x2F;Style&#x2F;URI.html&quot;&gt;Cool URIs don&#x27;t change&lt;&#x2F;a&gt;, and try and find a way to do your migrations without months of downtime next time, it&#x27;s really not cool.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pronouncing-cockburn&quot;&gt;Pronouncing Cockburn&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s pronounced &quot;co-burn&quot; and is of Scottish origin according to Alistair.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;pronounced &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20051215124021&#x2F;http:&#x2F;&#x2F;familytreemaker.genealogy.com&#x2F;users&#x2F;c&#x2F;o&#x2F;c&#x2F;Russell-W-Cockburn&#x2F;?Welcome=1058060142&quot;&gt;Coburn&lt;&#x2F;a&gt;&quot;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20051104031017&#x2F;http:&#x2F;&#x2F;www.clanshop.co.uk&#x2F;clans&#x2F;cockburn.htm&quot;&gt;Scottish&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;19991117103944&#x2F;http:&#x2F;&#x2F;www.tartans.com:80&#x2F;clans&#x2F;cockburn&#x2F;cockburn.html&quot;&gt;way&lt;&#x2F;a&gt;&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20051124112619&#x2F;http:&#x2F;&#x2F;alistair.cockburn.us&#x2F;&quot;&gt;Alistair&#x27;s original site header&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cockburn_(surname)&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cockburn_(surname)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;feedback-please&quot;&gt;Feedback please!&lt;&#x2F;h2&gt;
&lt;p&gt;If you think there&#x27;s something I&#x27;ve missed here, or you don&#x27;t agree with my description then please do get in touch so this article can be improved to the point of being useable as a canonical guide to all who seek to understand the pattern and use it as a communication tool between developers and other interested parties. That, after all, is the whole point of &quot;patterns&quot;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New podcast episodes - rust meetups and fast talkers</title>
        <published>2023-06-30T00:00:00+00:00</published>
        <updated>2023-06-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/06/30/new-podcast-episodes---rust-meetups-and-fast-talkers/"/>
        <id>https://0x5.uk/2023/06/30/new-podcast-episodes---rust-meetups-and-fast-talkers/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/06/30/new-podcast-episodes---rust-meetups-and-fast-talkers/">&lt;p&gt;If you&#x27;re a podcast lover and interested in tech you might be interested in the two new episodes I&#x27;ve published this week&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust-workshop&quot;&gt;Rust Workshop&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;s&#x2F;f4dbb201&quot;&gt;Rust meetups and DevOps pipelines with end-to-end testing for confident fast shipping&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;software-should-be-free&quot;&gt;Software Should Be Free&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;s&#x2F;e4e48a64&quot;&gt;Beware &quot;Fast Talkers&quot; and &quot;Pattern Obsessives&quot; - evolve your architecture&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;180&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; seamless src=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;e&#x2F;e4e48a64&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;180&quot; frameborder=&quot;no&quot; scrolling=&quot;no&quot; seamless src=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;e&#x2F;f4dbb201&quot;&gt;&lt;&#x2F;iframe&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Enabling modern app security</title>
        <published>2023-06-14T00:00:00+00:00</published>
        <updated>2023-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/06/14/enabling-modern-app-security/"/>
        <id>https://0x5.uk/2023/06/14/enabling-modern-app-security/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/06/14/enabling-modern-app-security/">&lt;p&gt;A broad-view of improving security in any organisation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;an-inspirational-panel-discussion&quot;&gt;An inspirational panel discussion&lt;&#x2F;h2&gt;
&lt;p&gt;Yesterday I went to a panel discussion hosted by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;esynergy.co.uk&#x2F;&quot;&gt;eSynergy&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;esynergy.co.uk&#x2F;event&#x2F;security-excellence-in-engineering&#x2F;&quot;&gt;&quot;Innovation at its safest: Excellence in Software Engineering through Integrated Security Best Practices&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;esynergy-security-event-IMG_20230613_175534.jpg&quot; alt=&quot;photo of panel discussion&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The whole event was live-streamed, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=FH5kyUwRZ5Q&quot;&gt;watch the panel discussion recording here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For me who lives in developer-land, it was a useful broadening of perspectives around app security. What follows are some bits that I took away from the discussions, which I think provide a useful starting point for anyone tasked with running any modern software systems in this increasingly hostile security environment.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;who-s-who-at-the-event&quot;&gt;Who&#x27;s who at the event&lt;&#x2F;h3&gt;
&lt;p&gt;The speakers at the event were as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Intro from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;ulrikeeder&#x2F;&quot;&gt;Ulrike Eder (eSynergy)&lt;&#x2F;a&gt; [00:03:47]&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Beyond OWASP Top 10&quot; from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;rewtd&#x2F;&quot;&gt;Grant Ongers&lt;&#x2F;a&gt; from OWASP and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;securedelivery.io&#x2F;&quot;&gt;secure delivery&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;defcon.social&#x2F;@rewtd&quot;&gt;@rewtd@defcon.social&lt;&#x2F;a&gt; &#x2F; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;rewtd&quot;&gt;@rewtd&lt;&#x2F;a&gt; [00:06:37]&lt;&#x2F;li&gt;
&lt;li&gt;Grant was then joined for the panel discussion by: [00:19:40]
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;salman-iqbal-a6a5b026&quot;&gt;Salman Iqbal&lt;&#x2F;a&gt;, Principal Consultant, DevOps and ML Security at esynergy (hosting the panel)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;yayiwu&#x2F;&quot;&gt;Teresa Wu&lt;&#x2F;a&gt; VP Engineer at J.P. Morgan&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;ben-burdsall-6ba2bb&quot;&gt;Ben Burdsall&lt;&#x2F;a&gt;, Chief Technology Officer at dunnhumby, non-exec at eSynergy&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;tomtechharris&#x2F;&quot;&gt;Tom Harris&lt;&#x2F;a&gt; Chief Technology Officer at ClearBank, BuildCircle, ex-JustEat&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s a bewildering array of things you can &#x2F; should &#x2F; must do for the security of your systems, users and company.&lt;&#x2F;p&gt;
&lt;p&gt;Within this article you&#x27;ll find some starting points for your onwards security journey&lt;&#x2F;p&gt;
&lt;h3 id=&quot;levels&quot;&gt;Levels&lt;&#x2F;h3&gt;
&lt;p&gt;There are two reasons for thinking of security in layers or levels:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Your business needs, risks, regulatory environment and finances&lt;&#x2F;li&gt;
&lt;li&gt;Your security maturity&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Some businesses are more at risk such as banks and thus need (and can afford) a more significant investment in security measures (such as multi-layered cloud infrastructure defenses), whereas some have less budget and less risk and so can operate at the simpler levels of security.&lt;&#x2F;p&gt;
&lt;p&gt;If you are currently very poor on security then there&#x27;s little point sprinkling some advanced things on top, it&#x27;s important to properly address each layer of security capability on the way up.&lt;&#x2F;p&gt;
&lt;p&gt;Regardless of your business needs, perfect security is always an unattainable ideal, but a worthy target nonetheless. The Unicorn project calls this kind of never-quite-attainable perfection an &quot;Ideal&quot;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.infoq.com&#x2F;articles&#x2F;unicorn-project&#x2F;&quot;&gt;The Unicorn Project and the Five Ideals: Interview with Gene Kim&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;who-s-job-is-security-anyway&quot;&gt;Who&#x27;s job is security anyway?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;The directors are &quot;accountable&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;The developers, product etc. are &quot;responsible&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While developers can and should write &quot;secure code&quot; (SQL Injection vulnerabilities is still on the top 10 list), it&#x27;s important that everyone plays their part.&lt;&#x2F;p&gt;
&lt;p&gt;Notably the product function (&quot;product owners&quot;), as they are the decision makers for balancing the competing demands placed on delivery&#x2F;development teams, including how much to invest in security defenses. (Much nodding in the audience at this one!)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;developers&quot;&gt;Developers&lt;&#x2F;h4&gt;
&lt;p&gt;Tools help but the developers need to understand what is required.&lt;&#x2F;p&gt;
&lt;p&gt;At ClearBank there is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Lunch and learn&quot; sessions from AppSec team.&lt;&#x2F;li&gt;
&lt;li&gt;Training with &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hacksplaining.com&#x2F;&quot;&gt;HackSplaining&lt;&#x2F;a&gt;&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;how-clearbank-leveled-up-app-dev-security&quot;&gt;How ClearBank leveled-up app dev security&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Added security training&lt;&#x2F;li&gt;
&lt;li&gt;Required pull-request approval from someone with security training&lt;&#x2F;li&gt;
&lt;li&gt;This created a temporary bottleneck, which encouraged everyone to do the security training&lt;&#x2F;li&gt;
&lt;li&gt;Incubated an AppSec team to &quot;reduce the cognitive load of security in collaboration with CISO and CTO (Tom)
&lt;ol&gt;
&lt;li&gt;Enthusiastic internal devs&lt;&#x2F;li&gt;
&lt;li&gt;Additional external resource&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Collaboration at the top then filters down to all the teams&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;justifying-security-investment&quot;&gt;Justifying security investment&lt;&#x2F;h3&gt;
&lt;p&gt;The board of directors now face &lt;strong&gt;criminal&lt;&#x2F;strong&gt; penalties (i.e. jail time) if they don&#x27;t properly approach security. It used to be just financial penalties but that wasn&#x27;t enough as they could just be absorbed as a &quot;cost of doing business&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;If you need the C-suite or board to take security sufficiently seriously you can remind them of the legal penalties and costs!&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Do security right because it&#x27;s the right thing to do and you care about your customer and their data.&lt;&#x2F;li&gt;
&lt;li&gt;There&#x27;s the &quot;daily mail test&quot; - how would we feel if there was a breach and it hit the papers?&lt;&#x2F;li&gt;
&lt;li&gt;Put a cost on breaches, e.g. probability of breach multiplied by cost of breach.&lt;&#x2F;li&gt;
&lt;li&gt;Use the &quot;house fire&quot; analogy. No-one thinks that insuring your house against fire is a bad investment. The same is true for investing in security before you have a incident or breach.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;lead-from-the-top&quot;&gt;Lead from the top&lt;&#x2F;h3&gt;
&lt;p&gt;Leaders should do the training too, no-one is too important and it sets the tone and culture, encouraging everyone down to the devs to do the training too.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shift-left&quot;&gt;Shift left&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Shift Left: &quot;take a task that&#x27;s traditionally done at a later stage of the process and perform that task at earlier stages&quot;&lt;br &#x2F;&gt;
~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devopedia.org&#x2F;shift-left&quot;&gt;https:&#x2F;&#x2F;devopedia.org&#x2F;shift-left&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Move security left. Nuff said. Dev+Security not Dev versus Security.&lt;&#x2F;p&gt;
&lt;p&gt;Check security and licenses at build time. Gives assurance of security for customers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-top-10-is-not-enough&quot;&gt;The Top 10 is not enough&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;owasp.org&#x2F;Top10&#x2F;&quot;&gt;OWASP Top 10&lt;&#x2F;a&gt; is a good tool for awareness and generating conversations, but addressing these is only the lowest &quot;level&quot; of security.&lt;&#x2F;p&gt;
&lt;p&gt;A much broader view of security is provided by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;owasp.org&#x2F;www-project-application-security-verification-standard&#x2F;&quot;&gt;OWASP Application Security Verification Standard&lt;&#x2F;a&gt; (ASVS). It is also broken down into levels to allow you to start at the bottom and work up as your security capabilities mature, and decide what level your business needs to attain based on the relevant risks and regulations. Banks for example would go all the way to level 3.&lt;&#x2F;p&gt;
&lt;p&gt;There are also per-environment lists. E.g. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mas.owasp.org&#x2F;&quot;&gt;OWASP Mobile Application Security&lt;&#x2F;a&gt; for mobile app development.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pen-tests&quot;&gt;Pen tests&lt;&#x2F;h3&gt;
&lt;p&gt;Don&#x27;t just tick off &quot;pen test&quot;, ask your pen test providers how they work.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Do they just cover the OWASP Top 10?&lt;&#x2F;li&gt;
&lt;li&gt;Do they just cover the SAMM Top 20?&lt;&#x2F;li&gt;
&lt;li&gt;Do they go deeper than the Top-n?&lt;&#x2F;li&gt;
&lt;li&gt;Do they look at ASVS?&lt;&#x2F;li&gt;
&lt;li&gt;What tools do they use?&lt;&#x2F;li&gt;
&lt;li&gt;Do the tools report against the ASVS? (If not talk to the tool provider!)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;threat-modelling&quot;&gt;Threat modelling&lt;&#x2F;h3&gt;
&lt;p&gt;Use threat modelling, assess and then defend against that.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;red-blue-teams&quot;&gt;Red&#x2F;blue teams&lt;&#x2F;h3&gt;
&lt;p&gt;Can be effective, but also very expensive. Do the basics first (e.g. sql-injection training!)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tools-resources-to-level-up-security&quot;&gt;Tools &amp;amp; resources to level-up security&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Training and assessments from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;securedelivery.io&#x2F;&quot;&gt;Secure Delivery&lt;&#x2F;a&gt;. They provide security training and assessments for everyone in the business, not just developers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;owaspsamm.org&#x2F;&quot;&gt;OWASP Software Assurance Maturity Model&lt;&#x2F;a&gt; (SAMM) A &quot;measurable way for all types of organizations to analyze and improve their software security posture&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;slimtoolkit&#x2F;slim&quot;&gt;Slim Toolkit&lt;&#x2F;a&gt; - had a massive impact in reducing vulnerabilities at dunnhumby.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hacksplaining.com&#x2F;&quot;&gt;HackSplaining&lt;&#x2F;a&gt; Security training, &quot;Learn to Hack&quot;. In use at ClearBank.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;snyk.io&#x2F;&quot;&gt;Snyk&lt;&#x2F;a&gt; (pronounced &quot;sneak&quot;) - security integrated with CI pipelines&lt;&#x2F;li&gt;
&lt;li&gt;Bug Bounties - good bang for buck, often find privilege escalation at the app level, even for as little as £3k per found vulnerability.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;owasp.org&#x2F;www-project-cornucopia&#x2F;&quot;&gt;OWASP Cornucopia physical card game&lt;&#x2F;a&gt; (also available online - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cornucopia.dotnetlab.eu&#x2F;&quot;&gt;cornucopia online&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OWASP&#x2F;cornucopia&quot;&gt;cornucopia game source code&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.meetup.com&#x2F;OWASP-London&#x2F;&quot;&gt;OWASP London Chapter Meetups&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;ai-llms-chatgpt&quot;&gt;AI, LLMs &amp;amp; ChatGPT&lt;&#x2F;h3&gt;
&lt;p&gt;There are new threats and risks with the new AI tools:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Developers incorrectly using information provided by the LLMs&lt;&#x2F;li&gt;
&lt;li&gt;ChatGPT allows attackers to accelerate, particularly social engineering. E.g. asking ChatGPT for an org chart instead of having to trawl for data manually, then using that in social engineering attacks. This might make it quicker for an attacker to use someone&#x27;s manager&#x27;s name to lend authority.&lt;&#x2F;li&gt;
&lt;li&gt;Developers etc accidentally exfiltrating sensitive data such as private keys and passwords by providing it as inputs to an LLM such as ChatGPT that then integrates the data into its model in a way that allows extraction by a malicious third-party.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Currently use of ChatGPT is blocked at some big companies.&lt;&#x2F;p&gt;
&lt;p&gt;The change to the security landscape is a bit like asking &quot;how did the creation of the internet change theft&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;OWASP has used LLM technology to help make it easier for clients to decide which of the 150 tools they have are most appropriate.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Text-based tools - the ultimate format for everything</title>
        <published>2023-06-01T00:00:00+00:00</published>
        <updated>2023-06-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/06/01/text-based-tools-the-ultimate-format-for-everything/"/>
        <id>https://0x5.uk/2023/06/01/text-based-tools-the-ultimate-format-for-everything/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/06/01/text-based-tools-the-ultimate-format-for-everything/">&lt;p&gt;Having lived in the world of technology for two to three decades now, I&#x27;ve come to a fundamental truth: text formats are &lt;strong&gt;the ultimate&lt;&#x2F;strong&gt; format.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;text formats are &lt;strong&gt;the ultimate&lt;&#x2F;strong&gt; format&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Me, just now&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It&#x27;s funny really because for everything we&#x27;ve invented, of every level of complexity, usability, shinyness etc, when it comes down to it, texts is still king, just like it was in 1980 when I was still learning to talk.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;properties-of-text-formats&quot;&gt;Properties of text formats&lt;&#x2F;h2&gt;
&lt;p&gt;Things that make text inevitably superior to all other more complicated formats:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Simple - &lt;strong&gt;nothing&lt;&#x2F;strong&gt; to go wrong.&lt;&#x2F;li&gt;
&lt;li&gt;Use any text editor you like - vim, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=yzhang.markdown-all-in-one&quot;&gt;vscode+vim&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;plugins.jetbrains.com&#x2F;plugin&#x2F;164-ideavim&quot;&gt;intellij+vim&lt;&#x2F;a&gt; are my gotos, but there are soooo many.&lt;&#x2F;li&gt;
&lt;li&gt;Sync, backup and restore are trivial - try as they might, nothing beats a folder-tree of text files.&lt;&#x2F;li&gt;
&lt;li&gt;They are ultimately portable - no change in technology (windows to linux, desktop to cloud, laptop to mobile) requires you to change anything, text is text, just copy them across and carry on, the ultimate defense against the ever-present pernicious vendor-lockin.&lt;&#x2F;li&gt;
&lt;li&gt;Conflict resolution is always possible - edited two out of sync copies? No problem, there&#x27;s a plethora of tools (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kdiff3.sourceforge.net&#x2F;&quot;&gt;kdiff3&lt;&#x2F;a&gt; is my favourite), or you can just do it manually if you wish.&lt;&#x2F;li&gt;
&lt;li&gt;Version control supported - text files are trivially versionable in tools like git, everything understands it and can show diffs etc.&lt;&#x2F;li&gt;
&lt;li&gt;Simple conventions like markdown, yaml, toml, and even slightly more complicated things like json don&#x27;t fundamentally break any of the above.&lt;&#x2F;li&gt;
&lt;li&gt;With some lightweight processing and structure (noteably markdown), the same basic format can be automatically converted to a plethora of rich and beautiful forms, and with so many tools understanding formats like markdown you are spoilt for choice.&lt;&#x2F;li&gt;
&lt;li&gt;Supports emoji - this one is more modern, but its usefulness is not to be underestimated, and thanks to utf-8 and unicode the plain-old-text-file can have rich emotions and symbols too.&lt;&#x2F;li&gt;
&lt;li&gt;You can use all sorts of interesting tools to process text files, many from the linux cli stack such as &lt;code&gt;sed&lt;&#x2F;code&gt;, &lt;code&gt;grep&lt;&#x2F;code&gt; (or &lt;code&gt;ag&lt;&#x2F;code&gt;), plus full-on shell scripting to automate repetitive tasks &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;timwise.co.uk&#x2F;blob&#x2F;eff17d609f862a14275c4fa0bd8319d13d59574e&#x2F;new&quot;&gt;such as making a new blog post&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;amazing-things-you-can-do-with-text-files&quot;&gt;Amazing things you can do with text files&lt;&#x2F;h2&gt;
&lt;p&gt;The below are all things I personally swear by and use daily. I wish more things were like this.&lt;&#x2F;p&gt;
&lt;p&gt;Markdown is by far my favourite text format, and it&#x27;s incredibly versatile. In my crusade to basically convert everything to plain text &#x2F; markdown files having been repeatedly burnt by fancy binary formats (&lt;code&gt;.doc&lt;&#x2F;code&gt; anyone?). GraphViz (&quot;dot&quot; format) is also a notably powerful text-based system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blogging&quot;&gt;Blogging&lt;&#x2F;h3&gt;
&lt;p&gt;As per this blog, see &lt;a href=&quot;&#x2F;2019&#x2F;06&#x2F;24&#x2F;setting-up-a-jekyll-blog&#x2F;&quot;&gt;&quot;Setting up a static website&#x2F;blog with jekyll&quot;&lt;&#x2F;a&gt; from 2019. No regrets there. Writing this in vim in a terminal.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;slide-decks&quot;&gt;Slide decks&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;reveal-js&quot;&gt;Reveal.js&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;revealjs.com&#x2F;&quot;&gt;reveal.js&lt;&#x2F;a&gt; can parse markdown files with a sprinkling of html &amp;amp; css allowed inline (very handy) and turn them into stunning modern presentations with slick animations and multi-step reveals, amazing.&lt;&#x2F;p&gt;
&lt;p&gt;I was trying to create some slides in google-slides thinking that would be the quick way, ran into some bizarre formatting limitation and went hunting for alternatives. I haven&#x27;t looked back, at least for things I don&#x27;t need real-time collaboration on.&lt;&#x2F;p&gt;
&lt;p&gt;You can see what I managed to do with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rustworkshop.github.io&#x2F;slide-decks&#x2F;&quot;&gt;reveal.js for the Rust Workshop&lt;&#x2F;a&gt; - here&#x27;s one of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rustworkshop&#x2F;slide-decks&#x2F;blob&#x2F;7eb002bfc1431025b47de97fd20e163456b5d7e5&#x2F;decks&#x2F;rust-workshop-master&#x2F;slides.md?plain=1&quot;&gt;source slide markdown files&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;marp&quot;&gt;Marp&lt;&#x2F;h4&gt;
&lt;p&gt;For a simpler setup for markdown slides I&#x27;m now (Jun 2025) using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marp.app&#x2F;&quot;&gt;Marp&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can see my current setup at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;marp-decks&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;marp-decks&lt;&#x2F;a&gt; which auto-published to github pages at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;deck.0x5.uk&#x2F;&quot;&gt;https:&#x2F;&#x2F;deck.0x5.uk&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;note-taking&quot;&gt;Note taking&lt;&#x2F;h3&gt;
&lt;p&gt;Markdown, VSCode with some markdown plugins, maybe even a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=kortina.vscode-markdown-notes&quot;&gt;markdown-wiki&lt;&#x2F;a&gt; tool. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;packages&#x2F;net.gsantner.markor&#x2F;&quot;&gt;Markor&lt;&#x2F;a&gt; on android. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;syncthing.net&#x2F;&quot;&gt;Syncthing&lt;&#x2F;a&gt; to keep them in sync across devices. Works for me, and any conflicts due to editing files out of sync is easier to deal with than &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.gnome.org&#x2F;Apps&#x2F;Tomboy&quot;&gt;tomboy&lt;&#x2F;a&gt;&#x27;s nasty XML format (yes I know XML is text but it&#x27;s still naaaasty).&lt;&#x2F;p&gt;
&lt;p&gt;And for something much fancier, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;logseq.com&#x2F;&quot;&gt;Logseq&lt;&#x2F;a&gt; is a FOSS note-taking app that stores all your notes as markdown and layers on a sqlite index, a great UI, and a ton of plugins.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-pdf-files&quot;&gt;Creating pdf files&lt;&#x2F;h3&gt;
&lt;p&gt;Thanks to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pandoc.org&#x2F;&quot;&gt;pandoc&lt;&#x2F;a&gt; (other tools are available), you can trivially convert your markdown files to pdf files for sharing with people who insist on that as a format.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;pandoc&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-from=gfm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-to=pdf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; html5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;input.md&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;output.pdf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;killer-cv&quot;&gt;Killer CV&lt;&#x2F;h3&gt;
&lt;p&gt;Thanks to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jsonresume.org&#x2F;&quot;&gt;json resume&lt;&#x2F;a&gt; you can create a CV in json (or yml), capturing the pure data, and then run it through a series of theme and formatting engines shared by the community to make something really fab in multiple formats.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;coding&quot;&gt;Coding&lt;&#x2F;h3&gt;
&lt;p&gt;This entry is only half tongue-in-cheek. I think it&#x27;s worth pointing out that programmers have, after flirting with &lt;em&gt;many&lt;&#x2F;em&gt; other approaches, settled on plain old ASCII as being the one-true-format for explaining to a computer (and other programmers) what the computer is supposed to be doing. Pay attention to what programmers have learnt, there is much depth here on managing vast amounts of precise information in text form. Especially if you are not a programmer or not used to text tools there is much to learn from this world. You might think programmers are odd creatures that thrive on unnecessary complexity; nothing could be further from the truth, they (we) are &lt;em&gt;obsessive&lt;&#x2F;em&gt; about solving problems once and for all and being ruthlessly efficient in all things. The fact that programmer practices are seen as odd by the general public is more a sign of just how far programmers have optimised their lives away from the unthinking defaults of the masses than it is of any peculiarity of whim or culture.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;graphs-flowcharts&quot;&gt;Graphs &amp;amp; flowcharts&lt;&#x2F;h3&gt;
&lt;p&gt;There are many formats for rendering diagrams from plain text description&lt;&#x2F;p&gt;
&lt;h4 id=&quot;graphviz-dot&quot;&gt;GraphViz &#x2F; dot&lt;&#x2F;h4&gt;
&lt;p&gt;The GraphViz dot format is amazing, it takes a bit of getting used to, but once you&#x27;ve got it then you can rearrange your flow chart with vim in a few keypresses and have the whole thing rearranged in milliseconds. Amazing.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s even some neat web based real-time renderers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dreampuf.github.io&#x2F;GraphvizOnline&#x2F;&quot;&gt;https:&#x2F;&#x2F;dreampuf.github.io&#x2F;GraphvizOnline&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sketchviz.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;sketchviz.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;mermaid&quot;&gt;Mermaid&lt;&#x2F;h4&gt;
&lt;p&gt;For UML, graphviz and many other formats there is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mermaid.js.org&#x2F;&quot;&gt;mermaid.js&lt;&#x2F;a&gt;, and amazingly you can embed the mermaid formats in markdown and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.github.com&#x2F;en&#x2F;get-started&#x2F;writing-on-github&#x2F;working-with-advanced-formatting&#x2F;creating-diagrams&quot;&gt;github pages will render your mermaid diagrams&lt;&#x2F;a&gt;. Win.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;plantuml&quot;&gt;PlantUML&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;plantuml.com&#x2F;&quot;&gt;PlantUML&lt;&#x2F;a&gt; is a format and renderer for many types of diagrams, including UML obviously.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;christopher-bimson.github.io&#x2F;2025&#x2F;05&#x2F;automating-architecture-diagrams&#x2F;&quot;&gt;Chris Bimpson posted &quot;Automating Architecture Diagrams&quot;&lt;&#x2F;a&gt; which provides a great example of using this in practice, though there are many ways to use this tooling.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;likec4&quot;&gt;LikeC4&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;likec4.dev&#x2F;&quot;&gt;LikeC4&lt;&#x2F;a&gt; is a text based diagram tool that produces an interactive static website with interactive diagrams, multiple views etc. Very good for documenting complicated existing architecture and being able to have a single source of truth viewable at multiple levels of abstraction and angles.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;documenting-things-in-markdown&quot;&gt;Documenting things in markdown&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;It&#x27;s pretty common in developer land to write docs for things in a markdown &lt;code&gt;README.md&lt;&#x2F;code&gt; file (for example the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rustworkshop&#x2F;gitopolis&#x2F;blob&#x2F;main&#x2F;README.md&quot;&gt;gitopolis readme&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Architectural Decision Records (ADRs) are a great format for documenting the reasons for decision, and that works great with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;adr.github.io&#x2F;madr&#x2F;&quot;&gt;Markdown-ADR template &quot;MADR&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-yucky-bits&quot;&gt;The yucky bits&lt;&#x2F;h2&gt;
&lt;p&gt;The almost-rans:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Email&#x27;s mbox format is kinda text, but due to the way it&#x27;s set up is &lt;em&gt;horrible&lt;&#x2F;em&gt; for sync&lt;&#x2F;li&gt;
&lt;li&gt;vcf for contacts, what happened there then?!&lt;&#x2F;li&gt;
&lt;li&gt;ical for calendars, what a disaster, so close but yet never works, shame&lt;&#x2F;li&gt;
&lt;li&gt;XML - nice try, turned out to be horrible in hindsight, but not before we&#x27;d written almost all software to use it (&lt;code&gt;.docx&lt;&#x2F;code&gt; anyone?)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The text world is a bit short on collaborative real-time editing - google-docs is still king on that one, though it would be perfectly possible for equivalent tools to be created for the above text formats and tools. Watch this space.&lt;&#x2F;p&gt;
&lt;p&gt;Crappy half-arsed implementations of markdown, looking at you Jira&#x2F;Confluence&#x2F;Slack (not really a problem of text, more something where we&#x27;re almost there with and then crappy WYSIWIG implementations wreck it).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;links&quot;&gt;Links&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;graydon2.dreamwidth.org&#x2F;193447.html&quot;&gt;&quot;always bet on text&quot; by graydon2&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Maintaining software - a bare minimum</title>
        <published>2023-05-22T00:00:00+00:00</published>
        <updated>2023-05-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/05/22/maintaining-software---a-bare-minimum/"/>
        <id>https://0x5.uk/2023/05/22/maintaining-software---a-bare-minimum/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/05/22/maintaining-software---a-bare-minimum/">&lt;p&gt;All the press goes to new features, but there&#x27;s a lot that has to happen just to stand still in software development.&lt;&#x2F;p&gt;
&lt;p&gt;None of the following results in &quot;shiny new feature that everyone is excited about&quot;. It&#x27;s the ongoing work that anyone who&#x27;s not in day-to-day software development might not appreciate, sometimes questioning where the time is going.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a catalog of things that eat engineering time, but that are eventually unavoidable if you don&#x27;t want to grind to a halt under a mountain of &lt;a href=&quot;&#x2F;2020&#x2F;07&#x2F;09&#x2F;approaches-to-refactoring-and-technical-debt&#x2F;&quot;&gt;tech debt&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;non-feature-work&quot;&gt;Non-feature work&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-bugs&quot;&gt;1) Bugs&lt;&#x2F;h3&gt;
&lt;p&gt;Customers (or your monitoring) notice something that&#x27;s not working:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Investigate and ship a fix,&lt;&#x2F;li&gt;
&lt;li&gt;or worse, spend time investigating only to discover it can&#x27;t &#x2F; won&#x27;t be changed or fixed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;2-minor-dependency-upgrades&quot;&gt;2) Minor dependency upgrades&lt;&#x2F;h3&gt;
&lt;p&gt;e.g. upgrading &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;xunit&quot;&gt;xUnit&lt;&#x2F;a&gt; from &lt;code&gt;v2.4.0&lt;&#x2F;code&gt; to &lt;code&gt;v2.4.2&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These are usually trivial if your tests are good and the authors respect &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;Semantic Versioning&lt;&#x2F;a&gt;. They still need to be done regularly to keep the impact small.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-major-dependency-upgrades&quot;&gt;3) Major dependency upgrades&lt;&#x2F;h3&gt;
&lt;p&gt;e.g. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jbogard&#x2F;MediatR&#x2F;wiki&#x2F;Migration-Guide-9.x-to-10.0&quot;&gt;upgrading MediatR from v9.x to v10.0.0&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;This release includes the following breaking changes in the API ...&quot;&lt;br &#x2F;&gt;
~ MediatR release notes&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;4-platform-upgrades&quot;&gt;4) Platform upgrades&lt;&#x2F;h3&gt;
&lt;p&gt;e.g.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.fastruby.io&#x2F;blog&#x2F;rails&#x2F;upgrades&#x2F;upgrade-rails-from-5-2-to-6-0.html&quot;&gt;Upgrading Rails from 5.2 to 6.0&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;azure-functions&#x2F;migrate-version-3-version-4?tabs=net6-in-proc%2Cazure-cli%2Clinux&amp;amp;pivots=programming-language-csharp&quot;&gt;Migrating apps from Azure Functions version 3.x to version 4.x&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is often significant changes, including removal and changing (sometimes called &quot;breaking&quot; or &quot;breaking changes&quot;) things that your code relies on.&lt;&#x2F;p&gt;
&lt;p&gt;You might be tempted to put these off. Don&#x27;t. The longer you leave it, the worse your problem becomes, eventually becoming insurmountable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;5-fundamental-shifts&quot;&gt;5) Fundamental shifts&lt;&#x2F;h3&gt;
&lt;p&gt;Sometimes there&#x27;s an enormous shift in technology, e.g.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;On-premise compute to cloud compute.&lt;&#x2F;li&gt;
&lt;li&gt;Desktop to mobile.&lt;&#x2F;li&gt;
&lt;li&gt;Server-rendered web to API + Single Page Applications (SPAs).&lt;&#x2F;li&gt;
&lt;li&gt;More recently, the shift from servers to serverless.&lt;&#x2F;li&gt;
&lt;li&gt;Data storage (SQL vs NoSql, vs Graph databases).&lt;&#x2F;li&gt;
&lt;li&gt;New hosting and technology platforms.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you don&#x27;t keep up to date then you find it increasingly hard to operate what you have (no engineers want to work with the old tech, the online world no longer supports you with information and tooling, etc). And your customers expectations start to demand things that your outdated approaches are just unable to support.&lt;&#x2F;p&gt;
&lt;p&gt;Have a plan for regularly considering these and taking action. You might spin up new teams to try them out, or give people &quot;Friday time&quot; to explore new things. The only thing you mustn&#x27;t do is &quot;nothing&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-is-keeping-on-top-of-upgrades-important&quot;&gt;Why is keeping on top of upgrades important?&lt;&#x2F;h2&gt;
&lt;p&gt;Why not just ignore the upgrades till you need them?&lt;&#x2F;p&gt;
&lt;p&gt;Two reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Security fixes&lt;&#x2F;li&gt;
&lt;li&gt;The longer you let it pile up, the harder it gets (exponentially so).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;keeping-changes-small&quot;&gt;Keeping changes small&lt;&#x2F;h2&gt;
&lt;p&gt;If you allow upgrades to pile up for a month or so, you&#x27;ll have one big patch that upgrades many things. If something breaks (even with good test coverage) it can be a lengthy process to figure out which upgrade broke it and what to do about it.&lt;&#x2F;p&gt;
&lt;p&gt;If you do this regularly (weekly at least), then you&#x27;ll only be upgrading a few minor versions at a time, and it will be immediately obvious where to start looking if something breaks (i.e. roll back, then upgrade the 5 dependencies one at a time, and look at the changelog of the one that breaks it.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-coverage&quot;&gt;Test coverage&lt;&#x2F;h2&gt;
&lt;p&gt;Upgrades are a key reason that good test coverage (and the functionality level) are very important. Without these you will have a significant manual testing effort for every upgrade. Relying on manual testing results in avoiding upgrades for longer, and breakages making it to production unnoticed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;monitoring&quot;&gt;Monitoring&lt;&#x2F;h2&gt;
&lt;p&gt;Good exception monitoring and telemetry in production will improve your ability to catch any oddities that slip through your test coverage.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Zero-downtime website rewrite migrations</title>
        <published>2023-05-22T00:00:00+00:00</published>
        <updated>2023-05-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/05/22/zero-downtime-website-rewrite-migrations/"/>
        <id>https://0x5.uk/2023/05/22/zero-downtime-website-rewrite-migrations/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/05/22/zero-downtime-website-rewrite-migrations/">&lt;p&gt;As we know, big-bang rewrites are incredibly dangerous. They are likely to fail or be rejected. For example, the new thing never reaches &quot;feature parity&quot; and gets rejected in favour of the system you were trying to replace.&lt;&#x2F;p&gt;
&lt;p&gt;But how do you practically avoid it? If it&#x27;s one website on one domain then that seems irreducible. Right?&lt;&#x2F;p&gt;
&lt;p&gt;But there is a way.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-change-looms&quot;&gt;A change looms&lt;&#x2F;h2&gt;
&lt;p&gt;You need to change the technology for your website for some reason.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps your &lt;a href=&quot;&#x2F;2020&#x2F;07&#x2F;09&#x2F;approaches-to-refactoring-and-technical-debt&#x2F;&quot;&gt;tech debt&lt;&#x2F;a&gt; is out of control and you basically need to do a complete rewrite from scratch, perhaps you&#x27;ve decided to switch technology.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps you have decided to move everything in your company to a different tech stack.&lt;&#x2F;p&gt;
&lt;p&gt;Either way you are making a BIG change to your technology. Out with the old, in with the new.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-c-to-rails-migration-at-dfe&quot;&gt;A C# to Rails migration at DfE&lt;&#x2F;h3&gt;
&lt;p&gt;I was lucky enough to be involved in a technology shift at the Department for Education (UK) with some exceptionally talented people. I&#x27;d been part of a team creating an MVP (Minimal Viable Product) in C# with a couple of web front ends and a postgres database (yay no sql server!). The department then decided to shift wholesale to Ruby on Rails (for good reasons, but they are not important here).&lt;&#x2F;p&gt;
&lt;p&gt;The approach taken was superb, went really well, and is well worth learning from, I&#x27;ll outline it here for the benefit of all. It was inspired by a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;insidegovuk.blog.gov.uk&#x2F;2016&#x2F;07&#x2F;29&#x2F;the-specialist-publisher-rebuild-behind-the-scenes&#x2F;&quot;&gt;previous rewrite at gov.uk&lt;&#x2F;a&gt; as we were lucky enough to have fabulous people on the team who&#x27;d been involved in that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-seamlessly-migrate&quot;&gt;How to seamlessly migrate&lt;&#x2F;h2&gt;
&lt;p&gt;What&#x27;s unsurprising here is that you spin up a new web service in your new technology, or with your new way of doing things.&lt;&#x2F;p&gt;
&lt;p&gt;There are two simple key elements that allow a seamless piece-by-piece migration:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;HTTP redirects in both directions&lt;&#x2F;li&gt;
&lt;li&gt;Shared state&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;These two allow you to build a new service, one tiny piece of functionality at a time, and immediately put them into production, retiring the legacy version of that feature immediately.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bi-directional-http-redirects&quot;&gt;Bi-directional HTTP redirects&lt;&#x2F;h2&gt;
&lt;p&gt;It goes as follow:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Chose one feature to build in the new technology&lt;&#x2F;li&gt;
&lt;li&gt;Spin up the new service on a similar subdomain (e.g. &quot;&lt;code&gt;www2.example.org&lt;&#x2F;code&gt;&quot; next to the legacy &quot;&lt;code&gt;www.example.org&lt;&#x2F;code&gt;&quot;)&lt;&#x2F;li&gt;
&lt;li&gt;In the new service, redirect all routes that are not yet implemented to the legacy domain&lt;&#x2F;li&gt;
&lt;li&gt;In the legacy service redirect the single route for the chosen feature to the new service.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Now users will seamlessly transition in and out of the new service as they click around the site.&lt;&#x2F;p&gt;
&lt;p&gt;This is genius and I wish I could say I thought of it myself!&lt;&#x2F;p&gt;
&lt;p&gt;Repeat until all desired features are on the new service and the legacy service can be turned off.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shared-state&quot;&gt;Shared state&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s obviously important that if a user does something on the new system that it is immediately reflected in the state on the legacy system. For us this meant shared access to the postgresql database. The exact method probably isn&#x27;t that important so long as you can get it to be seamless.&lt;&#x2F;p&gt;
&lt;p&gt;Whatever your state store is, it&#x27;s important to &quot;freeze&quot; schema changes while you do the transition (within reason) so that you avoid the overhead of updating both system&#x27;s understanding of the storage schema.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;no-more-legacy&quot;&gt;No more legacy&lt;&#x2F;h2&gt;
&lt;p&gt;This will go smoother if you observe the cardinal rule of rewrites: no new functionality can be added to the legacy system. Any changes and fixes must be postponed or made on the new service.&lt;&#x2F;p&gt;
&lt;p&gt;This is to avoid the trap where the old system keeps being improved and the new system can never catch up. It also prevents your time and resources being invested in something that you plan to delete.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;While it’s tempting to add new features to Specialist Publisher right now, we need to concentrate on rewriting and integrating with the Publishing Platform. ... We don’t want to run two versions of Specialist Publisher concurrently for very long as it risks creating confusion, so we’ll deprioritise product requests until the rebuild is complete.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;insidegovuk.blog.gov.uk&#x2F;2016&#x2F;07&#x2F;29&#x2F;the-specialist-publisher-rebuild-behind-the-scenes&#x2F;#:~:text=while%20it%E2%80%99s%20tempting%20to%20add%20new%20features%20to%20specialist%20publisher%20right%20now%2C%20we%20need%20to%20concentrate%20on%20rewriting%20and%20integrating%20with%20the%20publishing%20platform.%20&quot;&gt;Jen Allum, Inside GOV.UK, 2016&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The only exception to this is whatever changes are needed to support the seamless user experience across the two services. Notably the redirections.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;monitoring&quot;&gt;Monitoring&lt;&#x2F;h2&gt;
&lt;p&gt;As you migrate your tech, keep an eye on your telemetry, error reporting and anything else you have to make sure your user experience remains good throughout.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pattern-name-strangler-fig&quot;&gt;Pattern name: Strangler Fig&lt;&#x2F;h2&gt;
&lt;p&gt;This approach is known as the &quot;strangler fig&quot; pattern.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;An alternative route is to gradually create a new system around the edges of the old, letting it grow slowly over several years until the old system is strangled. Doing this sounds hard, but increasingly I think it&#x27;s one of those things that isn&#x27;t tried enough&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Martin Fowler&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;martinfowler.com&#x2F;bliki&#x2F;StranglerFigApplication.html&quot;&gt;https:&#x2F;&#x2F;martinfowler.com&#x2F;bliki&#x2F;StranglerFigApplication.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;See also&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;architecture&#x2F;microservices&#x2F;design&#x2F;patterns&quot;&gt;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;architecture&#x2F;microservices&#x2F;design&#x2F;patterns&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freecodecamp.org&#x2F;news&#x2F;what-is-the-strangler-pattern-in-software-development&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.freecodecamp.org&#x2F;news&#x2F;what-is-the-strangler-pattern-in-software-development&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-end&quot;&gt;The end&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s not much more to say on this. It&#x27;s a simple concept that packs a huge punch. If you&#x27;re thinking of modernising a web stack, or changing tech, I would 100% recommend this approach. The risks of failure are so much lower.&lt;&#x2F;p&gt;
&lt;p&gt;Many thanks to those who I worked with showed the way.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Website builders for non-programmers</title>
        <published>2023-05-04T00:00:00+00:00</published>
        <updated>2023-05-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/05/04/website-builders-for-non-programmers/"/>
        <id>https://0x5.uk/2023/05/04/website-builders-for-non-programmers/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/05/04/website-builders-for-non-programmers/">&lt;p&gt;Here&#x27;s some tools that you can use if you&#x27;re not a coder but want to put up a website.&lt;&#x2F;p&gt;
&lt;p&gt;I do custom coding, but sometimes non-technical folk ask me how to build a website, so here&#x27;s a list of tools that allow you to create a site without having to know how to code.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;webflow.com&#x2F;&quot;&gt;webflow.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.notion.so&#x2F;help&#x2F;guides&#x2F;build-a-website-with-notion-in-seconds-no-coding-required&quot;&gt;Notion as a website builder&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bricksbuilder.io&#x2F;&quot;&gt;bricksbuilder.io&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.brixbuilder.com&#x2F;&quot;&gt;brixbuilder.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.squarespace.com&#x2F;&quot;&gt;squarespace.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.weebly.com&#x2F;&quot;&gt;weebly.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wordpress.com&#x2F;&quot;&gt;wordpress.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;2019&#x2F;06&#x2F;24&#x2F;setting-up-a-jekyll-blog&#x2F;&quot;&gt;Jekyll + github pages&lt;&#x2F;a&gt; if you&#x27;re feeling a bit brave&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.wix.com&#x2F;&quot;&gt;Wix&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;neocities.org&#x2F;&quot;&gt;neocities.org&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Hope that&#x27;s helpful, they aren&#x27;t in any particular order of preference so try them out and see what works for you.&lt;&#x2F;p&gt;
&lt;p&gt;If you find others that should be on here then please drop me an email and I&#x27;ll add any suggestions.&lt;&#x2F;p&gt;
&lt;p&gt;If you found this useful then go ahead and share with anyone else who you think might find this useful.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Always Add Argument (Parameter) Names</title>
        <published>2023-04-18T00:00:00+00:00</published>
        <updated>2023-04-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/04/18/always-add-argument-names/"/>
        <id>https://0x5.uk/2023/04/18/always-add-argument-names/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/04/18/always-add-argument-names/">&lt;p&gt;An argument (lol) for the use of explicit argument names in C# function calls even when they seem redundant.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;You can assert correctness when reviewing the call site in a dumb text display (e.g. a patch in a github pull request)&lt;&#x2F;li&gt;
&lt;li&gt;Parameter-order refactoring won&#x27;t introduce subtle bugs and breaking changes.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This is particularly important when you have multiple arguments of the same type.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s also a good idea when the call doesn&#x27;t immediately make it obvious what the meaning of the parameter is. E.g. &lt;code&gt;Foo(3)&lt;&#x2F;code&gt; vs &lt;code&gt;Foo(sizeInMeters: 3)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;no-argument-names-bad&quot;&gt;No argument names (bad)&lt;&#x2F;h2&gt;
&lt;p&gt;Starting point:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Home&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Blah&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; don&amp;#39;t do this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; importantThing&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; otherThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;	switch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;importantThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Home&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;			DoSomething&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;			DoSomethingElse&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;otherThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If &lt;code&gt;Foo()&lt;&#x2F;code&gt; is defined in a different file it&#x27;s hard to eyeball &lt;code&gt;Main()&lt;&#x2F;code&gt; and tell if the arguments line up properly.&lt;&#x2F;p&gt;
&lt;p&gt;If I now re-order the arguments of &lt;code&gt;Foo()&lt;&#x2F;code&gt; can you easily spot that the call site in &lt;code&gt;Main()&lt;&#x2F;code&gt; is now incorrect?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Home&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Blah&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; Now broken!! But can you tell?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; otherThing&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; importantThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &amp;lt;-- parameters flipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;	switch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;importantThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Home&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;			DoSomething&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;			DoSomethingElse&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;otherThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;with-argument-names-good&quot;&gt;With argument names (good)&lt;&#x2F;h2&gt;
&lt;p&gt;Starting point:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;importantThing&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Home&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; otherThing&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Blah&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; importantThing&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; otherThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;	switch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;importantThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Home&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;			DoSomething&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;			DoSomethingElse&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;otherThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can now easily see that &lt;code&gt;&quot;Home&quot;&lt;&#x2F;code&gt; is going to &lt;code&gt;&quot;importantThing&quot;&lt;&#x2F;code&gt;, even in a plain-text view of the file.&lt;&#x2F;p&gt;
&lt;p&gt;If I now re-order the arguments of &lt;code&gt;Foo()&lt;&#x2F;code&gt; again, it &lt;em&gt;doesn&#x27;t&lt;&#x2F;em&gt; break because the compiler knows which string to connect to which parameter. Win.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;importantThing&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Home&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; otherThing&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Blah&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; still valid!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; otherThing&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; importantThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; &amp;lt;-- refactored&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;	switch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;importantThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Home&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;			DoSomething&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;			DoSomethingElse&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;otherThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;making-wrong-code-look-wrong&quot;&gt;Making Wrong Code Look Wrong&lt;&#x2F;h2&gt;
&lt;p&gt;This piece of code-style opinion falls under &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2005&#x2F;05&#x2F;11&#x2F;making-wrong-code-look-wrong&#x2F;&quot;&gt;Making Wrong Code Look Wrong&lt;&#x2F;a&gt;&quot; as Joel Spolsky teaches.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-types&quot;&gt;Using types&lt;&#x2F;h2&gt;
&lt;p&gt;Having many parameters of the same types can be a code smell that it&#x27;s time to move to stronger typing.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s two ways you can do this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create a wrapper type for all the data you need and only have one parameter of that type.&lt;&#x2F;li&gt;
&lt;li&gt;Create meaningful types that wrap primitive types and pass those instead so that the compiler will check the right type of thing is going in as the right argument.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;E.g. this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; importantThing&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; otherThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;becomes&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;SomeThings&lt;&#x2F;span&gt;&lt;span&gt; things&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;or&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;ImportantThing&lt;&#x2F;span&gt;&lt;span&gt; importantThing&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; OtherThing&lt;&#x2F;span&gt;&lt;span&gt; otherThing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Thus making the arguments impossible to mix up through being out of order.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;primitive-obsession&quot;&gt;Primitive Obsession&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s also worth noting that lack of such custom types is an example of the coding smell &#x2F; anti-pattern &quot;primitive obsession&quot;, which is where there is insufficient use of the ability to create and use a richer type system than that supplied by the language.&lt;&#x2F;p&gt;
&lt;p&gt;Learn more about primitive obsession in these article:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.ploeh.dk&#x2F;2011&#x2F;05&#x2F;25&#x2F;DesignSmellPrimitiveObsession&#x2F;&quot;&gt;https:&#x2F;&#x2F;blog.ploeh.dk&#x2F;2011&#x2F;05&#x2F;25&#x2F;DesignSmellPrimitiveObsession&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;grabbagoft.blogspot.com&#x2F;2007&#x2F;12&#x2F;dealing-with-primitive-obsession.html&quot;&gt;http:&#x2F;&#x2F;grabbagoft.blogspot.com&#x2F;2007&#x2F;12&#x2F;dealing-with-primitive-obsession.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freecodecamp.org&#x2F;news&#x2F;what-is-primitive-obsession&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.freecodecamp.org&#x2F;news&#x2F;what-is-primitive-obsession&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackernoon.com&#x2F;what-is-primitive-obsession-and-how-can-we-fix-it-wh2f33ki&quot;&gt;https:&#x2F;&#x2F;hackernoon.com&#x2F;what-is-primitive-obsession-and-how-can-we-fix-it-wh2f33ki&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;20601009&#x2F;when-are-named-arguments-useful&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;20601009&#x2F;when-are-named-arguments-useful&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.howtocodeit.com&#x2F;articles&#x2F;ultimate-guide-rust-newtypes&quot;&gt;https:&#x2F;&#x2F;www.howtocodeit.com&#x2F;articles&#x2F;ultimate-guide-rust-newtypes&lt;&#x2F;a&gt; - this is in Rust but a good example of creating type wrappers to avoid primitive obsession and eliminate many parameter ordering issues&lt;&#x2F;li&gt;
&lt;li&gt;Sadly my new favourite language &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rfcs&#x2F;issues&#x2F;323&quot;&gt;Rust does not support named args&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The trap of two-stage commitments</title>
        <published>2023-04-06T00:00:00+00:00</published>
        <updated>2023-04-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/04/06/the-trap-of-two-stage-commitments/"/>
        <id>https://0x5.uk/2023/04/06/the-trap-of-two-stage-commitments/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/04/06/the-trap-of-two-stage-commitments/">&lt;p&gt;When you know there is a future time at which you&#x27;ll have to &quot;really commit&quot; (e.g. sign something, put money down, put something in writing, commit publicly etc.) it&#x27;s easy to blasély commit without thinking too hard about how things might have changed by the time the more concrete commitment is needed, or perhaps if you even really mean it. This is a trap!&lt;&#x2F;p&gt;
&lt;p&gt;There is an unspoken mismatch in understanding of what was just casually agreed:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The person saying &quot;yes&quot; is often implicitly saying &quot;assuming when actual commitment time comes this is still a valid choice&quot;, (consciously or unconsciously thinking to themselves &quot;I can review this nearer the time and change my mind if needs be&quot;).&lt;&#x2F;li&gt;
&lt;li&gt;The person hearing &quot;yes&quot;, however carelessly given, is potentially hearing nothing but the &quot;yes&quot; and understandably thinks they can count on that regardless of further hurdles and levels of commitment.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The danger here is that even if you truly believed you could keep your word, circumstances can change, for example between verbal and written agreements, or between saying &quot;I&#x27;ll visit&quot; and actually booking flights. Money issues, health, behaviour of others and many other things out of your control can get in the way.&lt;&#x2F;p&gt;
&lt;p&gt;I like to think I stick to my word, and that if I say I&#x27;ll do something then I&#x27;ll do it. I make an effort to think through whether I would or wouldn&#x27;t do something before saying yes. What I have missed in my thinking sometimes is that &lt;strong&gt;things change&lt;&#x2F;strong&gt;, and I should be more reserved when answering the initial query. If circumstances don&#x27;t change there would be no issue, but if they do then one can be in hot water.&lt;&#x2F;p&gt;
&lt;p&gt;On the first commitment it all seems kind of vague and far off, but on the second one it&#x27;s very real, and you might realize you no longer want to honour your commitment for some reason, and now you are in a bad place of either breaking your commitment or violating your boundaries (if you can keep it at all).&lt;&#x2F;p&gt;
&lt;p&gt;The bias towards blindly saying yes and then regretting it all stems from being a &quot;people pleaser&quot; at heart, which probably goes back to ingrained behaviours learned in childhood. Wanting to give the &quot;right&quot; answer in the moment, even if the moment isn&#x27;t right.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with being to quick with a &quot;yes&quot; to please someone is that by the time you have to &quot;actually commit&quot;, circumstances may have changed, and you may be looking for a way out.&lt;&#x2F;p&gt;
&lt;p&gt;There isn&#x27;t one answer to the challenge of two-stage commitments, but here are some ways to handle that initial commitment question:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Be more circumspect in initial response, e.g. &quot;well maybe, let&#x27;s see how it looks when the paperwork arrives&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Buy time: &quot;can I get back to you on that?&lt;&#x2F;li&gt;
&lt;li&gt;Defer: &quot;interesting, let me know when you have something more concrete&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Say no - maybe it was never going to be right and you could have figured that out right away.&lt;&#x2F;li&gt;
&lt;li&gt;Say yes, but be damn sure you&#x27;re going to stick to it as if it was written in blood.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I hope reading this helps you. Writing it has helped me clarify my thinking around this tricky bit of human interaction.&lt;&#x2F;p&gt;
&lt;p&gt;If you have trouble with this kind of thing then definitely check out &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Untamed-Stop-pleasing-start-living-ebook&#x2F;dp&#x2F;B082K7QXRQ&quot;&gt;Untamed by Glennon Doyle&lt;&#x2F;a&gt;, she has lots to say on setting boundaries.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Importing Slashdot Journal Articles by Yak</title>
        <published>2023-03-29T00:00:00+00:00</published>
        <updated>2023-03-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2023/03/29/importing-slashdot-journal-articles-by-yak/"/>
        <id>https://0x5.uk/2023/03/29/importing-slashdot-journal-articles-by-yak/</id>
        
        <content type="html" xml:base="https://0x5.uk/2023/03/29/importing-slashdot-journal-articles-by-yak/">&lt;p&gt;I&#x27;ve imported all my old slashdot journal articles because:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;posterity&lt;&#x2F;li&gt;
&lt;li&gt;I like the fact I&#x27;ve been writing on the internet for so long and I want my domain to show it&lt;&#x2F;li&gt;
&lt;li&gt;there&#x27;s something to be said for keeping your own writing on your own domain and not someone else&#x27;s&lt;&#x2F;li&gt;
&lt;li&gt;because I can.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It turns out that although slashdot has an export feature, it doesn&#x27;t include the journal entries. Let the yak-shaving begin.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-worked&quot;&gt;What worked&lt;&#x2F;h2&gt;
&lt;p&gt;Use wget to download all the paginated lists of posts into html files. (I forget whether I looped this or got wget to spider it, either would work).&lt;&#x2F;p&gt;
&lt;p&gt;Parse paginated list of posts to get individual post urls into file &lt;code&gt;urls.txt&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;bin&#x2F;sh -v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; urls.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;for&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; page&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;g&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;h&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;l&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;    xidel&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;page&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-xquery&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;for $var in &#x2F;&#x2F;article return $var&#x2F;&#x2F;span[@class=&amp;quot;story-title&amp;quot;]&#x2F;&#x2F;a[@rel]&#x2F;@href&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; urls.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Loop through those urls downloading the individual post pages&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;bin&#x2F;bash -v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; posts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; posts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;while&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; url&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;url&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;    file&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;https&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;slashdot&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;org&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;journal&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;    file2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;file&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.html&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;file2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;    curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;file2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;done&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; ..&#x2F;urls.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Parse the downloaded files, transforming them into individual markdown files:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;!&#x2F;usr&#x2F;bin&#x2F;env ruby&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;nokogiri&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;date&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;Dir&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;glob&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;posts&#x2F;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;each&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;    puts&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    doc&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; File&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;input&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;f&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; Nokogiri&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6C71C4, #6C71C4);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;HTML&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    doc&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;css&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;article[data-fhtype=&amp;#39;journal&amp;#39;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;each&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;at_css&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.story-title a[rel]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;attribute&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;href&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;text&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        date&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; Date&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;at_css&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;time&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;text&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        outfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; date&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;to_s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;-slashdot-journal-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; url&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;gsub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.md&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;        puts&lt;&#x2F;span&gt;&lt;span&gt; outfile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;        File&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;out&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; outfile&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;w&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;out&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;---&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;title: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;at_css&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.story-title a[rel]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;date: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; date&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;to_s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;slashdot_url: https:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; url&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;---&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;css&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;div[class=body] div[class=p]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;each&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; p&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;inner_html&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;strip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;            end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;    end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;exploration-with-nokogiri&quot;&gt;Exploration with nokogiri&lt;&#x2F;h2&gt;
&lt;p&gt;Once you have an html file on disk you can explore the in-memory model interactively with &lt;code&gt;irb&lt;&#x2F;code&gt;, which helps iterate on scripts like the above more rapidly.&lt;&#x2F;p&gt;
&lt;p&gt;E.g.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ irb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;irb&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;001&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; doc &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; File&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;page-0.html&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;f&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; Nokogiri&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6C71C4, #6C71C4);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;XML&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;irb&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;002&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; doc&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;css&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;article[data-fhtype=&amp;#39;journal&amp;#39;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;each&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; puts&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;---&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;title: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;at_css&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.story-title&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;text&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;time: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;at_css&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;time&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;text&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;---&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B58900, #B58900);&quot;&gt;nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;dead-ends-explored&quot;&gt;Dead-ends explored&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sibprogrammer&#x2F;xq&quot;&gt;xq&lt;&#x2F;a&gt; - doesn&#x27;t seem to provide a rich enough expression to pick bits out of html and stitch them back together in interesting ways, more of a tool for capturing better structured data.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;benibela&#x2F;xidel&quot;&gt;xidel&lt;&#x2F;a&gt; - can do xquery not just xpath, got further with this but not far enough&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;wget&lt;&#x2F;code&gt;&#x27;ing the paginated list of posts - for some reason this resulted in repeated content when parsed with nokogiri&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;wget&lt;&#x2F;code&gt;&#x27;ing individual post pages - suspected manipulation of html, so dropped down to &lt;code&gt;curl&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Example of xquery in action: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;5987474&#x2F;return-multiple-data-elements&#x2F;5993577#5993577&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;5987474&#x2F;return-multiple-data-elements&#x2F;5993577#5993577&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Using xidel for parsing html: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;21015587&#x2F;get-content-between-a-pair-of-html-tags-using-bash&#x2F;21026668#21026668&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;21015587&#x2F;get-content-between-a-pair-of-html-tags-using-bash&#x2F;21026668#21026668&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;XQuery intro: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3schools.com&#x2F;xml&#x2F;xquery_intro.asp&quot;&gt;https:&#x2F;&#x2F;www.w3schools.com&#x2F;xml&#x2F;xquery_intro.asp&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Using nokogiri for parsing, official docs: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nokogiri.org&#x2F;#parsing-and-querying&quot;&gt;https:&#x2F;&#x2F;nokogiri.org&#x2F;#parsing-and-querying&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Parsing with nokogiri: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nokogiri.org&#x2F;tutorials&#x2F;parsing_an_html_xml_document.html&quot;&gt;https:&#x2F;&#x2F;nokogiri.org&#x2F;tutorials&#x2F;parsing_an_html_xml_document.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;carolineartz&#x2F;10276637&quot;&gt;Nokogiri cheatsheet gist&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Scraping with nokogiri walkthrough: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dev.to&#x2F;kreopelle&#x2F;nokogiri-scraping-walkthrough-alk&quot;&gt;https:&#x2F;&#x2F;dev.to&#x2F;kreopelle&#x2F;nokogiri-scraping-walkthrough-alk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Globbing files in ruby: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;7677410&#x2F;how-do-i-get-a-listing-of-only-files-using-dir-glob&#x2F;7677543#7677543&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;7677410&#x2F;how-do-i-get-a-listing-of-only-files-using-dir-glob&#x2F;7677543#7677543&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Looping through file lines in ruby: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;1521462&#x2F;looping-through-the-content-of-a-file-in-bash&#x2F;1521498#1521498&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;1521462&#x2F;looping-through-the-content-of-a-file-in-bash&#x2F;1521498#1521498&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;String replacement in bash: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linuxhandbook.com&#x2F;replace-string-bash&#x2F;&quot;&gt;https:&#x2F;&#x2F;linuxhandbook.com&#x2F;replace-string-bash&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Parsing odd date formats with ruby: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;11617410&#x2F;parse-date-string-in-ruby&#x2F;11617505#11617505&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;11617410&#x2F;parse-date-string-in-ruby&#x2F;11617505#11617505&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Finding a contractor accountants</title>
        <published>2022-11-11T00:00:00+00:00</published>
        <updated>2022-11-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/11/11/finding-a-contractor-accountants/"/>
        <id>https://0x5.uk/2022/11/11/finding-a-contractor-accountants/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/11/11/finding-a-contractor-accountants/">&lt;p&gt;Boring but important, having an accountant firm to make sure the books are HMRC-proof is important.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t know why but I&#x27;ve found it hard to pick good ones, and harder than I expected to find, research and choose a firm.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;things-that-you-need-to-keep-in-mind&quot;&gt;Things that you need to keep in mind&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Business insurance (professional indemnity etc), often bundled but needs to happen&lt;&#x2F;li&gt;
&lt;li&gt;Accountancy software - some use their own but that makes moving firms harder, so I&#x27;d use something separate. Some accountants bundle the fee.
&lt;ul&gt;
&lt;li&gt;Xero - works but not very useable, seems to be built around ye-olde accountancy practices rather than what&#x27;s easy to use.&lt;&#x2F;li&gt;
&lt;li&gt;FreeAgent - much more useable, good enough for a contracting business&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Company registration (if you&#x27;re just starting), some accountants will do it for you, or you can &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gov.uk&#x2F;topic&#x2F;company-registration-filing&#x2F;starting-company&quot;&gt;set a company up yourself&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;things-your-accountants-can-should-do-for-you&quot;&gt;Things your accountants can&#x2F;should do for you&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Submit yearly accounts to companies house&lt;&#x2F;li&gt;
&lt;li&gt;Help you set tax efficient salary&lt;&#x2F;li&gt;
&lt;li&gt;Make sure your accounts in freeagent are accurate&lt;&#x2F;li&gt;
&lt;li&gt;Help you understand your P&amp;amp;L (profit and loss)&lt;&#x2F;li&gt;
&lt;li&gt;Submit your vat returns, and help you make sure it&#x27;s right&lt;&#x2F;li&gt;
&lt;li&gt;Personal tax return prep (plus spouse), some charge extra&lt;&#x2F;li&gt;
&lt;li&gt;Make sure you&#x27;re claiming the correct expenses, notably home-office allowance&lt;&#x2F;li&gt;
&lt;li&gt;Check your accounts are in line with current laws and tax laws.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;additional-services&quot;&gt;Additional services&lt;&#x2F;h2&gt;
&lt;p&gt;Some also will do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bundled FreeAgent subscription&lt;&#x2F;li&gt;
&lt;li&gt;Company setup&lt;&#x2F;li&gt;
&lt;li&gt;Umbrella company stuff&lt;&#x2F;li&gt;
&lt;li&gt;IR35 assessment&#x2F;protection&lt;&#x2F;li&gt;
&lt;li&gt;IPSE membership&lt;&#x2F;li&gt;
&lt;li&gt;Provide a registered address to use that&#x27;s not your home, and forward any mail&lt;&#x2F;li&gt;
&lt;li&gt;Business insurance&lt;&#x2F;li&gt;
&lt;li&gt;Registered company address&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;contract-accountant-list-reviews&quot;&gt;Contract accountant list &amp;amp; reviews&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve asked around my network and these are the ones I&#x27;ve gathered so far. I&#x27;ve put them in a table, added links to trustpilot reviews and made a note of current (at time of writing) review scores and counts to help decide.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;airtable.com&#x2F;shrRhSa7ZFHt1o6Bx&quot;&gt;Airtable of contract accountants&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;iframe class=&quot;airtable-embed&quot; src=&quot;https:&#x2F;&#x2F;airtable.com&#x2F;embed&#x2F;shr3L59pAzDxaDES4?backgroundColor=cyan&amp;viewControls=on&quot; frameborder=&quot;0&quot; onmousewheel=&quot;&quot; width=&quot;100%&quot; height=&quot;533&quot; style=&quot;background: transparent; border: 1px solid #ccc;&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;tim_abell&#x2F;status&#x2F;1591194541797040128&quot;&gt;Asking on twitter&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;posts&#x2F;timabell_any-suggestions-for-a-better-accountancy-activity-6851550397241290752-JRBl&#x2F;&quot;&gt;Asking on LinkedIn&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;feed&#x2F;update&#x2F;urn:li:activity:6985724333893591042&#x2F;&quot;&gt;Asking on contractor LinkedIn group&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exceptions vs Wrapper Return Types</title>
        <published>2022-11-10T00:00:00+00:00</published>
        <updated>2022-11-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/11/10/exceptions-vs-wrapper-return-types/"/>
        <id>https://0x5.uk/2022/11/10/exceptions-vs-wrapper-return-types/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/11/10/exceptions-vs-wrapper-return-types/">&lt;h2 id=&quot;the-possibilities&quot;&gt;The possibilities&lt;&#x2F;h2&gt;
&lt;p&gt;Here are two ways you can deal with something going wrong in your code in C#:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;exceptions&quot;&gt;Exceptions&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; GetAnswer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;someDependency&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;HasWhatWeNeed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B58900, #B58900);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		throw&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;someDependency didn&amp;#39;t supply what we needed&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; someDependency&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Something&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;returning-failure&quot;&gt;Returning failure&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; GetAnswer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;someDependency&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;HasWhatWeNeed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B58900, #B58900);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;someDependency didn&amp;#39;t supply what we needed&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;someDependency&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Something&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;	public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; readonly&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; T&lt;&#x2F;span&gt;&lt;span&gt; Value&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;	public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; readonly&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; Error&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;	public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt; value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;	public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; error&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(This is just a stub example of Result to illustrate what I&#x27;m talking about. A real Result type would need more a bit more thought than this. You could potentially use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mcintyre321&#x2F;OneOf&quot;&gt;OneOf&lt;&#x2F;a&gt; for your error return types.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;context&quot;&gt;Context&lt;&#x2F;h2&gt;
&lt;p&gt;For most of C#&#x27;s life as a language exceptions have been a pretty normal way of getting things done.&lt;&#x2F;p&gt;
&lt;p&gt;For a web system, it&#x27;s a common pattern to throw any time things aren&#x27;t in place to proceed for any reason, and then have a broad catch in middleware that turns it into a sensible 500 exception and logs the exception to somewhere for troubleshooting.&lt;&#x2F;p&gt;
&lt;p&gt;Meanwhile other languages and paradigms have been learning from the real-world challenges of this approach and have been downplaying the role of exceptions for normal coding. In golang multiple-returns are used, with panic reserved for truly irrecoverable problems (e.g. out of disk space). In Rust normal error handling is done with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dev.to&#x2F;cthutu&#x2F;rust-3-options-results-and-errors-part-1-4d52&quot;&gt;Options and Result types&lt;&#x2F;a&gt;, and again has a less commonly used panic capability for catastrophic situations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pros-and-cons&quot;&gt;Pros and Cons&lt;&#x2F;h2&gt;
&lt;p&gt;Specifically within C# here&#x27;s the reasons that would push you to chose one or the other approach:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;exceptions-1&quot;&gt;Exceptions&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;in-favour-of-exceptions&quot;&gt;In favour of exceptions&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Minimal code required&lt;&#x2F;li&gt;
&lt;li&gt;Includes stack trace by default&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;against-exceptions&quot;&gt;Against exceptions&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;More expensive than normal control of flow.&lt;&#x2F;li&gt;
&lt;li&gt;It is not possible to tell from looking at the GetAnswer() function signature whether the programmer expected this to fail under any circumstances, or whether it&#x27;s something that can be relied on.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;error-return-types&quot;&gt;Error Return types&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;in-favour-of-error-return-types&quot;&gt;In favour of Error return types&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Clear indication to reader that the author knew that this function could fail under known circumstances.&lt;&#x2F;li&gt;
&lt;li&gt;In the long run systems that rely heavily on exceptions eventually become a losing battle of endless exceptions in logs that never truly get dealt with and you can&#x27;t tell the catastrophic urgent ones apart from the run-of-the-mill bearable problems. (I&#x27;m thinking support of production web systems here)&lt;&#x2F;li&gt;
&lt;li&gt;Forces a more thoughtful approach to failure modes of the system.&lt;&#x2F;li&gt;
&lt;li&gt;Marginal performance gain - only relevant for hot-path areas, trivial compared to optimising database&#x2F;network&#x2F;io areas.&lt;&#x2F;li&gt;
&lt;li&gt;Expression of intent: by throwing an exception the programmer is indicating &quot;I never expected this to happen!!&quot;, by using an error return the programmer is saying &quot;I know this can happen, but I can&#x27;t carry on and the caller needs to deal with it.&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;against-error-return-types&quot;&gt;Against Error return types&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;More boilerplate code (because C# doesn&#x27;t support this natively like Rust does)&lt;&#x2F;li&gt;
&lt;li&gt;Need to explain pattern to C# programmers who are used to relying on Exceptions&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;how-to-choose&quot;&gt;How to choose&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;web-systems-microservices&quot;&gt;Web systems &amp;amp; microservices&lt;&#x2F;h3&gt;
&lt;p&gt;An illustrative example is a microservice having to handle being misconfigured:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if all is well the system will be configured correctly&lt;&#x2F;li&gt;
&lt;li&gt;misconfiguration can cause a system to fail&lt;&#x2F;li&gt;
&lt;li&gt;the code can be expected occasionally have to deal with receiving bad config&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Systems consist of many concentric circles, a library is used by a single web service, which is part of a microservices architected platform etc etc.&lt;&#x2F;p&gt;
&lt;p&gt;If a single web service throws an exception, it should indicate:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;that there is a programming error such as an unhandled enum value in a switch statement, or&lt;&#x2F;li&gt;
&lt;li&gt;complete system failure in the microservice (e.g. out of memory&#x2F;disk)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The case where the system is misconfigured should be handled without using an exception, but instead use error-return types to indicate that it is unable to perform its duties due the bad configuration it has been fed, rather than something unexpected going wrong.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-rule-of-thumb&quot;&gt;A rule of thumb&lt;&#x2F;h3&gt;
&lt;p&gt;From my experience the heuristic to use is:&lt;&#x2F;p&gt;
&lt;p&gt;Restrict exceptions to all-gone-to-shit tear-the-stack-down-and-bail type failures.&lt;&#x2F;p&gt;
&lt;p&gt;Use return type errors to pass problematic conditions to callers to handle for anything your particular piece of code could reasonably be expected to have to deal with (bad inputs etc).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-wealth-of-expressive-options&quot;&gt;A wealth of expressive options&lt;&#x2F;h2&gt;
&lt;p&gt;Another way to think about this choice is that if you  only ever use Exceptions, or conversely if you only ever use return types to indicate failure you are missing out on a richer way of expressing your intent in code.&lt;&#x2F;p&gt;
&lt;p&gt;By using only exceptions your medium for expression is limited to:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Fail -&amp;gt; throw Exception&lt;&#x2F;li&gt;
&lt;li&gt;Success&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;By adding return type failures you have a third way to express yourself, allowing a richer communication with fellow programmers:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Catastrophic unexpected fail -&amp;gt; throw Exception&lt;&#x2F;li&gt;
&lt;li&gt;Fail that could be reasonably expected -&amp;gt; return error type&lt;&#x2F;li&gt;
&lt;li&gt;Success&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Why would we opt out of any one of theses dogmatically as an absolute rule? The all have their place, even if we can argue and bike-shed endlessly about where to draw the lines.&lt;&#x2F;p&gt;
&lt;p&gt;There is value in consistency within a particular project with its own set of good tradeoff choices to be made. Do discuss the tradeoffs here with your team, and come to a consensus as to how you want to use these alternatives consistently withing your own project(s).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Throw exceptions for thinks that should never happen if the code is correct and the host computer is functioning properly (unhandled enum in switch statement, out of memory)&lt;&#x2F;li&gt;
&lt;li&gt;Return error types for all failure modes that could be reasonably expected (missing config, dependent microservices down etc).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;are-you-sure&quot;&gt;Are you sure?&lt;&#x2F;h2&gt;
&lt;p&gt;Not entirely, this is my best attempt at figuring out this issue having listened to others. There&#x27;s still a bit of me that things that maybe exceptions are actually fine, are less code, and where we need to deal with specific conditions we can throw and catch custom exceptions seamlessly bypassing layers of code. I think that&#x27;s probably my resistance to change and learning kicking in, and I trust that golang and Rust really are learning from the failures of Java and C# in this arena both in terms of performance and in terms of writing reliable and supportable systems.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Taking an idea from business concept to software implementation</title>
        <published>2022-08-30T00:00:00+00:00</published>
        <updated>2022-08-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/08/30/taking-an-idea-from-business-concept-to-software-implementation/"/>
        <id>https://0x5.uk/2022/08/30/taking-an-idea-from-business-concept-to-software-implementation/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/08/30/taking-an-idea-from-business-concept-to-software-implementation/">&lt;p&gt;This post is my explanation of a concept I got from someone far more intelligent than me, and I&#x27;ve written it here in my own words as much to see if I can understand, explain and refine it as to share it with you lovely people. When one person teaches two people learn, as they say.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;context&quot;&gt;Context&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes you are taking instructions from someone who deeply understands technology and how to design and iterate delivery of software systems. This blog post is &lt;strong&gt;not&lt;&#x2F;strong&gt; about that situation.&lt;&#x2F;p&gt;
&lt;p&gt;This post is for when the people with the business knowledge don&#x27;t know how to run digital projects themselves, and that&#x27;s why you&#x27;re here.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s also &lt;strong&gt;not&lt;&#x2F;strong&gt; a post about an individual technologist doing the whole thing, listening to the business and then building what they need; in that case you need far less formal process.&lt;&#x2F;p&gt;
&lt;p&gt;This approach is for software engineering &lt;strong&gt;teams&lt;&#x2F;strong&gt;, which means the business knowledge has to be transferred effectively into many heads. System design and implementation is in this case a collaborative engineering effort.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;method&quot;&gt;Method&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Business folks ensure they have an idea of what their needs are, the relevant context and are ready to explain and document it for engineering teams.&lt;&#x2F;li&gt;
&lt;li&gt;Run a workshop where &quot;the business&quot; shares with the delivery team the business requirements they have gathered in their preparation for the work plus the context for the needs (i.e. the &quot;why&quot;).
&lt;ol&gt;
&lt;li&gt;The goal is to create a common understanding of what the business needs without getting into technical design or product increments &#x2F; stories &#x2F; tasks.&lt;&#x2F;li&gt;
&lt;li&gt;The outputs of this exercise should be living documents that can be referred to and refined as project delivery continues and understanding evolves.&lt;&#x2F;li&gt;
&lt;li&gt;This is a collaborative exercise, with the engineering delivery team actively probing and challenging and the shared artifacts being refined with the new understanding.&lt;&#x2F;li&gt;
&lt;li&gt;Don&#x27;t forget &quot;unhappy&quot; paths as well has the more obvious &quot;happy&quot; paths, plus non-functionals like capacity, latency, cost, design, UX etc.&lt;&#x2F;li&gt;
&lt;li&gt;Explanatory diagrams, journey maps and data journey maps are preferrable to bullet lists and prose as they encourage the right level of detail and help avoid solutionizing.&lt;&#x2F;li&gt;
&lt;li&gt;Check out &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;miro.com&#x2F;&quot;&gt;Miro&lt;&#x2F;a&gt; &amp;amp; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.lucidchart.com&#x2F;&quot;&gt;Lucidchart&lt;&#x2F;a&gt; to assist with sharing this understanding, as well as whiteboards, Post-its, index cards etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Run a technical design session with the technical team to plan out the design of the system and a route to delivery at a high level. The business do not need to be present but may need to be consulted for clarifications of the above business needs.&lt;&#x2F;li&gt;
&lt;li&gt;Present the design back to the business to flush out any issues and further refine understanding of the business needs. Iterate as necessary.&lt;&#x2F;li&gt;
&lt;li&gt;Produce user stories that represent independently deliverable capabilities. (Only as much as you need right now for planning and delivery, let&#x27;s not turn this in to waterfall!) ... With these user stories you can then:
&lt;ol&gt;
&lt;li&gt;Estimate the delivery effort required (complexity, t-shirt sizes, story points etc)&lt;&#x2F;li&gt;
&lt;li&gt;Prioritise them based on estimated cost versus value delivered.&lt;&#x2F;li&gt;
&lt;li&gt;Prioritise things by the risk involved (e.g. &quot;this is completely unknown so let&#x27;s spike this first to reduce delivery risk&quot;)&lt;&#x2F;li&gt;
&lt;li&gt;Figure out what depends on what and order delivery based on that.&lt;&#x2F;li&gt;
&lt;li&gt;Decide what should be delivered versus what should be dropped. (A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;timwise.co.uk&#x2F;2019&#x2F;07&#x2F;08&#x2F;why-every-team-needs-a-delivery-manager&#x2F;#aside-product-who&quot;&gt;Product Owner&lt;&#x2F;a&gt; decision)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Only once this shared understanding of the business needs and context plus system design is in place do we proceed to delivery of the user stories in whatever way the engineering team sees fit. Presumably some kind of agile&#x2F;scrum&#x2F;xp kind of thing.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to be a highly valued developer</title>
        <published>2022-08-24T00:00:00+00:00</published>
        <updated>2022-08-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/08/24/how-to-be-a-highly-valued-developer/"/>
        <id>https://0x5.uk/2022/08/24/how-to-be-a-highly-valued-developer/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/08/24/how-to-be-a-highly-valued-developer/">&lt;h2 id=&quot;learn-to-code-then-get-endlessly-better-at-coding&quot;&gt;Learn to code... then get endlessly better at coding...&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Be good at coding.&lt;&#x2F;li&gt;
&lt;li&gt;The end.&lt;&#x2F;li&gt;
&lt;li&gt;... but wait, there&#x27;s more.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There is truly endless training available for getting better at the craft of being a developer:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For programming languages:
&lt;ul&gt;
&lt;li&gt;There&#x27;s online courses, in-person courses, video training, coding Katas, live programming playgrounds, free courses, reaaaaly expensive courses, or you could just sit with language documentation and an editor and compiler and just learn by doing.&lt;&#x2F;li&gt;
&lt;li&gt;There&#x27;s training for all the mainstream programming languages such as C#, Javascript or Ruby&lt;&#x2F;li&gt;
&lt;li&gt;Or maybe you could &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Seven-Languages-Weeks-Programming-Programmers&#x2F;dp&#x2F;193435659X&quot;&gt;learn more about languages that might give you a new angle on things&lt;&#x2F;a&gt; such as Erlang, Haskell or Lisp and then bring those concepts back to the current language of your project making you a better and more well rounded programmer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Then there&#x27;s the frameworks such as Rails, NodeJS, ASPNET etc which are all huge things to learn in there own right. Again there&#x27;s many ways to learn these tools of the trade such as:
&lt;ul&gt;
&lt;li&gt;Read the docs&lt;&#x2F;li&gt;
&lt;li&gt;Take a Pluralsight &#x2F; Coursera &#x2F; course&lt;&#x2F;li&gt;
&lt;li&gt;Try building something and do a lot of stackoverflow searching&lt;&#x2F;li&gt;
&lt;li&gt;Pair with someone else or work on a team and learn together and from each other&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I could probably go on all morning thinking of all the ways to learn more about the pure skill of programming, or &quot;sharpening the saw&quot; as Jonathan Stark likes to call it.&lt;&#x2F;p&gt;
&lt;p&gt;Becoming a programmer, then becoming excellent at the raw skills of programming is of course something that&#x27;s been done to death, because it&#x27;s a fundamental skill. You can&#x27;t be a programmer at all by just learning SCRUM if you still don&#x27;t to know how to write an &lt;code&gt;if-else&lt;&#x2F;code&gt; statement. I don&#x27;t have much more to add to what&#x27;s out there on this, if you want to learn to code or want to be a better programmer you don&#x27;t even need to spend money these days, just go and do it. I don&#x27;t mind lending a hand if you get stuck, but it&#x27;s not like I hold some magical secret as a programmer. I am not a member of some Pratchett-esque &quot;Ancient Guild of Programmers&quot; with access to the only true source of ancient&#x27;s algorithms; it&#x27;s all out there, it&#x27;s just tricky to wrap your head round turning a pile of ASCII into stuff that works, and then trickier still to make it maintainable and easy to iterate on as needs evolve change. This is a critical foundation of the skill and not something to be skipped. In fact if you&#x27;re a programmer reading this you&#x27;d do well to read the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;noidea.dog&#x2F;glue&quot;&gt;article by Tanya Reilly titled &quot;Being Glue&quot;&lt;&#x2F;a&gt; (also a very good talk if you prefer video) before paying too much heed to the next section.&lt;&#x2F;p&gt;
&lt;p&gt;There is however a reason I am taking up your time in an era of all-the-information-you-can-eat. There are other aspects to being a truly &lt;em&gt;great&lt;&#x2F;em&gt; programmer that go beyond ingenious use of raw code. Having been around for a while I&#x27;ve started to see patterns in what makes for great teams that are a pleasure to work in and who get things done. I want to get that captured here so that good programmers can learn how to be one of those sought-after people, and to help leaders and managers know what to filter for when building great teams.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;beyond-coding-being-a-really-great-developer&quot;&gt;Beyond coding - being a &lt;em&gt;really&lt;&#x2F;em&gt; great developer&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Leave ego at the door.&lt;&#x2F;li&gt;
&lt;li&gt;Be humble.&lt;&#x2F;li&gt;
&lt;li&gt;Speak up when you think things need to be different, even if it&#x27;s not a programmer thing.&lt;&#x2F;li&gt;
&lt;li&gt;Focus on success&#x2F;failure of the project above individual productivity.&lt;&#x2F;li&gt;
&lt;li&gt;Focus on small iterative delivery&lt;&#x2F;li&gt;
&lt;li&gt;Not just knowledge of agile structures such as scrum, xp and kanban but a drive to see them done well and iterated on.&lt;&#x2F;li&gt;
&lt;li&gt;Ability and desire to educate upwards - you are the expert, help those above and around you understand.&lt;&#x2F;li&gt;
&lt;li&gt;Belief that team output is more important than personal output.&lt;&#x2F;li&gt;
&lt;li&gt;Ability to separate ones own ego from a technical opinion - so when an idea is debated it is not viewed as a personal attack.&lt;&#x2F;li&gt;
&lt;li&gt;Constant iteration in personal productivity, e.g. learning to touch-type, creating aliases for common commands. It&#x27;s not so much that this makes you faster, it&#x27;s more about what it says about the attitude you bring to everything. If you don&#x27;t constantly improve your own things, would you constantly improve your client&#x2F;company things? These things pay compound returns, particularly by freeing up mental space for the next thing.&lt;&#x2F;li&gt;
&lt;li&gt;A drive for simplicity.&lt;&#x2F;li&gt;
&lt;li&gt;An avoidance of &quot;clever&quot; - valuing future maintainability and legibility for other programmers over your own programmer ego. (This one is straying into pure programmer skills but I mention it as it&#x27;s not something you&#x27;ll get from a course on C#).&lt;&#x2F;li&gt;
&lt;li&gt;Consider how code and systems could behave not just under perfect &quot;happy path&quot; conditions, but how it would behave under unexpected conditions, failure, bad input, maybe even when in the hands of a hostile attacker. Would it be catastrophic? Would it be easy to troubleshoot and fix? Would it give a hacker a leg-up to even greater evil powers?&lt;&#x2F;li&gt;
&lt;li&gt;Empathy for your team.&lt;&#x2F;li&gt;
&lt;li&gt;Empathy for your users, including a11y needs.&lt;&#x2F;li&gt;
&lt;li&gt;A desire to be in contact with end-users (whether or not the organisation is supportive of this, I love that GDS style teams have dedicated &quot;user research&quot; functions to connect programmers to end users).&lt;&#x2F;li&gt;
&lt;li&gt;Know when it&#x27;s important to polish and when to just ship fast.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A lot of this is down to personal growth, which takes a lot of work. I&#x27;ve recommended some books that are relevant to this in &lt;a href=&quot;&#x2F;2021&#x2F;01&#x2F;25&#x2F;a-book-list-for-my-children&#x2F;&quot;&gt;A book list for my children&lt;&#x2F;a&gt;, and there&#x27;s more scattered around my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;review&#x2F;list&#x2F;50628592?shelf=read&quot;&gt;goodreads list&lt;&#x2F;a&gt;. If you&#x27;re a programmer then work on these things. If you&#x27;re a hiring manager then be sure to filter for these things, you can&#x27;t train them in time it takes to run a project, and maybe not even over an entire employment.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Choosing a programming language for timslist</title>
        <published>2022-07-29T00:00:00+00:00</published>
        <updated>2022-07-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/07/29/choosing-a-programming-language-for-timslist/"/>
        <id>https://0x5.uk/2022/07/29/choosing-a-programming-language-for-timslist/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/07/29/choosing-a-programming-language-for-timslist/">&lt;p&gt;I&#x27;m working on a new thing, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;timslist.uk&#x2F;&quot;&gt;timslist.uk&lt;&#x2F;a&gt;, and of course with the first thing out the way (a domain), the second thing is the choice of programming language. Excuse me, I&#x27;ll be back in a few years with an answer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;goals&quot;&gt;Goals&lt;&#x2F;h2&gt;
&lt;p&gt;I primarily want something that I can keep hosting costs low as possible while it has no income, for as long as possible, something that doesn&#x27;t become an unmaintainable nightmare, and something that I would be able to get decent programmers to work on in the future without creating a new unmaintainable mess.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hypothesis&quot;&gt;Hypothesis&lt;&#x2F;h2&gt;
&lt;p&gt;The hypothesis is that I can hack away on the side, build something that compiles to web assembly for sharing logic with front-end, use manifests to make it installable on mobile until I can justify full mobile apps (which are &lt;em&gt;very&lt;&#x2F;em&gt; high maintenance thanks to the api &amp;amp; app store churn) and have infinite runway while I figure out what works thanks to the consulting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-big-question-golang-or-rust&quot;&gt;The big question, GoLang or Rust?&lt;&#x2F;h2&gt;
&lt;p&gt;Currently I&#x27;m considering GoLang and Rust, which are both languages that would give me the ability to serve vast user numbers with relatively low costs. (I can dream right? Maybe I&#x27;ll even succeed...)&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m giving this &lt;em&gt;a lot&lt;&#x2F;em&gt; of thought because should I succeed then this is probably one of the hardest things to change amidst the chaos of a runaway startup; and the choice has very real consequences.&lt;&#x2F;p&gt;
&lt;p&gt;(P.s. In case anyone wonders, I&#x27;m happy to carry on consulting in C# land and hack on other things outside of client time.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-do-i-want-out-of-a-language&quot;&gt;What do I want out of a language?&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Something I&#x27;ll enjoy working on in the short to medium term while it&#x27;s just me building it.&lt;&#x2F;li&gt;
&lt;li&gt;Something that would allow me to attract great collaborative coders (not rock stars) to work on it with or for me later on when I can show revenue.&lt;&#x2F;li&gt;
&lt;li&gt;Something that will keep hosting costs as low as possible to maximize my pre-revenue ability to scale the user base while supporting it with contracting.&lt;&#x2F;li&gt;
&lt;li&gt;Something I can run server and client side (with WASM) to avoid duplication of code that I can ill afford.&lt;&#x2F;li&gt;
&lt;li&gt;Something that allows me to build up advanced abstractions that allow me to operate and pivot without re-writing reams of code..&lt;&#x2F;li&gt;
&lt;li&gt;Something that has enough good quality library support that I&#x27;m not going to drown in unfinished or missing dependencies.&lt;&#x2F;li&gt;
&lt;li&gt;Ideally something that might allow me to build some unique technical advantages over the competition.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;golang&quot;&gt;GoLang&lt;&#x2F;h3&gt;
&lt;p&gt;I wrote &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;schema-explorer&quot;&gt;schema explorer&lt;&#x2F;a&gt; in GoLang which was educational. I still appreciate the simplicity of the language, and having worked on C# 2.0 that was still simple I appreciate the value of being able to pick up anyone&#x27;s code and refactor it into shape, something no longer possible in the sprawling language that is C# 10 or whatever they&#x27;ve got to now. On the other hand I was left with the feeling that abstractions would be less high-level resulting in more code to wrangle for the same amount of functionality; something I can ill afford as a lone programmer at this stage.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rust&quot;&gt;Rust&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;survey.stackoverflow.co&#x2F;2022&#x2F;#overview&quot;&gt;Rust has been the most loved language for 7 years in a row&lt;&#x2F;a&gt; which must mean something, right? It is low level and fast, but it also doesn&#x27;t shy away from high-level abstractions that I appreciate as a programmer. To give myself a better idea as to what it&#x27;s like to work in I&#x27;ve been working on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;gitopolis&#x2F;&quot;&gt;gitopolis&lt;&#x2F;a&gt;, this has helped me get beyond the (excellent) docs. So far it&#x27;s, erm, hard!&lt;&#x2F;p&gt;
&lt;p&gt;I want to enjoy this project, and I also want it to be written in something that attracts great coders for many years just in case this is successful. The kind of coders that are more than just writers of reams of mediocre code.&lt;&#x2F;p&gt;
&lt;p&gt;My main worry with Rust (and to a lesser extent GoLang) is the incompleteness of libraries, frameworks and integrations; leading to endless toil and dead ends that I just don&#x27;t have the engineering resources to contend with.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;popularity-curves-engineering-talent&quot;&gt;Popularity curves &amp;amp; engineering talent&lt;&#x2F;h4&gt;
&lt;p&gt;Ruby has seen a rise and fall in popularity with the best coders as the basecamp-induced excitement faded and the kool kids moved to the next big thing, probably something with types or functional programming.&lt;&#x2F;p&gt;
&lt;p&gt;C# has a vast army of not-very-good programmers (who create endless projects for me to improve at work).&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s hard to tell where GoLang and Rust fit in these curves.&lt;&#x2F;p&gt;
&lt;p&gt;I suspect GoLang is likely to bore the better coders in the end, and although it will prevent the less good coders hurting themselves quite so badly I&#x27;m not sure I want that crowd.&lt;&#x2F;p&gt;
&lt;p&gt;Rust is definitely a sharper and harder to use tool, which is the kind of thing that attracts the hot talent. But equally, when they get bored of the challenge they move on like locusts to the next hot thing, leaving the businesses that chose Rust behind with a dearth of talented people to work on their existing code.&lt;&#x2F;p&gt;
&lt;p&gt;I can&#x27;t tell if Rust will buck that trend and be sustainably cool, or if the cool coders will all head off to the next big thing by the time I have need of many engineers.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m also worried that Rust will attract the C++ over-engineering crowd who will write incredible code that no-one else can comprehend while the business goes out of business due to not shipping anything users actually care about. (Sometimes called &quot;write-only code&quot;!)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;articles-of-persuasion&quot;&gt;Articles of persuasion&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;endler.dev&#x2F;2017&#x2F;go-vs-rust&#x2F;&quot;&gt;Endler&#x27;s article on GoLang vs Rust&lt;&#x2F;a&gt; makes me think I will &lt;em&gt;enjoy&lt;&#x2F;em&gt; building in Rust more, which is important for a project that I plan to be solo on for a long time, and have to want to work on it day in day out regardless of the challenges of life to stand a chance of success&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kristoff.it&#x2F;blog&#x2F;why-go-and-not-rust&#x2F;&quot;&gt;Loris Cro&#x27;s piece on choosing GoLang over Rust for the enterprise&lt;&#x2F;a&gt; is very compelling and I think probably has the argument that I&#x27;ve been looking for to persuade me that I should choose GoLang rather than Rust for timslist. I&#x27;m looking for something that will do engineering at scale in the long run while keeping hosting and programmer costs down.&lt;&#x2F;p&gt;
&lt;p&gt;Completely opposing this, and also very compelling is the story of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discord.com&#x2F;blog&#x2F;why-discord-is-switching-from-go-to-rust&quot;&gt;Why Discord is switching from Go to Rust&lt;&#x2F;a&gt;, where they show their massively improved metrics thanks to a rewrite of a GoLang microservice into Rust, along with assertions from experience of being able to keep engineering (relatively) small, and iterate fast. They say they are using Rust extensively in production which is reason for confidence in it as a choice as Discord probably has far more demanding needs than timslist would have any time in the next 20 years if it took off like a rocket.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;betterprogramming.pub&#x2F;early-impressions-of-go-from-a-rust-programmer-f4fd1074c410?gi=4ae004f7c897&quot;&gt;Early Impressions of Go From a Rust Programmer&lt;&#x2F;a&gt; is interesting because on the one hand it pretty much all points towards GoLang being the right answer (I happen to like the use of upper&#x2F;lower case for public&#x2F;private), however towards the end it shows some things that are missing that might make it harder to ever use higher level abstactions, and it notes the fact that nil-pointer de-refs are still a runtime failure in GoLang.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;articles-on-rust-versus-golang&quot;&gt;Articles on Rust versus GoLang&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;This is a must read on GoLang and Rust: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bitfieldconsulting.com&#x2F;golang&#x2F;rust-vs-go&quot;&gt;https:&#x2F;&#x2F;bitfieldconsulting.com&#x2F;golang&#x2F;rust-vs-go&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;endler.dev&#x2F;2017&#x2F;go-vs-rust&#x2F;&quot;&gt;https:&#x2F;&#x2F;endler.dev&#x2F;2017&#x2F;go-vs-rust&#x2F;&lt;&#x2F;a&gt; this one makes me think that perhaps using the hard road of Rust would give me some opportunities for hard-to-copy features in future (such as responsiveness, stability)
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=15266066&quot;&gt;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=15266066&lt;&#x2F;a&gt; interesting discussion of the endler post&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kristoff.it&#x2F;blog&#x2F;why-go-and-not-rust&#x2F;&quot;&gt;https:&#x2F;&#x2F;kristoff.it&#x2F;blog&#x2F;why-go-and-not-rust&#x2F;&lt;&#x2F;a&gt; - a very persuasive and level-headed article article that explains the tradeoff in terms of real enterprise development (something I&#x27;m painfully familiar with).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeburst.io&#x2F;should-i-rust-or-should-i-go-59a298e00ea9?gi=8338640ecce8&quot;&gt;https:&#x2F;&#x2F;codeburst.io&#x2F;should-i-rust-or-should-i-go-59a298e00ea9?gi=8338640ecce8&lt;&#x2F;a&gt; - mentions that Rust can be made hard to read by other devs, an important point.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discord.com&#x2F;blog&#x2F;why-discord-is-switching-from-go-to-rust&quot;&gt;Why Discord is switching from Go to Rust&lt;&#x2F;a&gt; - powerful article on how much better Rust is than GoLang for making the best use of server resources and providing low-latency high-throughput capabilities, with no GC related spikes in latency. A strong argument for Rust over GoLang.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.boot.dev&#x2F;rust&#x2F;concurrency-in-rust-can-it-stack-up-against-gos-goroutines&#x2F;&quot;&gt;https:&#x2F;&#x2F;blog.boot.dev&#x2F;rust&#x2F;concurrency-in-rust-can-it-stack-up-against-gos-goroutines&#x2F;&lt;&#x2F;a&gt; compares concurrency and parallelism in Rust and GoLang in a short and enlightening style with some useful code samples. I think the differences are less important to the decision than the other factors above, clearly both can solve the problems as needed.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;questions&#x2F;247298&#x2F;how-are-rust-traits-different-from-go-interfaces&quot;&gt;https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;questions&#x2F;247298&#x2F;how-are-rust-traits-different-from-go-interfaces&lt;&#x2F;a&gt; - dynamic and static dispatch&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;assimilating-the-tradeoffs&quot;&gt;Assimilating the tradeoffs&lt;&#x2F;h2&gt;
&lt;p&gt;The pros and cons that are relevant to what I&#x27;m trying to do:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;in-favour-of-golang&quot;&gt;In favour of GoLang&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Maintainable as more programmers added to team of varying quality and opinion (inevitable in the long run I think).&lt;&#x2F;li&gt;
&lt;li&gt;Highly performant programs.&lt;&#x2F;li&gt;
&lt;li&gt;Fast compile times on big codebases.&lt;&#x2F;li&gt;
&lt;li&gt;I like the test library style (minimal, uncontrived, use real code to write tests).&lt;&#x2F;li&gt;
&lt;li&gt;Has generics at last.&lt;&#x2F;li&gt;
&lt;li&gt;Easy multi-threading (not sure I need this particularly).&lt;&#x2F;li&gt;
&lt;li&gt;GC (easier than worrying about Rust&#x27;s ideas).&lt;&#x2F;li&gt;
&lt;li&gt;Continues to be used internally at google at scale so likely to be supported for a loooong time.&lt;&#x2F;li&gt;
&lt;li&gt;Stated mission to remain a small language.
&lt;ul&gt;
&lt;li&gt;Having watched C# go from being a truly knowable and useful language in 2.0 to being a sprawling mess with syntactic-sugar-itis in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;csharp&#x2F;whats-new&#x2F;csharp-11&quot;&gt;C# 11&lt;&#x2F;a&gt;, a state that makes it increasingly hard to work with the code of others and work well together in teams, I have no desire to set my own startup up for that fate.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;m guessing the ecosystem of libraries &amp;amp; frameworks for writing web things has matured since I last looked and is (I&#x27;m guessing) ahead of the Rust ecosystem.&lt;&#x2F;li&gt;
&lt;li&gt;Explicit handling of errors by return (but also has panic available for burn-it-all-down errors, which can be caught).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;against-golang&quot;&gt;Against GoLang&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Error handling boilerplate.&lt;&#x2F;li&gt;
&lt;li&gt;Module system is a bit confusing (perhaps they have it right and easy now?)&lt;&#x2F;li&gt;
&lt;li&gt;Unknown future direction (do we know the future of any language really?)&lt;&#x2F;li&gt;
&lt;li&gt;Code ends up quite verbose - volume of code can cause resistance to change.&lt;&#x2F;li&gt;
&lt;li&gt;Dull, so might not be able to retain great coders in the long run as the zeitgeist moves on to hip&#x27;er pastures.&lt;&#x2F;li&gt;
&lt;li&gt;No pattern matching coolness. I don&#x27;t know if I&#x27;m just overexcited about discovering this way of coding or if it&#x27;s actually important. No doubt I&#x27;ll gain more perspective with practice.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;yager.io&#x2F;programming&#x2F;go.html&quot;&gt;Why Go Is Not Good by Will Yager&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;in-favour-of-rust&quot;&gt;In favour of Rust&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Highly performant programs.&lt;&#x2F;li&gt;
&lt;li&gt;Immutable by default (this is huge!)&lt;&#x2F;li&gt;
&lt;li&gt;No null-ref errors (hooray!)&lt;&#x2F;li&gt;
&lt;li&gt;Intersting new toy to learn.&lt;&#x2F;li&gt;
&lt;li&gt;Potentially able to make higher level clean abstractions than in go.&lt;&#x2F;li&gt;
&lt;li&gt;Created by Mozilla who we love.&lt;&#x2F;li&gt;
&lt;li&gt;Owned and run by the independent &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;foundation.rust-lang.org&#x2F;&quot;&gt;Rust Foundation&lt;&#x2F;a&gt;, so perhaps free from the dubious influence of commercial interests. (Though people don&#x27;t ignore those that pay them).&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Most loved language&quot;, but what does that mean? Possibly easier to attract talent that want to work in Rust? But will they be the right kind of talent? And how long will that last?&lt;&#x2F;li&gt;
&lt;li&gt;No runtime means smaller WASM files I think, and there seems to be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rustwasm.github.io&#x2F;book&#x2F;reference&#x2F;code-size.html&quot;&gt;lots of ways to optimise wasm file size in Rust&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;against-rust&quot;&gt;Against Rust&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Harder to learn.&lt;&#x2F;li&gt;
&lt;li&gt;Takes longer to write a single piece of functionality up front.&lt;&#x2F;li&gt;
&lt;li&gt;Unknown future direction.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;foundation.rust-lang.org&#x2F;news&#x2F;2021-02-08-hello-world&#x2F;&quot;&gt;Rust foundation is new&lt;&#x2F;a&gt;, and unproven in ability to maintain the language over the long term.&lt;&#x2F;li&gt;
&lt;li&gt;I heard that there may be issues with the completeness and maintenance of libraries (&quot;crates&quot;) in the Rust ecosystem, this is of particular concern when it comes to security issues. Perhaps this will improve, or perhaps I am misled. Every ecosystem has its security issues, it&#x27;s a tough world out there at the moment no matter your platform.&lt;&#x2F;li&gt;
&lt;li&gt;I clearly don&#x27;t know what I&#x27;m doing yet, given how long it&#x27;s taking me to build gitopolis.&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Fighting the borrow checker&quot; (perhaps a worthy price for eliminating whole classes of programming error at compile time).&lt;&#x2F;li&gt;
&lt;li&gt;Perhaps a more limited pool of Rust programmers availale than GoLang programmers. If all I can find is a few relevant coders it&#x27;s going to be harder to filter for other traits such as not-being-an-asshole, or communication skills.&lt;&#x2F;li&gt;
&lt;li&gt;Layers and layers of boilerplate error&#x2F;match handlers (or so I heard). Not sure if this is an issue yet, I need to get more experience to judge.&lt;&#x2F;li&gt;
&lt;li&gt;Language for C++ coders, not people who want to build simple business value fast. Might encourage over-engineering for what should be straight-forward simple solutions to simple business needs.&lt;&#x2F;li&gt;
&lt;li&gt;Complex language with many ways to solve problems, that might result in it being harder to maintain as programmers and styles come and go.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-now&quot;&gt;What now?&lt;&#x2F;h2&gt;
&lt;p&gt;I need to sleep on all this research, and spend some more time building gitopolis with all this in mind.&lt;&#x2F;p&gt;
&lt;p&gt;Currently there&#x27;s a bit of me that thinks I &quot;should&quot; use GoLang as the &quot;boring&quot; option that would result in minimal drama, but my heart is definitely pullled towards Rust right now, and that&#x27;s important because I have to actually want to work on this thing.&lt;&#x2F;p&gt;
&lt;p&gt;To be continued ...&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Single class per file</title>
        <published>2022-07-10T00:00:00+00:00</published>
        <updated>2022-07-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/07/10/single-class-per-file/"/>
        <id>https://0x5.uk/2022/07/10/single-class-per-file/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/07/10/single-class-per-file/">&lt;p&gt;Reasons you should prefer a single &lt;code&gt;class&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;interface&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;record&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;enum&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;struct&lt;&#x2F;code&gt; per file in C# projects.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;congitive-load&quot;&gt;Congitive load&lt;&#x2F;h2&gt;
&lt;p&gt;Multiple types per file increases the cognitive overhead of remembering where everything lives.&lt;&#x2F;p&gt;
&lt;p&gt;When working on a project, having to remember where each thing is hidden and how things are organised is extra mental load that can be eliminated by following the simple rule of &quot;every class gets a file&quot; regardless of how trivial or short they may be.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reduced-dependence-on-ide-support&quot;&gt;Reduced dependence on IDE support&lt;&#x2F;h2&gt;
&lt;p&gt;IDEs that can jump to a definition are not the only tool we use to inspect and navigate code.&lt;&#x2F;p&gt;
&lt;p&gt;By hiding multiple types in a file where the name doesn&#x27;t match you make it harder to operate in a codebase without a full IDE.&lt;&#x2F;p&gt;
&lt;p&gt;You might be an IDE-only developer but not everyone operates that way, and you might be missing out on some other excellent tools out there.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;git-merge-conflict-avoidance&quot;&gt;Git merge conflict avoidance&lt;&#x2F;h2&gt;
&lt;p&gt;You are more likely to run in to merge conflicts if you put types all together in one file as multiple developers work on a project. Especially when things get moved &#x2F; renamed &#x2F; refactored.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simple-refactoring&quot;&gt;Simple refactoring&lt;&#x2F;h2&gt;
&lt;p&gt;Putting multiple things in a file breaks refactoring tool flows (resharper) which assume they can rename files to match types.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-be-applied-consistently&quot;&gt;Can be applied consistently&lt;&#x2F;h2&gt;
&lt;p&gt;Having multiple types per file requires you to make constant judgement calls about what goes together in one file and what is separate. Different developers will inevitably make different judgement calls.&lt;&#x2F;p&gt;
&lt;p&gt;This problem can be entirely eliminated by sticking to class-per-file.&lt;&#x2F;p&gt;
&lt;p&gt;It is impossible to come up with a concrete rule for exactly what goes together in a file and what is separate, whereas the rule of one-class-per-file is trivial to apply consistently.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;avoid-need-for-additional-naming&quot;&gt;Avoid need for additional naming&lt;&#x2F;h2&gt;
&lt;p&gt;If you have one class in a file you can name the file the same as the class. If you have two types in a file what do you name the file?&lt;&#x2F;p&gt;
&lt;p&gt;If you have two types in a file you now have to come up with a &lt;em&gt;third&lt;&#x2F;em&gt; name that covers both things, or use the name of only one of the things, which is then misleading &#x2F; surprising. By having a class per file you eliminate this entirely.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-wait-what-about-tiny-little-records&quot;&gt;But wait, what about tiny little records&lt;&#x2F;h2&gt;
&lt;p&gt;A project I was on recently made heavy use of the newer &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;csharp&#x2F;language-reference&#x2F;builtin-types&#x2F;record&quot;&gt;&lt;code&gt;record&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; type, which is cool because they&#x27;re (usually) immutable. In that project there was a coding style of lumping all related records together in one file, and I must confess that I&#x27;m happy to make the exception for tiny one-line record types that only exist as child types to a parent record, and they can go in the parent&#x27;s file. As soon as they are shared between two parents at that point they have to go in their own file otherwise the structure makes no sense any more.&lt;&#x2F;p&gt;
&lt;p&gt;For example if &lt;code&gt;Pet&lt;&#x2F;code&gt; is only referenced through Person then I&#x27;m cool with &lt;code&gt;Tattoo&lt;&#x2F;code&gt; living in &lt;code&gt;Person.cs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; record&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; Person&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; FirstName&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt; LastName&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; Hair&lt;&#x2F;span&gt;&lt;span&gt; Hair&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; List&amp;lt;Tattoo&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; record&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; Hair&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; Colour&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; LengthCm&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#586E75, #93A1A1);font-weight: bold;&quot;&gt; record&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; Tattoo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt; Description&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt; HasColour&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Without accepting this nuance the result is thousands of tiny files, which ends up being harder to navigate. Use your judgement wisely.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-hear-c-and-rust-like-huge-files&quot;&gt;I hear C and Rust like huge files&lt;&#x2F;h2&gt;
&lt;p&gt;I have seen in Rust at least that there&#x27;s a cultural preference for &quot;one big file&quot; that defines a whole thing. This is interesting, but not something I&#x27;d be keen to import into C# projects which have a much stronger thing-per-file heritage and where I&#x27;ve seen both and far prefer the class per file style.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tips for remembering names</title>
        <published>2022-05-19T00:00:00+00:00</published>
        <updated>2022-05-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/05/19/tips-for-remembering-names/"/>
        <id>https://0x5.uk/2022/05/19/tips-for-remembering-names/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/05/19/tips-for-remembering-names/">&lt;h2 id=&quot;the-tips&quot;&gt;The Tips&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;tip-1&quot;&gt;Tip #1&lt;&#x2F;h3&gt;
&lt;p&gt;📝 When being introduced to everyone in an office, take the time to make a quick note in a notepad. Name + role.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;👹Fear: not making eye contact, being rude.&lt;&#x2F;li&gt;
&lt;li&gt;😇 Reality: people really appreciate that you care enough about them to make the extra effort.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;tip-2&quot;&gt;Tip #2&lt;&#x2F;h3&gt;
&lt;p&gt;Use their name immediately.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Hi Angela!&quot;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-3&quot;&gt;Tip #3&lt;&#x2F;h3&gt;
&lt;p&gt;Pair them mentally with someone you know with the same name, perhaps someone famous. Imagine them stood together.&lt;&#x2F;p&gt;
&lt;p&gt;Any kind of visual image that helps you jump from face to name no matter how silly.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-4&quot;&gt;Tip #4&lt;&#x2F;h3&gt;
&lt;p&gt;Make an effort to get the pronunciation *precisely&quot; right, especially with names from languages with sounds that don&#x27;t exist in your native tongue.&lt;&#x2F;p&gt;
&lt;p&gt;People appreciate that you actually want to get it right and it&#x27;s an excuse to repeat it lots while looking at their face.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-5&quot;&gt;Tip #5&lt;&#x2F;h3&gt;
&lt;p&gt;Attempt use their name when you see them next.&lt;&#x2F;p&gt;
&lt;p&gt;Swallow your fear of looking like an idiot &#x2F; being uncaring.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s nothing like the horror and embarrassment of being corrected bluntly to sear the right name into your reptilian brain.&lt;&#x2F;p&gt;
&lt;p&gt;I did this twice yesterday 🙊🙈, sorry!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-6&quot;&gt;Tip #6&lt;&#x2F;h3&gt;
&lt;p&gt;Mentally rehearse and reinforce the name-to-face pairing both ways.&lt;&#x2F;p&gt;
&lt;p&gt;Name -&amp;gt; face (or distinguishing features)&lt;&#x2F;p&gt;
&lt;p&gt;Face -&amp;gt; Name + role + interests&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-7&quot;&gt;Tip #7&lt;&#x2F;h3&gt;
&lt;p&gt;Practice recall over time:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;immediately (oh hi Ishmel)&lt;&#x2F;li&gt;
&lt;li&gt;In 5 mins (hmm so Heather is a coder from 1st floor)&lt;&#x2F;li&gt;
&lt;li&gt;10 mins&lt;&#x2F;li&gt;
&lt;li&gt;half hour&lt;&#x2F;li&gt;
&lt;li&gt;2 hours&lt;&#x2F;li&gt;
&lt;li&gt;6 hrs&lt;&#x2F;li&gt;
&lt;li&gt;1 day&lt;&#x2F;li&gt;
&lt;li&gt;2 days&lt;&#x2F;li&gt;
&lt;li&gt;4 days&lt;&#x2F;li&gt;
&lt;li&gt;1 week&lt;&#x2F;li&gt;
&lt;li&gt;etc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;tip-8&quot;&gt;Tip #8&lt;&#x2F;h3&gt;
&lt;p&gt;Chat to them on teams &#x2F; slack &#x2F; email etc where the tech shows full names and hopefully profile pics too.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-9&quot;&gt;Tip #9&lt;&#x2F;h3&gt;
&lt;p&gt;Try and recall, when you can&#x27;t then refer to your list of names from the office intros.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-10&quot;&gt;Tip #10&lt;&#x2F;h3&gt;
&lt;p&gt;When a new name pops up add it to your physical notebook with a person symbol in the margin so you can scan for them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-11&quot;&gt;Tip #11&lt;&#x2F;h3&gt;
&lt;p&gt;Put them in your phone address book, use tags and notes to associate them with where you met them (neighbour, job at X, works at Y)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-12&quot;&gt;Tip #12&lt;&#x2F;h3&gt;
&lt;p&gt;Take the time to rewrite your rough list of names into a tidier and organised list.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-13&quot;&gt;Tip #13&lt;&#x2F;h3&gt;
&lt;p&gt;Go and coffee with them individually and learn about them, their history and what excites them.&lt;&#x2F;p&gt;
&lt;p&gt;It turns them into a human with depth and feelings in your brain instead of a lifeless fact to remember.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-14&quot;&gt;Tip #14&lt;&#x2F;h3&gt;
&lt;p&gt;Ask the group in a meeting if they wouldn&#x27;t mind starting with a round of intros. (Or ask the meeting organiser &#x2F; chair to include that.)&lt;&#x2F;p&gt;
&lt;p&gt;Make notes when they do. None of us can remember 15 names &amp;amp; faces in one go.&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t be afraid to interrupt if you miss one, it shows caring.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-15&quot;&gt;Tip #15&lt;&#x2F;h3&gt;
&lt;p&gt;Use &lt;em&gt;any&lt;&#x2F;em&gt; excuse to use people&#x27;s names&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;when they are there&lt;&#x2F;li&gt;
&lt;li&gt;without them&lt;&#x2F;li&gt;
&lt;li&gt;with other&lt;&#x2F;li&gt;
&lt;li&gt;privately&lt;&#x2F;li&gt;
&lt;li&gt;verbally&lt;&#x2F;li&gt;
&lt;li&gt;in writing&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;tip-16&quot;&gt;Tip #16&lt;&#x2F;h3&gt;
&lt;p&gt;Ignore your fear of getting their name wrong.&lt;&#x2F;p&gt;
&lt;p&gt;Better to try, fail and improve than to be stuck not knowing. Time heals all.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-17&quot;&gt;Tip #17&lt;&#x2F;h3&gt;
&lt;p&gt;Don&#x27;t be afraid to screw up names more than once.&lt;&#x2F;p&gt;
&lt;p&gt;Most people can empathise and are also afraid.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-18&quot;&gt;Tip #18&lt;&#x2F;h3&gt;
&lt;p&gt;Show empathy by repeating your own name to help them learn without fear.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-19&quot;&gt;Tip #19&lt;&#x2F;h3&gt;
&lt;p&gt;Visibly lead by example by using names a lot with others - to help everyone learn new names.&lt;&#x2F;p&gt;
&lt;p&gt;Hopefully others will follow suit. (I&#x27;m not sure this actually works, let me know!)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tip-20&quot;&gt;Tip #20&lt;&#x2F;h3&gt;
&lt;p&gt;Don&#x27;t be afraid to actually &lt;em&gt;look&lt;&#x2F;em&gt; directly at their face and the rest of them.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s hard to remember a face that you haven&#x27;t actually seen.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes there&#x27;s social dynamics that make it &lt;em&gt;really&lt;&#x2F;em&gt; hard to look someone in the face.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-journey-to-better&quot;&gt;My journey to better&lt;&#x2F;h2&gt;
&lt;p&gt;I too was terrified of this. I just quietly held the shame &amp;amp; failure of not knowing names I&#x27;d been told. Memory isn&#x27;t my forté.&lt;&#x2F;p&gt;
&lt;p&gt;One day I just thought why am I avoiding this, all I can do is try and be better. So from then on I resolved to put my fears aside and just do my best.&lt;&#x2F;p&gt;
&lt;p&gt;As a contract coder who has to learn 40+ new names on a regular basis this has been a huge improvement for me, and I continue to both fail and improve.&lt;&#x2F;p&gt;
&lt;p&gt;I have zero regrets for taking the risk and trying to be better, including the many many failures.&lt;&#x2F;p&gt;
&lt;p&gt;The best thing about deciding to try harder is that even if I utterly fail remembering someones name it&#x27;s really obvious that they really appreciate the fact that I&#x27;m trying, that I care enough about them to to want to know who they are and treat them as a real person, and that I take the time to learn more about them than just an email address.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve accepted that my human brain only has limited ability and I&#x27;m sorry to say I&#x27;ve forgotten hundreds, maybe thousands of names in my 22 years of work.&lt;&#x2F;p&gt;
&lt;p&gt;We all have these limitations to a greater or lesser extent, so when I fail I get empathy and usually a correction. Not one person has expressed annoyance with me.&lt;&#x2F;p&gt;
&lt;p&gt;I still value and honour my time with all those people, whether I remember names or not.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-about-you&quot;&gt;What about you?&lt;&#x2F;h2&gt;
&lt;p&gt;How do you approach remembering names?&lt;&#x2F;p&gt;
&lt;p&gt;Do you risk it or do you avoid it altogether?&lt;&#x2F;p&gt;
&lt;p&gt;What tips and experiences can you share?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sleepless-nights&quot;&gt;Sleepless nights&lt;&#x2F;h2&gt;
&lt;p&gt;This post started as a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;tim_abell&#x2F;status&#x2F;1527109721429315586&quot;&gt;series of tweets&lt;&#x2F;a&gt; when I woke up in the small hours thinking about it. Do add your thoughts there if you&#x27;re a twitter kinda person.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Detecting bit-rot with md5deep</title>
        <published>2022-03-02T00:00:00+00:00</published>
        <updated>2022-03-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/03/02/detecting-bit-rot-with-md5deep/"/>
        <id>https://0x5.uk/2022/03/02/detecting-bit-rot-with-md5deep/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/03/02/detecting-bit-rot-with-md5deep/">&lt;p&gt;Thanks to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;luxagen.com&#x2F;&quot;&gt;luxagen&lt;&#x2F;a&gt; for getting me to actually set something up for this. Turned out to be mighty useful when I accidentally trashed half my home folder and wanted to know if &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;syncthing.net&#x2F;&quot;&gt;syncthing&lt;&#x2F;a&gt; had propagated any of the damage.&lt;&#x2F;p&gt;
&lt;p&gt;The use case is slightly different to mine, but &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;luxagen&#x2F;RotKraken&quot;&gt;RotKraken&lt;&#x2F;a&gt; is worth a look. Its unique feature is storing file hashes in the extended attributes of the same file. This is very tidy but doesn&#x27;t help me with catching unwanted deletions, hence going back to md5deep.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;d think that running &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jessek&#x2F;hashdeep&quot;&gt;md5deep aka hashdeep&lt;&#x2F;a&gt; wouldn&#x27;t be worthy of a blog post, but what I found is that the primary use case for hashdeep is actually validating the integrity of an installation in order to detect rootkits etc. This is not the same as what I&#x27;m doing which is being able to spot if I&#x27;ve lost any files I care about in &lt;code&gt;&#x2F;home&#x2F;tim&lt;&#x2F;code&gt; through carelessness or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Data_degradation&quot;&gt;bit-rot&lt;&#x2F;a&gt;. It turns out that md5deep does actually have what I needed, but the way the options are described means it&#x27;s not at all obvious that it would fulfill this need.&lt;&#x2F;p&gt;
&lt;p&gt;You can find &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;f70f34f8933b2abaf42789f8afdbd7d5&quot;&gt;my hash and verify scripts as a gist here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It turns out the magic is in the &quot;audit&quot; section of the docs.&lt;&#x2F;p&gt;
&lt;p&gt;The terminology of the verification output is more about what it did than why you care. The important one for spotting bit-rot when verifying is &lt;code&gt;Known file not used&lt;&#x2F;code&gt; which means that you have a hash but you no longer have a matching file anywhere. Either you deleted it or modified it on purpose or you&#x27;ve just lost something you care about. Time to reach for the backups. I like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;backintime.readthedocs.io&#x2F;&quot;&gt;back-in-time&lt;&#x2F;a&gt; to usb disks for backup.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hashing&quot;&gt;Hashing&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hashdeep -c md5 -of -r -l Music Documents &amp;gt; hash_file.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;explainshell.com&#x2F;explain?cmd=hashdeep+-c+md5+-of+-r+-l+Music+Documents&quot;&gt;https:&#x2F;&#x2F;explainshell.com&#x2F;explain?cmd=hashdeep+-c+md5+-of+-r+-l+Music+Documents&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;%%%% HASHDEEP-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;%%%% size,md5,filename&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;## Invoked from: &#x2F;home&#x2F;tim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;## $ hashdeep -c md5 -of -r -l Music Downloads Documents Pictures Phone Dropbox repo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;## &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3425,3ecc5852703f3846298b381bc2510a39,Music&#x2F;checksums-verification-Music.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;461,456e92277eaf9de695bd1229d80f059b,Music&#x2F;checksums-verification-Music.txt.bak&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100663,0d9d53e95e5d80fa43a64f5d02f25b1e,Music&#x2F;checksums-Music.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;794926,95c1558e7c97200140c37ffb0d12669d,Music&#x2F;flac&#x2F;Mordecai Smyth - Dial M For Mordecai&#x2F;cover.jpg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;17618302,cfb11490aacfdcbb79fd4310cf834e01,Music&#x2F;flac&#x2F;Mordecai Smyth - Dial M For Mordecai&#x2F;Mordecai Smyth - Dial M For Mordecai - 02 Psychedelic Sarah.flac&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;verifying&quot;&gt;Verifying&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hashdeep -k  hash_file.txt -rle -of Music Documents -avv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;explainshell.com&#x2F;explain?cmd=hashdeep+-k++hash_file.txt+-rle+-of+Music+Documents+-avv&quot;&gt;https:&#x2F;&#x2F;explainshell.com&#x2F;explain?cmd=hashdeep+-k++hash_file.txt+-rle+-of+Music+Documents+-avv&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Documents&#x2F;hashdeep-checksums-verification.txt.bak: Moved from Documents&#x2F;hashdeep-checksums-verification.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Documents&#x2F;hashdeep-checksums-verification.txt: No match&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Documents&#x2F;hashdeep-checksums.txt: No match&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;repo&#x2F;rust-kata&#x2F;.idea&#x2F;workspace.xml: No match&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;repo&#x2F;rust-kata&#x2F;.git&#x2F;logs&#x2F;HEAD: No match&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Documents&#x2F;hashdeep-checksums-verification.txt.bak: Known file not used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Documents&#x2F;hashdeep-checksums.txt: Known file not used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;repo&#x2F;rust-kata&#x2F;.idea&#x2F;workspace.xml: Known file not used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;workflow&quot;&gt;Workflow&lt;&#x2F;h2&gt;
&lt;p&gt;I have a monthly calendar reminder to run backups. When that goes off I:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;verify-hashes.sh&lt;&#x2F;code&gt; and search the output for &quot;Known file not used&quot; to find any rot or churn.&lt;&#x2F;li&gt;
&lt;li&gt;Run &lt;code&gt;rehash.sh&lt;&#x2F;code&gt; to update the hashes.&lt;&#x2F;li&gt;
&lt;li&gt;Plug a backup HDD in and run back-in-time to update the backup&lt;&#x2F;li&gt;
&lt;li&gt;Sleep easy.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I run one hash file for all folders. I started with one per top level folder but that meant the verify couldn&#x27;t spot things moved between folders and it reported them as missing.&lt;&#x2F;p&gt;
&lt;p&gt;It would be nice to iterate on this but it&#x27;s a good start.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;updated-workflow-jun-2025&quot;&gt;Updated workflow Jun 2025&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve ditched the odd hashdeep format that I only used because of the &quot;audit&quot; capability, and am now using the more common md5deep format (same binary, different file format),&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;╰─$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; checksum-home.sh&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;set&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; exit on error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; ~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;backup_paths&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;M&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;u&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; D&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;w&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; D&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;u&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;hashfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Documents&#x2F;checksums&#x2F;home&#x2F;md5deep-checksums-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;date&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;+%Y%m%d-%H%M%S&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;.md5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; -r = recursive&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; -l = relative paths&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;time&lt;&#x2F;span&gt;&lt;span&gt; md5deep -r -l &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;backup_paths&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; tee&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;hashfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;explainshell.com&#x2F;explain?cmd=md5deep+-rl+.&quot;&gt;https:&#x2F;&#x2F;explainshell.com&#x2F;explain?cmd=md5deep+-rl+.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;... then using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;md5-tools&quot;&gt;my fork of md5-tools&lt;&#x2F;a&gt; - subcommand &lt;code&gt;md5-diff&lt;&#x2F;code&gt; - to assess differences between hash files, filtered through a quick &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;f7f776c7f0792ea13ef44798082b9935&quot;&gt;awol-hashes bash script&lt;&#x2F;a&gt; to show only the files that have vanished or been modified.&lt;&#x2F;p&gt;
&lt;p&gt;The result is then sent piped through &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rustworkshop&#x2F;paths2html&quot;&gt;paths2html&lt;&#x2F;a&gt; that I wrote to give a collabsible html view of the missing files for easy review.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;md5-diff&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;before&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;after&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-regexp&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;^\+A&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; sed&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;s&#x2F;^\+A &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; tee&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;missing_hashes_file&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;missing_hashes_file&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; awk&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;{print substr($0, index($0, $2))}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; paths2html&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;missing_hashes_html_file&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;xdg-open&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;missing_hashes_html_file&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Upgrading indirect NuGet dependencies</title>
        <published>2022-02-15T00:00:00+00:00</published>
        <updated>2022-02-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2022/02/15/upgrading-indirect-nuget-dependencies/"/>
        <id>https://0x5.uk/2022/02/15/upgrading-indirect-nuget-dependencies/</id>
        
        <content type="html" xml:base="https://0x5.uk/2022/02/15/upgrading-indirect-nuget-dependencies/">&lt;h2 id=&quot;update-transitive-pinning&quot;&gt;Update - transitive pinning&lt;&#x2F;h2&gt;
&lt;p&gt;It seems microsoft have produced a solution to this problem, along with the long awaited solution-level package management. Read all about it here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;nuget&#x2F;introducing-central-package-management&#x2F;#transitive-pinning&quot;&gt;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;nuget&#x2F;introducing-central-package-management&#x2F;#transitive-pinning&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you want to convert to central package management this tool works a charm: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Webreaper&#x2F;CentralisedPackageConverter&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Webreaper&#x2F;CentralisedPackageConverter&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;dotnet&#x2F;comments&#x2F;vnayh9&#x2F;converting_a_large_project_to_central_package&#x2F;&quot;&gt;via reddit&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;about&quot;&gt;About&lt;&#x2F;h2&gt;
&lt;p&gt;The state of the art for dependency management in dotnet land. Having used ruby bundler and npm this makes me cry.&lt;&#x2F;p&gt;
&lt;p&gt;I really hope I&#x27;m massively wrong about the following information. Please do tell me if I&#x27;m wrong and NuGet dependency management is not actually as bad as this!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;paket-a-nuget-alternative&quot;&gt;Paket, a NuGet alternative&lt;&#x2F;h2&gt;
&lt;p&gt;If you have the option then look into replacing nuget with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fsprojects.github.io&#x2F;Paket&#x2F;&quot;&gt;paket&lt;&#x2F;a&gt; for your projects as I gather this has the below problems solved.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;indirect-dependencies&quot;&gt;Indirect dependencies&lt;&#x2F;h2&gt;
&lt;p&gt;Say you depend on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;Microsoft.AspNetCore.Http&#x2F;2.2.2&quot;&gt;Microsoft.AspNetCore.Http v2.2.2&lt;&#x2F;a&gt; (which is the latest available at time of writing), which in turn depends on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;Microsoft.AspNetCore.Http.Abstractions&#x2F;2.2.0&quot;&gt;Microsoft.AspNetCore.Http.Abstractions &amp;gt;= v2.2.0&lt;&#x2F;a&gt;  (also currently the latest) which in turn depends on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;System.Text.Encodings.Web&#x2F;4.5.0&quot;&gt;System.Text.Encodings.Web &amp;gt;= 4.5.0&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And then you discover, say, just for a fun example, that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dotnet&#x2F;announcements&#x2F;issues&#x2F;178&quot;&gt;System.Text.Encodings.Web v4.5.0 has the Remote Code Execution (RCE) Vulnerability CVE-2021-26701&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Thankfully Microsoft have released a patch release with a fix for the CVE: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;System.Text.Encodings.Web&#x2F;4.5.1&quot;&gt;System.Text.Encodings.Web v4.5.1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So obviously you&#x27;ll just upgrade your packages, run CI, make a cup of tea and ship to prod, right? Wrong.&lt;&#x2F;p&gt;
&lt;p&gt;But it says &lt;code&gt;&amp;gt;= 4.5.0&lt;&#x2F;code&gt;, so shurley it&#x27;d just upgrade it?...&lt;&#x2F;p&gt;
&lt;p&gt;Apparently not. It seems that for whatever reason nuget actually prefers the &lt;em&gt;lowest&lt;&#x2F;em&gt; compatible patch release. Go figure. So it won&#x27;t upgrade.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;checking-the-source-of-truth&quot;&gt;Checking the source of truth&lt;&#x2F;h3&gt;
&lt;p&gt;Because I&#x27;m starting to doubt my sanity at this point, let&#x27;s dive in to the source code for the middle package to make sure we&#x27;re not just being ignorant about how it actually works.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Microsoft.AspNetCore.Http.Abstractions&lt;&#x2F;code&gt; has abstracted out the version info for its dependencies to another file, you can see the defined version of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;aspnet&#x2F;HttpAbstractions&#x2F;blob&#x2F;release&#x2F;2.2&#x2F;build&#x2F;dependencies.props#L24&quot;&gt;...Encodings.Web dependency as at v2.2.0 here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;SystemTextEncodingsWebPackageVersion&amp;gt;4.5.0&amp;lt;&#x2F;SystemTextEncodingsWebPackageVersion&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which is then &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;aspnet&#x2F;HttpAbstractions&#x2F;blob&#x2F;release&#x2F;2.2&#x2F;src&#x2F;Microsoft.AspNetCore.Http.Abstractions&#x2F;Microsoft.AspNetCore.Http.Abstractions.csproj#L23&quot;&gt;referenced in the &lt;code&gt;.csproj&lt;&#x2F;code&gt; here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;PackageReference Include=&amp;quot;System.Text.Encodings.Web&amp;quot; Version=&amp;quot;$(SystemTextEncodingsWebPackageVersion)&amp;quot; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On the face of it you&#x27;d think that this meant it was pinned to an exact version, but microsoft in their infinite desire to pander to the lowest common denominator (i.e. idiots and n00bs) decided that &lt;code&gt;1.0&lt;&#x2F;code&gt; should actually mean &lt;code&gt;1.*&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Notation&lt;&#x2F;th&gt;&lt;th&gt;Applied rule&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1.0&lt;&#x2F;td&gt;&lt;td&gt;x ≥ 1.0&lt;&#x2F;td&gt;&lt;td&gt;Minimum version, inclusive&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Source: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;nuget&#x2F;concepts&#x2F;package-versioning#version-ranges&quot;&gt;NuGet version range definitions&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It doesn&#x27;t even define whether it will upgrade major, minor, or just patch releases. Horror-show.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lock-files&quot;&gt;lock files&lt;&#x2F;h2&gt;
&lt;p&gt;Lock files don&#x27;t actually help much here, but are a good idea, so if you want to use them here&#x27;s what I&#x27;ve learned about &lt;code&gt;packages.lock.json&lt;&#x2F;code&gt; files in Microsoft-land.&lt;&#x2F;p&gt;
&lt;p&gt;NuGet is veeeeeeeeeeery late to the lockfile game. A lockfile is just a second file that lists the dependency tree that was actually calculated for a given set of top level dependencies. Useful for repeatable builds and lets you see what&#x27;s being resolved, but doesn&#x27;t actually help fix the problem here as the point of lockfiles isn&#x27;t to manually futz with them, it&#x27;s just to do repeatable builds. And futzing with them would confuse everyone, and is made a little harder with the inclusion of checksums.&lt;&#x2F;p&gt;
&lt;p&gt;It is possible to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;nuget&#x2F;enable-repeatable-package-restores-using-a-lock-file&#x2F;&quot;&gt;manually enable lockfiles&lt;&#x2F;a&gt; by adding the following to a csproj file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PropertyGroup&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;RestorePackagesWithLockFile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;RestorePackagesWithLockFile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PropertyGroup&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I very much enjoyed &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NuGet&#x2F;Home&#x2F;issues&#x2F;5602#issuecomment-450269920&quot;&gt;this multi-comment rant at the NuGet team&lt;&#x2F;a&gt; for basically being behind the times and always making poor decisions.&lt;&#x2F;p&gt;
&lt;p&gt;There is a slightly harder problem that microsoft have so far failed to sort out of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NuGet&#x2F;Home&#x2F;wiki&#x2F;Centrally-managing-NuGet-package-versions&quot;&gt;managing packages across a whole solution&lt;&#x2F;a&gt; (i.e. multiple projects). Though I can&#x27;t help thinking that it&#x27;s mostly hard because of the mess they&#x27;ve allowed to build up so far. (For example encouraging people to create multiple solutions with a mix of project files included, and the horror that is the one-giant-tree TFS system.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;forcing-the-upgrade&quot;&gt;Forcing the upgrade&lt;&#x2F;h2&gt;
&lt;p&gt;So it seems the only way to force the upgrade of the vulnerable &quot;transient&quot; dependency (i.e. one not directly specified in your &lt;code&gt;.csproj&lt;&#x2F;code&gt; file) is to add it as an explicit dependency directly to the &lt;code&gt;.csproj&lt;&#x2F;code&gt; &lt;code&gt;PackageReference&lt;&#x2F;code&gt; entries. This is lame, and likely to cause confusion later. Make sure your commit message is clear as to why you&#x27;ve added this seemingly nonsense dependency.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;ItemGroup&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PackageReference&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; Include&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;System.Text.Encodings.Web &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; Version&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;4.5.1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;ItemGroup&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;getting-notified-of-dependency-updates&quot;&gt;Getting notified of dependency updates&lt;&#x2F;h2&gt;
&lt;p&gt;If you run any production code you can run an analysis tool like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;snyk.io&#x2F;&quot;&gt;Snyk.io&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dependabot&quot;&gt;dependabot&lt;&#x2F;a&gt; to check for such CVEs popping up in your dependency graph.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll probably want to install a local version of whatever you use to avoid the CI loop for every change you make, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=snyk-security.snyk-vulnerability-scanner&quot;&gt;snyk has a visual studio extension&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Phone setup notes</title>
        <published>2021-12-17T00:00:00+00:00</published>
        <updated>2021-12-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/12/17/phone-setup-notes/"/>
        <id>https://0x5.uk/2021/12/17/phone-setup-notes/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/12/17/phone-setup-notes/">&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;about&quot;&gt;About&lt;&#x2F;h2&gt;
&lt;p&gt;Well this makes a good counterpart to the &lt;a href=&quot;&#x2F;2019&#x2F;08&#x2F;20&#x2F;laptop-setup&#x2F;&quot;&gt;laptop setup post&lt;&#x2F;a&gt;. Similar idea, it&#x27;s just a place for me to keep track of all the things involved in building a new phone from scratch. This one also explains to people who look at me like I&#x27;m mad why I don&#x27;t just &quot;do what everyone else does&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-don-t-you-just&quot;&gt;Why don&#x27;t you just...?&lt;&#x2F;h2&gt;
&lt;p&gt;Most people don&#x27;t think their phone install deserves a blog post, or even a lot of thought beyond a visit to the Apple &quot;genius&quot; bar (lol) so they can push the &quot;copy everything to my new phone button&quot;. I&#x27;m not most people. I&#x27;ve been running Linux since approximately &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ubuntu_version_history#Ubuntu_5.04_(Hoary_Hedgehog)&quot;&gt;Ubuntu 5.04 Hoary Hedgehog&lt;&#x2F;a&gt; in 2005 (the brown one). Even while being a &quot;.NET developer&quot;, back when &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Halloween_documents&quot;&gt;Microsoft were still trying to simultaneously ignore and destroy Linux&lt;&#x2F;a&gt;. What strange times we live in now with dotnet being open source and cross-platform, has the leopard changed its spots?&lt;&#x2F;p&gt;
&lt;p&gt;There are many factors in this battle for the phone in your pocket.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The GPL&#x27;s fundamental truth is that there is a tension for control over your devices between the creators of software and the users of that software. iOS and Android both believe that the users can&#x27;t be trusted with full control over their device because &quot;security&quot;. I believe this balance of power is important. Too far in either direction and things start to go badly:
&lt;ul&gt;
&lt;li&gt;All the power in the hands of vendors at the expense of users results in exploitation, unfair pricing, anti-competitive practices, monopolies, duopolies (google+apple), cartels, and lack of innovation and quality due to lack of competition.&lt;&#x2F;li&gt;
&lt;li&gt;On the flip side all the power in the hands of &quot;users&quot; (or at least user-developers) as per the pure GPL and it becomes difficult or impossible for capitalist processes to fund innovation and engineering effort due to the inability to capture generated value.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The apps matter, I do actually want to use a phone for useful things, and increasingly web applications are a poor cousin to their equivalent apps. (Facebook, horror that it is, oscillates between making a browser unusable and making it just about possible to read and interact, they &lt;em&gt;really&lt;&#x2F;em&gt; want all that juicy extra data that you can get from being an installed app).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;iOS and Android both believe that users can&#x27;t be trusted with full control over their device&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This time in smartphones is a moment like my first linux install around the year 2006. I hated the main operating system (Windows) that I was locked in to. All the app[lication]s that I relied on (outlook, visual studio etc) were locked to the operating system I hated. And now in 2021 all the proprietary apps on phones are locked to android &#x2F; iOS (gmail, authenticator, waze, google maps, banking apps, whatsapp etc.)&lt;&#x2F;p&gt;
&lt;p&gt;I could just install OpenGApps or similar to get the google play store on top of a slightly more free android variant; then install all the proprietary apps again, or I could see just how much I can do without google services by using microG and open source alternative apps like k9mail and maps.me. I&#x27;ve already started this journey by trying out many free alternatives and think it&#x27;s worth pushing ahead. Running a build with no google services will be a good acid-test of how far I&#x27;ve got even if I have to go running back to the proprietary google services.&lt;&#x2F;p&gt;
&lt;p&gt;In my switch to Linux from Windows I just tried to do as much as I could with free software such as the gimp and thunderbird, often still installed on Windows, and then bit by bit I needed to fire up Windows less and less often as I found alternative apps and ways of doing things.&lt;&#x2F;p&gt;
&lt;p&gt;Any progress I can make here will make the jump to a fully free phone OS less painful in the future, and I&#x27;m increasingly confident that day will come just like I don&#x27;t think twice about running Linux Mint even for work these days.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nursing-homes-and-neighbourhoods&quot;&gt;Nursing Homes and Neighbourhoods&lt;&#x2F;h3&gt;
&lt;p&gt;I highly recommend reading this article - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;puri.sm&#x2F;posts&#x2F;the-future-of-computers-the-neighborhood-and-the-nursing-home&#x2F;&quot;&gt;Purism, The Future of Computers: The Neighborhood and The Nursing Home&lt;&#x2F;a&gt;. It wonderfully illustrates the binary choice between the apple&#x2F;google duopoly and the DIY open source and privacy movement with the rather apt analogy of nursing homes (apple etc where your needs are met but you give up control of your environment) and neighbourhoods (open source where it&#x27;s up to you not let the wrong people in to renovate your house).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-not-just-apple-ios&quot;&gt;Why not just Apple iOS?&lt;&#x2F;h3&gt;
&lt;p&gt;Yes I know the iPhone crowd can just push a button on the new phone and have it look like the old phone, but iOS is the polar opposite of what I want my technology to be: under &lt;em&gt;my&lt;&#x2F;em&gt; control. That means root. That means open source. That means GPL.&lt;&#x2F;p&gt;
&lt;p&gt;iOS certainly does have some unique advantages that I will be sad to miss out on but not sad enough to give up all the other things I care about.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;ios-the-good&quot;&gt;iOS, the good&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;A secure boot chain, remarkably hacker-proof - even with physical device access which is very impressive.&lt;&#x2F;li&gt;
&lt;li&gt;Impressively effective device-to-device migration of user settings and data (android failed miserably at this in my experiments)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;ios-the-dubious-to-bad&quot;&gt;iOS, the dubious-to-bad&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Complete reliance on a single vendor for looking after all your precious &quot;data&quot;. This in my view is risky no matter how good the vendor is.
&lt;ul&gt;
&lt;li&gt;In 2012 this was demonstrated as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.wired.com&#x2F;2012&#x2F;08&#x2F;apple-amazon-mat-honan-hacking&#x2F;&quot;&gt;Mat Honan had &lt;em&gt;all&lt;&#x2F;em&gt; his data and devices wiped and locked remotely when a hacker took over his Apple account&lt;&#x2F;a&gt;, and he had no other copy of all his precious family photos. A cautionary tale for all of us.&lt;&#x2F;li&gt;
&lt;li&gt;Someone I know lost everything on their iPhone when the OS upgrade process somehow managed to do the following:
&lt;ol&gt;
&lt;li&gt;backup the phone to the iCloud&lt;&#x2F;li&gt;
&lt;li&gt;wipe the phone and install the updated iOS (I understand this is normal procedure)&lt;&#x2F;li&gt;
&lt;li&gt;back up the blank phone to iCloud &lt;em&gt;overwriting&lt;&#x2F;em&gt; the only backup (apparently there was only a single slot)&lt;&#x2F;li&gt;
&lt;li&gt;restore the blank backup to the updated phone&lt;&#x2F;li&gt;
&lt;li&gt;declare success, leaving my friend with all his data gone and a factory-installed OS&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;No root (a problem for syncthing, independent backups and general user-control)&lt;&#x2F;li&gt;
&lt;li&gt;No user-replaceable OS (aka ROM)&lt;&#x2F;li&gt;
&lt;li&gt;No open source&lt;&#x2F;li&gt;
&lt;li&gt;All the apps cost more!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;why-not-just-stock-android&quot;&gt;Why not just stock android?&lt;&#x2F;h3&gt;
&lt;p&gt;&quot;So you must be an android dude then&quot; you say. Well no because frankly android isn&#x27;t much better these days. Ever heard of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;source.android.com&#x2F;&quot;&gt;AOSP? (The Android Open Source Project)&lt;&#x2F;a&gt; Well that&#x27;s an ever-shrinking piece of what people call Android these days. Piece by piece &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arstechnica.com&#x2F;gadgets&#x2F;2018&#x2F;07&#x2F;googles-iron-grip-on-android-controlling-open-source-by-any-means-necessary&#x2F;&quot;&gt;google have been replacing open-source android with proprietary rewrites&lt;&#x2F;a&gt;. Combine that with proprietary drivers for the endless churn in hardware. If you can even install ASOP on a device good luck getting much to work. The idea of android being &quot;the open source one&quot; in the true spirit of the GPL is a distant and fading memory.&lt;&#x2F;p&gt;
&lt;p&gt;There is a cartel of industry players called the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Open_Handset_Alliance&quot;&gt;Open Handset Alliance&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.openhandsetalliance.com&#x2F;index.html&quot;&gt;http:&#x2F;&#x2F;www.openhandsetalliance.com&#x2F;index.html&lt;&#x2F;a&gt;. These industry groups can be good but I think in this case they are a barrier to innovation and openness.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;OHA members are contractually forbidden from producing devices that are based on competing forks of Android&quot;&lt;br &#x2F;&gt;
~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Open_Handset_Alliance&quot;&gt;Wikipedia on OHA&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arstechnica.com&#x2F;gadgets&#x2F;2018&#x2F;07&#x2F;googles-iron-grip-on-android-controlling-open-source-by-any-means-necessary&#x2F;&quot;&gt;Ars Technica: &quot;Google’s iron grip on Android: Controlling open source by any means necessary&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;root-and-backups&quot;&gt;Root and backups&lt;&#x2F;h4&gt;
&lt;p&gt;One of the big drivers I&#x27;ve had for getting a non-standard phone setup is that I don&#x27;t want to rely on on google to backup everything on my phone in case it dies, but because Android is by default locked in by secure boot and doesn&#x27;t give the user any root access or ability to get root access that&#x27;s a bit of a problem for the normal method of backing up a device.&lt;&#x2F;p&gt;
&lt;p&gt;A laptop backup is a question of backing up &lt;code&gt;&#x2F;home&lt;&#x2F;code&gt; plus a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&quot;&gt;dotmatrix&#x2F;bootstrap&lt;&#x2F;a&gt; setup for regaining interesting configuration etc.&lt;&#x2F;p&gt;
&lt;p&gt;Android is a bit more complex because it has a couple of storage areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;an [emulated] &#x27;sdcard&#x27; this is kinda like &lt;code&gt;&#x2F;home&lt;&#x2F;code&gt; on a laptop and has things like downloaded files; some of the apps use this to save things to&lt;&#x2F;li&gt;
&lt;li&gt;storage for every individual app (I learned about the existence of this by losing all my app data)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Every app on android runs under a separate userId, which allows Android to ensure that apps can&#x27;t read each other&#x27;s data. This is a good thing for security, but that means if you install a &quot;backup app&quot; it can&#x27;t read any of the data you actually want backed up. And it can&#x27;t get root because that&#x27;s not available to you as a user or to any non-system apps.&lt;&#x2F;p&gt;
&lt;p&gt;So that means to backup independently of google, you need root, and to get root you need to unlock the whole boot chain.&lt;&#x2F;p&gt;
&lt;p&gt;I did have root on my OnePlus 5t, but an operating system update helpfully removed that for me... breaking my backups... and root access couldn&#x27;t be restored without wiping the phone... including the data I didn&#x27;t have backed up because it had broken my backups. Gah. Off the back of that experience I want to make sure that I&#x27;m not set up to fight some bloody vendor that doesn&#x27;t believe I should have root.&lt;&#x2F;p&gt;
&lt;p&gt;Any hope of an effective root is dwindling. According to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.androidpolice.com&#x2F;a-new-method-for-hiding-root-in-magisk-may-soon-emerge&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.androidpolice.com&#x2F;a-new-method-for-hiding-root-in-magisk-may-soon-emerge&#x2F;&lt;&#x2F;a&gt; the developer of Magisk Hide that prevented root being detected and thus allowed shitty apps to continue to be run has been &lt;em&gt;hired by google&lt;&#x2F;em&gt;. That&#x27;s google following the advice of &quot;keep friends close, keep your enemies closer&quot; close if ever I&#x27;ve seen it. No better way to shut the project down than to pay off the developer with a &quot;salary&quot;. Cough.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;something-other-than-ios-or-android-and-its-derivatives&quot;&gt;Something other than iOS or Android and its derivatives?&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s all about the apps.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;An operating system is not that useful on its own.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;There&#x27;s a reason &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=KMU0tzLwhbE&quot;&gt;Ballmer shouted &quot;developers developers developers&quot;&lt;&#x2F;a&gt; (amusing as this meme has become in the abstract). An operating system is not that useful on its own. Operating systems live and die by the applications (aka apps) available on them, and the utility and value they in turn bring to their users.&lt;&#x2F;p&gt;
&lt;p&gt;iOS and Android have utterly captured the app market on phones, creating a duopoly in the phone space.&lt;&#x2F;p&gt;
&lt;p&gt;Even the mighty Nokia (with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Symbian&quot;&gt;Symbian&lt;&#x2F;a&gt;), &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;BlackBerry_10&quot;&gt;Research In Motion (RIM) with Blackberry&lt;&#x2F;a&gt;&lt;code&gt;*&lt;&#x2F;code&gt; and Microsoft with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Windows_Phone&quot;&gt;Windows Phone&lt;&#x2F;a&gt; failed to win against them and eventually threw in the towel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;*&lt;&#x2F;code&gt; Blackberry seems to have all but fallen off the radar, they started shipping android in the end basically being a android phone with a physical keyboard thus becoming part of the apple-google duopoloy..&lt;&#x2F;p&gt;
&lt;p&gt;So for me that rules out for the time being all the Linux based phones such as a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shop.puri.sm&#x2F;shop&#x2F;librem-5&#x2F;&quot;&gt;Librem 5 running PureOS&lt;&#x2F;a&gt;. (See below).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;It&#x27;s only when alternatives like Librem&#x2F;PureOS gain traction that we&#x27;ll see the makers of apps, websites and phones have to create and adopt open standards that allow further diversity and innovation.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The fact the Librem exists and seems to be sustainable are encouraging signs for the breaking of the google+apple duopoly on mobiles. It&#x27;s only when alternatives like Librem&#x2F;PureOS gain traction that we&#x27;ll see the makers of apps, websites and phones have to create and adopt open standards that allow further diversity and innovation. Currently we are seeing a repeat of the &quot;works best in Netscape &#x2F; Internet Explorer&quot; duopoly of the browser wars that was eventually broken forever by Firefox, Opera and friends forcing websites to stop using proprietary extensions and stick to open standards.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;dearly-departed&quot;&gt;Dearly departed&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;nokia-symbian&quot;&gt;Nokia &#x2F; Symbian&lt;&#x2F;h5&gt;
&lt;p&gt;Symbian was briefly ahead on features as an OS in my opinion. I had a Sony Ericsson &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sony_Ericsson_P800&quot;&gt;P800&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sony_Ericsson_P910&quot;&gt;P910&lt;&#x2F;a&gt; and in their day they were &lt;em&gt;almost&lt;&#x2F;em&gt; amazing phones, hampered by lacking hardware (2g at the dawn of 3g, serial port connectivity emulated over usb, and for god knows what reason Sony were still trying to beat SD cards with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Memory_Stick&quot;&gt;memory stick&lt;&#x2F;a&gt;). Consumers flocked away from them in droves to the new iPhone.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;microsoft-windows-phone-os&quot;&gt;Microsoft &#x2F; Windows Phone OS&lt;&#x2F;h5&gt;
&lt;p&gt;Microsoft&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theverge.com&#x2F;2017&#x2F;10&#x2F;10&#x2F;16452162&#x2F;windows-phone-history-glorious-failure&quot;&gt;&quot;Windows Phone&quot; was a triumph of a phone operating system&lt;&#x2F;a&gt;, and everyone I knew that had one absolutely loved the operating system. But &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theverge.com&#x2F;2015&#x2F;10&#x2F;23&#x2F;9602350&#x2F;microsoft-windows-phone-app-removal-windows-store&quot;&gt;Microsoft just couldn&#x27;t persuade the big-name mobile-app developers&lt;&#x2F;a&gt; (i.e. companies) to invest the endless effort required to create and maintain a third version of their apps for another app store.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;openmoko-neo-freerunner&quot;&gt;OpenMoko &#x2F; Neo FreeRunner&lt;&#x2F;h5&gt;
&lt;p&gt;I had high hopes for the truly open Neo running OpenMoko, but it didn&#x27;t stand a hope in hell amongst the rapidly evolving tech and software at the time. I bought the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Openmoko#Neo_FreeRunner&quot;&gt;Neo FreeRunner&lt;&#x2F;a&gt; and it was an exciting time, but it quickly became a relic.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;cyanogenmod&quot;&gt;CyanogenMod&lt;&#x2F;h5&gt;
&lt;p&gt;After many years of being the goto android-variant mobile OS for non-conformists, sadly &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;CyanogenMod&quot;&gt;CyanogenMod&lt;&#x2F;a&gt; imploded in 2016. The code lives on in LineageOS (see below).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;promising-futures&quot;&gt;Promising futures&lt;&#x2F;h4&gt;
&lt;p&gt;Two currently active non-android physical phone projects, and several more ongoing Linux based (i.e. non-android) mobile-friendly operating system efforts. Although these will never cross the radar of most people just like Linux didn&#x27;t for many years) these are important foundational projects.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;purism-s-librem-5-phone-hardware-running-pureos-linux&quot;&gt;Purism&#x27;s Librem 5 phone hardware running PureOS (Linux)&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shop.puri.sm&#x2F;shop&#x2F;librem-5&#x2F;&quot;&gt;Librem 5 phone&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pureos.net&#x2F;&quot;&gt;PureOS&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shop.puri.sm&#x2F;shop&#x2F;librem-5&#x2F;&quot;&gt;Librem 5&lt;&#x2F;a&gt; is worth a look if you want to take it to the next level of openness, however it comes with a compromise in specifications, a hefty price tag (inevitable due to lower production volumes) and no android &#x2F; iOS apps.&lt;&#x2F;p&gt;
&lt;p&gt;You might however want to consider spending your dollars as a vote for the future you want to see.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;puri.sm&#x2F;products&#x2F;librem-5&#x2F;pureos-mobile&#x2F;&quot;&gt;Librem 5 runs Linux (PureOS), not Android&lt;&#x2F;a&gt;. This is great but as of 2021 does mean it suffers from the &quot;app&quot; problem (see above).&lt;&#x2F;p&gt;
&lt;p&gt;Because of the &quot;app&quot; problem I&#x27;m not ready to make the jump to a Linux based smartphone that can&#x27;t run android apps. I&#x27;m also not particularly keen to drop quite this much in specification for the benefit.&lt;&#x2F;p&gt;
&lt;p&gt;Personally I&#x27;m happy with the OnePlus compromise of specification plus apps versus openness for now, but I&#x27;m very glad to see Purism pushing the frontier of openness and maybe I&#x27;ll join their users one day.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;pinephone-pro-phone-hardware-linux-for-now&quot;&gt;PinePhone Pro phone hardware (Linux, for now)&lt;&#x2F;h5&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pine64.org&#x2F;pinephonepro&#x2F;&quot;&gt;PinePhone Pro&lt;&#x2F;a&gt; is a low spec but very open Linux phone. A follow up to the original PinePhone.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;pre-orders from developers on October 15, 2021, and expect to have them delivered by December&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Phones like this are important in building momentum in the capability of non iOS&#x2F;Android software even though they will never be mainstream phones themselves.&lt;&#x2F;p&gt;
&lt;p&gt;This is a Linux phone, though in theory &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;glodroid.github.io&#x2F;&quot;&gt;GloDroid&lt;&#x2F;a&gt; will provide a build of Android (AOSP) for it, but don&#x27;t hold your breath. - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.omgubuntu.co.uk&#x2F;2020&#x2F;07&#x2F;glodroid-android-for-pinephone-allwinner&quot;&gt;OmgUbuntu article on PinePhone+GloDroid&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;ubports-ubuntu-phone-linux&quot;&gt;UBPorts Ubuntu Phone (Linux)&lt;&#x2F;h5&gt;
&lt;p&gt;Canonical killed the Ubuntu Phone and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ubuntu_Touch&quot;&gt;Ubuntu Touch&lt;&#x2F;a&gt; operating system, but the software lives on in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ubports.com&#x2F;&quot;&gt;ubports&lt;&#x2F;a&gt;. (Presumably that&#x27;s short for UBuntu Ports)&lt;&#x2F;p&gt;
&lt;h5 id=&quot;plasma-linux-kde-for-phones&quot;&gt;Plasma (Linux KDE for phones)&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;plasma-mobile.org&#x2F;&quot;&gt;Plasma Mobile&lt;&#x2F;a&gt; is a variant of the KDE Plamsa desktop specifically for mobiles.&lt;&#x2F;p&gt;
&lt;p&gt;Learn more about &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Plasma_Mobile&quot;&gt;Plasma on Wikipedia&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h5 id=&quot;mobian-debian-linux-for-phones&quot;&gt;Mobian - (Debian Linux for phones)&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mobian-project.org&#x2F;&quot;&gt;Mobian&lt;&#x2F;a&gt; is encouraging to see. Debian Linux&#x27;s strenth has always been its governance and stability. Debian has been a rock in the stormy seas of open source even as different people have passed through its team. This is because debian has a strong set of organisational rules that are above and beyond any individual contributor. The fact that they are working on a mobile variant is very encouraging.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;postmarketos-linux&quot;&gt;PostmarketOS (Linux)&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;postmarketos.org&#x2F;&quot;&gt;PostmarketOS&lt;&#x2F;a&gt; is an Alpine Linux (i.e. very small) variation designed to breath life into otherwise obsolete hardware. I expect this will become more useful as phone hardware stops becoming utterly obsolete due to major changes in basic expectations and environment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;secure-boot&quot;&gt;Secure boot&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s the secure boot chain and device locking. This can be a good thing or a bad thing depending on the power dynamic between users and providers (and maybe even the state&#x2F;government).&lt;&#x2F;p&gt;
&lt;p&gt;It is true that your device is less &quot;secure&quot; with the bootloader unlocked (as the phone likes to scream at you every time you boot it up), at least to attackers with physical access to your device, however I think that&#x27;s worth the trade for full control of your device (that you paid for and &quot;own&quot;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.isaca.org&#x2F;resources&#x2F;isaca-journal&#x2F;issues&#x2F;2021&#x2F;volume-6&#x2F;evidence-based-prioritization-of-cybersecurity-threats&quot;&gt;Security is not an absolute&lt;&#x2F;a&gt;. You have to consider cost, inconvenience, human behaviour, the value of an attack target, the motivations of different actors (state, organised crime, hackers, opportunist thieves, trolling friends etc). For me an encrypted data partition and a passcode will do for physical security. In theory you can get full secure boot chain for custom operating systems but even on a Linux laptop this is non-trivial currently.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s an important difference here between google&#x2F;apple considering the security of their entire device eco-system in the hands of every kind of user, and the security of an individual&#x27;s device customised to suit them. If google turn off secure boot for everyone then it makes it that much more likely that someone will successfully develop and spread an android virus that corrupts the boot chain. If I turn it of it&#x27;s a rounding error on the probability, and a marginal difference to the &quot;security&quot; of my own device.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;apple-s-secure-boot-chain&quot;&gt;Apple&#x27;s secure boot chain&lt;&#x2F;h3&gt;
&lt;p&gt;Apple don&#x27;t want you to fiddle with the OS they control, so you don&#x27;t get to touch it without &quot;jailbreaking&quot; it. Jailbreaking is done by exploiting a security flaw, and it&#x27;s a cat and mouse game with Apple fixing bugs to close holes and hackers finding new ones to regain control of the devices. Not a game I want to play just to have control over my own hardware. This 100% rules out iOS for me, it&#x27;s a complete dealbreaker. No matter how shiny, how bug free, how capable it is I wouldn&#x27;t trade unless there was absolutely no alternative.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;android-s-secure-boot-chain&quot;&gt;Android&#x27;s secure boot chain&lt;&#x2F;h3&gt;
&lt;p&gt;Android also secure their boot chain by default, however whether you can unlock it and flash a different recovery&#x2F;bootloader&#x2F;OS&#x2F;ROM depends on the phone manufacturer, individual device, and sometimes the phone network provider (aka locking&#x2F;unlocking).&lt;&#x2F;p&gt;
&lt;p&gt;This means choose your device and provider carefully if you wish to unlock without wasting your time trying to jailbreaking a locked device.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;artificial-app-limitations-when-unlocked&quot;&gt;Artificial app limitations when unlocked&lt;&#x2F;h3&gt;
&lt;p&gt;Android has a system that allows apps to hide or limit functionality called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.lineageos.org&#x2F;Safetynet&#x2F;&quot;&gt;SafetyNet&lt;&#x2F;a&gt;. For apps like NetFlix that won&#x27;t even show in the play store for unlocked phones we&#x27;re into the mega-discussion that is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Digital_rights_management&quot;&gt;DRM&lt;&#x2F;a&gt;. In short if a content creator wants to lock their device to a locked-down platform that&#x27;s fine be me but I won&#x27;t be using those platforms for my main computing, instead I might have them as throw-away additional appliances like the google chromecast, or samsung TV&#x27;s built in junk. What really matters here is what alternatives you have available to you. For google pay, I&#x27;m very slightly sad to miss out but my contactless debit card still works fine so I&#x27;ll live.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hardware-choices&quot;&gt;Hardware choices&lt;&#x2F;h2&gt;
&lt;p&gt;Given the &quot;app&quot; problem, any devices not capable of running Android or a derivative are currently out of the running (sad times).&lt;&#x2F;p&gt;
&lt;p&gt;A non-negotiable for me is manufacturer support for replacing the bootloader and everything above that (OS, apps). This ensures the life of the device beyond the point at which the manufacturer loses interest or does something horrific&#x2F;stupid. This is also a signal for who is truly in charge of the device once it&#x27;s &quot;yours&quot; - you the user or the supplier and their developers. By locking you out of making modifications it&#x27;s a clear signal that you are not to be trusted with the power over your own device.&lt;&#x2F;p&gt;
&lt;p&gt;As the useful innovation in hardware slows down (2G to 3G was a big jump, but 8-megapixels camera to 32-megapixel cameras is less foundational) it will be less often that devices will become obsolete through huge leaps in capability. It will also mean that phone hardware will inevitably become more commodity and less proprietary, giving a chance for more open standards to get a foothold (just as x86 replace proprietary CPU architectures many decades ago), while still being acceptably capable. We shouldn&#x27;t be throwing out devices because the manufacturer decided not to provide security patches for their OS variant, and certainly not because the manufacturer took away a feature we like through forced updates.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;google-nexus-pixel-meh&quot;&gt;Google Nexus &#x2F; Pixel (meh)&lt;&#x2F;h3&gt;
&lt;p&gt;I have run a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Google_phone&quot;&gt;google nexus&lt;&#x2F;a&gt; 4 previously which was flashable and rootable, but long since obsolete in hardware capabilities (and suffered a hardware failure). I never looked back at the google line after I discovered OnePlus, I can&#x27;t comment on whether the current pixel phones are a good device for my constraints. I don&#x27;t particularly want to further feed the beast. If you want the authentic pure google experience I guess these are probably worth a look but the pure google experience seems less and less appealing as the years roll on.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sony-yuck&quot;&gt;Sony (yuck)&lt;&#x2F;h3&gt;
&lt;p&gt;Someone told me that a particular Sony phone was flashable, I researched it, found instructions on flashing it, ordered one... and couldn&#x27;t flash it. Discussing with Sony support it transpired that that precise model was sometimes flashable and sometimes not, and the only way to find out was to order one and look at the serial number. Fuck you Sony. They never have understood the open source movement and look like they still don&#x27;t. They always treated their kit like appliances not a blend of hardware and software (or firmware) with everything that means for the long term management of the software. It&#x27;s a shame because they do make nice hardware. I&#x27;d still buy a dumb Sony audio amplifier but not much else of theirs. Returned and refunded, try again...&lt;&#x2F;p&gt;
&lt;h3 id=&quot;oneplus-yay-no-wait-boo&quot;&gt;OnePlus (yay, no wait, boo)&lt;&#x2F;h3&gt;
&lt;p&gt;This is my choice for the new &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.oneplus.com&#x2F;uk&#x2F;9-pro&quot;&gt;OnePlus 9 Pro&lt;&#x2F;a&gt; I&#x27;m trying to set up, and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.oneplus.com&#x2F;uk&#x2F;support&#x2F;spec&#x2F;oneplus-5t&quot;&gt;OnePlus 5T&lt;&#x2F;a&gt; I&#x27;ve been using for more than a couple of years now.&lt;&#x2F;p&gt;
&lt;p&gt;They don&#x27;t make the grade for the pure &quot;everything must be open including chip bytecode and chip architecture&quot; as they use proprietary chips, but they make the right balance for me of reasonably high spec hardware for a reasonable price, android compatibility, and the ability to flash whatever ROM&#x2F;OS you like (at your own risk).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been running a OnePlus 5t for a while now (bought outright, no network lockin or contract nonsense) and generally happy enough with it. There are some bugs and storage is starting to constrain hence the upgrade, plus the camera could be better by modern standards and I don&#x27;t fancy carrying a separate camera.&lt;&#x2F;p&gt;
&lt;p&gt;I now have had the OnePlus 9 Pro sat in a drawer for two months waiting for me to figure out what-the-&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Flying_Spaghetti_Monster&quot;&gt;FSM&lt;&#x2F;a&gt; to run on it, hence this blog post. It&#x27;s already been unlocked and I&#x27;ve tried flashing a couple of things but am not happy with the setup yet. I stopped looking at it while I concentrated all my efforts on making sure my business was going in the right direction (or any direction at all).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;To get root you have to wipe the phone&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The OnePlus comes with OxygenOS (an android derivative) preinstalled, but not rooted and with a locked bootloader. To get root you have to wipe the phone which means it&#x27;s important to do it before you start using it. It&#x27;s caused me no end of pain that you can&#x27;t use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.titaniumtrack.com&#x2F;titanium-backup.html&quot;&gt;titanium backup&lt;&#x2F;a&gt; to backup all your data without root, and you can&#x27;t get root without losing your files. I understand why (so you can&#x27;t just unlock a phone to steal all the data) but that doesn&#x27;t make it less of a pain in the arse. Bonus points for operating system updates (over the air &#x2F; OTA or just normal updates) de-root the phone.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;oneplus-9&#x2F;&quot;&gt;XDA Developers detailed page on the OnePlus 9 including pro&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;But wait, there&#x27;s trouble in paradise.&lt;&#x2F;p&gt;
&lt;p&gt;The founder &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;techcrunch.com&#x2F;2020&#x2F;10&#x2F;16&#x2F;oneplus-co-founder-carl-pei-confirms-he-has-left-the-company&#x2F;&quot;&gt;Carl Pei left OnePlus in 2020&lt;&#x2F;a&gt; after 7 years at the company.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.androidauthority.com&#x2F;oneplus-oppo-design-894687&#x2F;&quot;&gt;OnePlus was funded by an existing phone company called Oppo&lt;&#x2F;a&gt;. (And &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.androidauthority.com&#x2F;oneplus-oppo-1177898&#x2F;&quot;&gt;both OnePlus and Oppo are part of BBK&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;It seems that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.androidauthority.com&#x2F;oneplus-oppo-complete-opinion-3025477&#x2F;&quot;&gt;OnePlus is basically now dead in the water&lt;&#x2F;a&gt; as a brand if not a company in its own right and will be sucked back into whatever the mothership has to offer, breaking everything along the way by trying to merge Oppo&#x27;s colorOS with OnePlus&#x27;s OxygenOS into an unholy mess.&lt;&#x2F;p&gt;
&lt;p&gt;Fuck.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;As if that wasn&#x27;t enough:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;OnePlus is adding artificial limitations and breaking features via software updates, and there are no indications that they&#x27;ll improve.&quot; ~ GCam Hub, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.celsoazevedo.com&#x2F;files&#x2F;android&#x2F;google-camera&#x2F;f&#x2F;post-05&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.celsoazevedo.com&#x2F;files&#x2F;android&#x2F;google-camera&#x2F;f&#x2F;post-05&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;It turns out that the founder of OnePlus, Carl Pei, has set up a new company called &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nothing.tech&#x2F;&quot;&gt;Nothing&lt;&#x2F;a&gt;&quot; (enjoy googling that one), which did just make headphones (unexciting), but who have just announced a phone. So maybe this is the true successor to the likely dead OnePlus brand. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theverge.com&#x2F;2022&#x2F;3&#x2F;23&#x2F;22992424&#x2F;nothing-phone-1-smartphone-carl-pei-apple-ecosystem&quot;&gt;https:&#x2F;&#x2F;www.theverge.com&#x2F;2022&#x2F;3&#x2F;23&#x2F;22992424&#x2F;nothing-phone-1-smartphone-carl-pei-apple-ecosystem&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;so-what-os-options-does-that-leave&quot;&gt;So what OS options does that leave?&lt;&#x2F;h2&gt;
&lt;p&gt;So not iOS and preferably not Android either.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately the apps mean that I&#x27;m stuck with Android and its derivatives for the time being.&lt;&#x2F;p&gt;
&lt;p&gt;It seems the best hope for salvation is the Linux based options discussed above eventually getting sufficient app coverage to make the jump more bearable, or maybe even some kind of android emulation allowing them to run android apps sufficiently well. The path from Windows to Linux for me included a mix of dual-boot, virtualization and wine (an api compatibility layer, not an emulator)&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s worth mentioning that some (most&#x2F;all?) phone manufacturers make proprietary customizations to Android or even complete &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fork_(software_development)&quot;&gt;forks&lt;&#x2F;a&gt; that you may or may not want. Samsung for example (for the Galaxy line of phones) replaces the &quot;launcher&quot; with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Samsung_Experience&quot;&gt;&quot;Samsung Experience&quot;&lt;&#x2F;a&gt;. I&#x27;m going for more open rather than less, so I&#x27;m not interested in trading slickness for losing even more control. I just want a platform that runs the apps I care about and is as open as possible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;researching-the-options&quot;&gt;Researching the options&lt;&#x2F;h3&gt;
&lt;p&gt;I don&#x27;t follow this stuff all the time so I had to do some googling (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duckduckgo.com&#x2F;&quot;&gt;duckduckgo&lt;&#x2F;a&gt;-ing). Here&#x27;s some useful comparisons I turned up:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;itsfoss.com&#x2F;open-source-alternatives-android&#x2F;&quot;&gt;It&#x27;s FOSS, Open Source Mobile OS Alternatives To Android&lt;&#x2F;a&gt; - mostly pure Linux things that don&#x27;t have the android app ecosystem&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;uk.pcmag.com&#x2F;linux&#x2F;131295&#x2F;break-away-from-android-7-free-open-source-mobile-oses-to-try&quot;&gt;PC Magazine, Break Away From Android: 7 Free Open-Source Mobile OSes to Try&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;best-custom-rom-oneplus-9-pro&#x2F;&quot;&gt;GetDroidTips has some more ROMs I haven&#x27;t looked at&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I&#x27;ve got more to learn&#x2F;research here so I&#x27;ll expand this section as and when I learn more. Think of this as a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.webopedia.com&#x2F;definitions&#x2F;bliki&#x2F;&quot;&gt;bliki&lt;&#x2F;a&gt;. There&#x27;s a full history in git (link at end).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;towering-stacks-of-patches&quot;&gt;Towering stacks of patches&lt;&#x2F;h3&gt;
&lt;p&gt;The below are probably the most realistic alternatives to stock Android and iOS for those who want more openness but don&#x27;t want to give up all the modern conveniences in the name of openness and&#x2F;or privacy. They are however all customizations of Android and that brings a very real problem.&lt;&#x2F;p&gt;
&lt;p&gt;The core open &quot;Android Open Source Project (AOSP)&quot; is run by google for google&#x27;s benefit and for their own Android ecosystem. There is significant engineering effort continually poured in to this, with major releases made on remarkably short timelines.&lt;&#x2F;p&gt;
&lt;p&gt;Any project that makes a customization to AOSP such as LineageOS and keeps track of it in their own fork is constantly at the mercy of changes to the foundation it has been based on, a foundation which really has no reason to care about them.&lt;&#x2F;p&gt;
&lt;p&gt;This creates a never ending challenge that stunts innovation outside the Android&#x2F;iOS duopoly. If you build a significant customization, it will sooner or later be broken and need re-engineering because of changes in AOSP, or maybe even be impossible to resurrect. The more you innovate and customize, the more engineering fire-power is required just to stand still on the treadmill of change in the platform.&lt;&#x2F;p&gt;
&lt;p&gt;While we have good tools for managing all this complexity (git, gerrit) this is a fundamental and unavoidable problem with building on a platform that doesn&#x27;t care about you.&lt;&#x2F;p&gt;
&lt;p&gt;Contrast that with the Linux ecosystem where the platforms people are building on (consisting of many many layers and teams) are much more interested in supporting downstream projects and allowing choice. Projects that run on Linux can often run with minimal modification for decades. Linux is also not built for the benefit of some particular vendor like google with their own agenda, it is instead run by a foundation with far more broad interests and pressures.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;android-derivative-options&quot;&gt;Android derivative options&lt;&#x2F;h3&gt;
&lt;p&gt;I now need to look into the below and decide what to run (maybe with some trial flashing). Once that&#x27;s done it&#x27;ll be on to the slog of setting up the actual device how I want it.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;oxygenos-from-oneplus-used-to-be-good-now-dying-a-painful-death&quot;&gt;OxygenOS from OnePlus - used to be good, now dying a painful death&lt;&#x2F;h4&gt;
&lt;p&gt;See the section on OnePlus hardware above. The company and OS are in trouble now the founder has left and the operating system has been merged with Oppo&#x27;s colorOS (read &quot;fucked&quot;)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.oneplus.com&#x2F;uk&#x2F;oxygenos&quot;&gt;https:&#x2F;&#x2F;www.oneplus.com&#x2F;uk&#x2F;oxygenos&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is the default for the OnePlus device I have, which means it&#x27;s the most likely to make the hardware perform at its best.&lt;&#x2F;p&gt;
&lt;p&gt;After a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theverge.com&#x2F;circuitbreaker&#x2F;2017&#x2F;10&#x2F;11&#x2F;16457954&#x2F;oneplus-phones-collecting-sensitive-data&quot;&gt;wobble on data reporting&lt;&#x2F;a&gt; (which I&#x27;m not too bothered about) they seem to have largely sorted out their privacy game... apart from being full of google services just like the rest of the mainstream android devices. To play or not to play...&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.chrisdcmoore.co.uk&#x2F;post&#x2F;oneplus-analytics&#x2F;&quot;&gt;the original article disclosing OnePlus silently sending data home&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It seems the latest news is that Oxygen is falling apart. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;oneplus-9-oxygenos-12-stable-update-bugs&#x2F;&quot;&gt;XDA Developers: &quot;OxygenOS 12 for the OnePlus 9 series is littered with bugs&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;It was shit after merge with #Oppo and getting worst day by day. I really like #OnePlus device but #OxygenOS is dead now.&quot; ~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;rahulawanjari&#x2F;status&#x2F;1468885793691168771?s=20&quot;&gt;@rahulawanjari, 9 Dec 2021, twitter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Crap, there goes another good option. As if the mobile phone space wasn&#x27;t horrific enough already.&lt;&#x2F;p&gt;
&lt;p&gt;In fact OxygenOS 12 was so bad, that they&#x27;ve just &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.androidpolice.com&#x2F;oneplus-is-pulling-its-oxygenos-12-update-for-the-op-9-and-9-pro&#x2F;&quot;&gt;OnePlus pulled the plug on the entire OxygenOS 12 upgrade!!&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bonus points for the anti-competitive practice of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gizmochina.com&#x2F;2021&#x2F;12&#x2F;13&#x2F;oxygenos-12-blocks-access-to-auxiliary-cameras-on-third-party-camera-apps&#x2F;&quot;&gt;actively denying access to hardware features (secondary cameras)&lt;&#x2F;a&gt;. I hope the courts slap them down for this clearly anti-competitive behaviour.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;So after discovering that shit-show-in-paradise from OnePlus I could potentially skip OxygenOS 12 and stick to the less f*cked OxygenOS 11, but that doesn&#x27;t seem like much of a plan so it looks like I&#x27;ll be skipping any fancy hardware capability and looking for a more open and less broken Android variant. Yet more proof that corporations can&#x27;t be trusted as guardians of our software for the long term without GPL or at least MIT to stop them from hurting their users sooner or later. Did I mention my podcast is called &quot;Software Should Be Free&quot;. Does this horror show give you a hint as to why it&#x27;s called that?&lt;&#x2F;p&gt;
&lt;h4 id=&quot;lineageos-yep&quot;&gt;LineageOS (yep)&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lineageos.org&#x2F;&quot;&gt;LineageOS&lt;&#x2F;a&gt; is the successor to the now defunct CyanogenMod. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;LineageOS&quot;&gt;See the history of LineageOS and it&#x27;s relationship to CyanogenMod here on Wikipedia&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;CyanogenMod was a bastian of freedom and innovation. I hope Lineage has managed to continue that.&lt;&#x2F;p&gt;
&lt;p&gt;There does appear to be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;download.lineageos.org&#x2F;lemonadep&quot;&gt;a build of LineageOS for the OnePlus 9 pro&lt;&#x2F;a&gt; - I think this is worth trying out.&lt;&#x2F;p&gt;
&lt;p&gt;LineageOS has it&#x27;s own recovery image, so no need to run TWRP as well.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-18-1-review&#x2F;&quot;&gt;Review of LineageOS on XDA Developers&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;lineage-for-microg-maybe&quot;&gt;Lineage for microG (maybe?)&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lineage.microg.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;lineage.microg.org&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lineageos4microg&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;lineageos4microg&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is a fork of lineage with microG already set up properly and a patch that lineage wouldn&#x27;t allow that let&#x27;s them spoof google signatures in order to trick apps into believing they are using the real google play services&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Q: &quot;Why do we need a custom build of LineageOS to have microG? Can&#x27;t I install microG on the official LineageOS?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;A: &quot;MicroG requires a patch called &quot;signature spoofing&quot;, which allows the microG&#x27;s apps to spoof themselves as Google Apps. LineageOS&#x27; developers refused (multiple times) to include the patch, forcing us to fork their project.&quot;&lt;br &#x2F;&gt;
~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lineage.microg.org&#x2F;#faq&quot;&gt;Lineage for microG faq&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;replicant-not-yet&quot;&gt;Replicant (not yet)&lt;&#x2F;h4&gt;
&lt;p&gt;&quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;replicant.us&#x2F;&quot;&gt;Replicant&lt;&#x2F;a&gt; is a fully free Android distribution running on several devices&quot;
I&#x27;m glad this freedom is here but I&#x27;m not quite ready to give up every last proprietary thing until there&#x27;s a bit less of a gap.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;redmine.replicant.us&#x2F;projects&#x2F;replicant&#x2F;wiki#Supported-devices&quot;&gt;Supported devices&lt;&#x2F;a&gt; shows purely Samsung Galaxy devices currently.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;e-aka-eelo&quot;&gt;&#x2F;e&#x2F; (aka Eelo)&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;e.foundation&#x2F;&quot;&gt;https:&#x2F;&#x2F;e.foundation&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;We build desirable, open source, privacy-enabled smartphone operating systems.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This Android derivative is focussed on privacy; eliminating as much data collection (i.e. all things google) as possible. Laudable but not my main focus right now.&lt;&#x2F;p&gt;
&lt;p&gt;You can buy their reconditioned phones with their OS pre-installed or just install the OS on something else.&lt;&#x2F;p&gt;
&lt;p&gt;They provide their own alternative cloud hosting for contacts etc for reasonable prices.&lt;&#x2F;p&gt;
&lt;p&gt;Their dev build has a root option it seems which might be useful. - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.e.foundation&#x2F;support-topics&#x2F;root-e-os.html&quot;&gt;https:&#x2F;&#x2F;doc.e.foundation&#x2F;support-topics&#x2F;root-e-os.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;&#x2F;e&#x2F;_(operating_system)&quot;&gt;&#x2F;e&#x2F; on wikipedia&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;itsfoss.com&#x2F;eelo-mobile-os&#x2F;&quot;&gt;itsfoss.com&#x2F;eelo-mobile-os&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pcmag.com&#x2F;news&#x2F;google-free-android-smartphones-are-now-available-in-the-us&quot;&gt;https:&#x2F;&#x2F;www.pcmag.com&#x2F;news&#x2F;google-free-android-smartphones-are-now-available-in-the-us&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;grapheneos-nope&quot;&gt;GrapheneOS (nope)&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;grapheneos.org&#x2F;&quot;&gt;GrapheneOS&lt;&#x2F;a&gt; - The private and secure mobile operating system with Android app compatibility. Developed as a non-profit open source project.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;grapheneos.org&#x2F;faq#supported-devices&quot;&gt;GrapheneOS only officially supports Pixel phones&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;calyxos-nope&quot;&gt;CalyxOS (nope)&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;calyxos.org&#x2F;&quot;&gt;CalyxOX&lt;&#x2F;a&gt; - &quot;Your Phone Should Be Private Everyone needs a phone. Not everyone wants to be spied on. Reclaim your privacy with CalyxOS.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Supports Pixel devices and one Xiaomi phone (never heard of it).&lt;&#x2F;p&gt;
&lt;p&gt;Seems to be pushing Signal and Tor so is super-privacy focussed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;google-apps-and-services&quot;&gt;Google Apps and Services&lt;&#x2F;h2&gt;
&lt;p&gt;There are two major parts to this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Google play - the app store for downloading apk files to install (plus ratings, reviews, screenshots etc)&lt;&#x2F;li&gt;
&lt;li&gt;Google services - these provide services that many apps want to use to avoid multiple implementations such as location information, push notification etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There&#x27;s a few ways of getting the google play store and related proprietary horrors:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Open GApps - pulls down the proprietary apps and writes them to the image&lt;&#x2F;li&gt;
&lt;li&gt;MindTheGapps? - pulls down the proprietary apps and writes them to the image&lt;&#x2F;li&gt;
&lt;li&gt;microG - open source re-implementation of the services&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;gapps#mobile&quot;&gt;For Lineage 18.1 (Android 11) the Lineage wiki links to MindTheGaps&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;gapps-package-recommended-rom-developer&#x2F;&quot;&gt;XDA Developers says &quot;Always Use the GApps Package Recommended by your ROM Developer&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t mind proprietary software as long as there&#x27;s choice out there, and the apple app store + google play duopoly on apps is not choice. F-Droid is fine but doesn&#x27;t have a single big name vendor&#x27;s apps, so it&#x27;s probably enough for google to dodge an anti-competitive lawsuit but not enough to produce any real competition.&lt;&#x2F;p&gt;
&lt;p&gt;Comparisons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;8358p0&#x2F;mindthegapps_vs_opengapps&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;8358p0&#x2F;mindthegapps_vs_opengapps&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;degoogle&#x2F;comments&#x2F;olsv4c&#x2F;i_am_very_confused_by_opengapps_mindthegapps&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;degoogle&#x2F;comments&#x2F;olsv4c&#x2F;i_am_very_confused_by_opengapps_mindthegapps&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;open-gapps-installer&quot;&gt;Open GApps (installer)&lt;&#x2F;h3&gt;
&lt;p&gt;Installer for google&#x27;s proprietary services.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;GApps &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;gapps&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;gapps&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;opengapps&#x2F;opengapps&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;opengapps&#x2F;opengapps&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;opengapps.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;opengapps.org&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Q: Why is this such a pain? A: Licensing...&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Due to licensing restrictions, these apps do not come pre-installed with ROMs others than those from vendors that are part of the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.openhandsetalliance.com&#x2F;index.html&quot;&gt;Open Handset Alliance&lt;&#x2F;a&gt; and must be installed as a sideload package by the user themselves.&quot; ~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;opengapps&#x2F;opengapps&#x2F;wiki&#x2F;FAQ&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;opengapps&#x2F;opengapps&#x2F;wiki&#x2F;FAQ&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We&#x27;re lucky they let us do this at all, google could take their toys away from us at any time.&lt;&#x2F;p&gt;
&lt;p&gt;For Open GApps pico looks sufficient &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;opengapps&#x2F;opengapps&#x2F;wiki&#x2F;Package-Comparison&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;opengapps&#x2F;opengapps&#x2F;wiki&#x2F;Package-Comparison&lt;&#x2F;a&gt;, Lineage recommends nano and no bigger.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mindthegapps-installer&quot;&gt;MindTheGapps (installer)&lt;&#x2F;h3&gt;
&lt;p&gt;Installer for google&#x27;s proprietary services.&lt;&#x2F;p&gt;
&lt;p&gt;Really haven&#x27;t found much information about this.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;about-1&quot;&gt;About&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;MindTheGapps&#x2F;vendor_gapps&quot;&gt;https:&#x2F;&#x2F;gitlab.com&#x2F;MindTheGapps&#x2F;vendor_gapps&lt;&#x2F;a&gt; - I think this is probably the official source
&lt;ul&gt;
&lt;li&gt;There&#x27;s no download link, as mentioned in this issue: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;MindTheGapps&#x2F;vendor_gapps&#x2F;-&#x2F;issues&#x2F;1&quot;&gt;https:&#x2F;&#x2F;gitlab.com&#x2F;MindTheGapps&#x2F;vendor_gapps&#x2F;-&#x2F;issues&#x2F;1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MindTheGapps&#x2F;vendor_gapps&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;MindTheGapps&#x2F;vendor_gapps&lt;&#x2F;a&gt; appears to be a stale copy, maybe they moved hosting to gitlab&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;mindthegapps-8-1-0&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;mindthegapps-8-1-0&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;change-opengapps-for-mindthegapps-afterthought.3837816&#x2F;&quot;&gt;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;change-opengapps-for-mindthegapps-afterthought.3837816&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;This wasn&#x27;t a lot of help but basically said just flash it: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;mindthegapps-8-1-0&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;mindthegapps-8-1-0&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;microg-open-source-reimplementation&quot;&gt;microG (open source reimplementation)&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;microg&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;microg&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A free software implementation of shared services provided by the proprietary google services (such as location and push messaging used by many apps).&lt;&#x2F;p&gt;
&lt;p&gt;Doesn&#x27;t work properly when flashed to lineage according to the faq so they made their own fork of Lineage &quot;Lineage for microG&quot; (see above)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;aurora-play-store-proxy&quot;&gt;Aurora - play store proxy&lt;&#x2F;h3&gt;
&lt;p&gt;Download apks (installation files) from the google play store without any googleness.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aurora-store.en.uptodown.com&#x2F;android&quot;&gt;https:&#x2F;&#x2F;aurora-store.en.uptodown.com&#x2F;android&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;packages&#x2F;com.aurora.store&#x2F;&quot;&gt;https:&#x2F;&#x2F;f-droid.org&#x2F;packages&#x2F;com.aurora.store&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;yalp-play-store-proxy&quot;&gt;Yalp - play store proxy&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;yalp-store.en.uptodown.com&#x2F;android&quot;&gt;https:&#x2F;&#x2F;yalp-store.en.uptodown.com&#x2F;android&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;f-droid-app-store&quot;&gt;F-Droid app store&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;&quot;&gt;F-Droid&lt;&#x2F;a&gt; is an app store for android like google play but without all the googlyness.&lt;&#x2F;p&gt;
&lt;p&gt;This a bit pointless if you install play because all the open source apps are available in both, and the closed ones are only in play. I think I&#x27;ll skip this for now but I&#x27;m glad it exists... Though it is pre-installed in lineage-for-microG so I have poked around and installed a few things.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;playmaker-play-store-f-droid-integration&quot;&gt;Playmaker - play store &#x2F; f-droid integration&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NoMore201&#x2F;playmaker&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;NoMore201&#x2F;playmaker&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;recovery-images&quot;&gt;Recovery images&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;twrp-great-but-not-needed&quot;&gt;TWRP (great but not needed)&lt;&#x2F;h3&gt;
&lt;p&gt;Previously I&#x27;ve used TWRP, and I got as far as flashing it before discovering &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-18-1-review&#x2F;&quot;&gt;Lineage has it&#x27;s own recovery image&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Unlock bootloader &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;oneplus-9-pro-unlock-bootloader&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;oneplus-9-pro-unlock-bootloader&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Download TWRP for lemonadep &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twrp.me&#x2F;oneplus&#x2F;oneplus9pro.html&quot;&gt;https:&#x2F;&#x2F;twrp.me&#x2F;oneplus&#x2F;oneplus9pro.html&lt;&#x2F;a&gt; - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eu.dl.twrp.me&#x2F;lemonadep&#x2F;twrp-3.6.0_11-0-lemonadep.img.html&quot;&gt;3.6 twrp download for lemonadep&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Get twrp public gpg&#x2F;pgp public key to be able to verify &lt;code&gt;.asc&lt;&#x2F;code&gt; files &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twrp.me&#x2F;faq&#x2F;pgpkeys.html&quot;&gt;https:&#x2F;&#x2F;twrp.me&#x2F;faq&#x2F;pgpkeys.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Flash TWRP (TeamWin Recovery Project?) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twrp.me&#x2F;&quot;&gt;https:&#x2F;&#x2F;twrp.me&#x2F;&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Power off the phone&lt;&#x2F;li&gt;
&lt;li&gt;Hold down volume-down and power buttons&lt;&#x2F;li&gt;
&lt;li&gt;Select english&lt;&#x2F;li&gt;
&lt;li&gt;select reboot to fastboot&lt;&#x2F;li&gt;
&lt;li&gt;connect the usb cable (usb-c to usb-c doesn&#x27;t work on my dell xps, use the bigger usb 3 A to usb-c cable)&lt;&#x2F;li&gt;
&lt;li&gt;run &lt;code&gt;fastboot devices&lt;&#x2F;code&gt; on the laptop (connected over usb), you should see your phone listed&lt;&#x2F;li&gt;
&lt;li&gt;boot the phone from the local twrp image &lt;code&gt;fastboot boot twrp-3.6.0_11-0-lemonadep.img&lt;&#x2F;code&gt;, phone boots up into twrp gui&lt;&#x2F;li&gt;
&lt;li&gt;advanced &amp;gt; flash current twrp&lt;&#x2F;li&gt;
&lt;li&gt;there&#x27;s a note about bootloops, but the options isn&#x27;t there so skipping that&lt;&#x2F;li&gt;
&lt;li&gt;reboot &amp;gt; power off (says current slot: A, just for the record)&lt;&#x2F;li&gt;
&lt;li&gt;power on with volume-down held again, boots straight to twrp this time&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;lineageos-s-recovery-image&quot;&gt;LineageOS&#x27;s recovery image&lt;&#x2F;h3&gt;
&lt;p&gt;Came across this here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-18-1-review&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-18-1-review&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Works well, flashed no problem and have used both recovery and fastboot modes with no issues. You&#x27;ll see it as part of the steps below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-lineageos-on-oneplus-9-pro-take-1&quot;&gt;Installing LineageOS on OnePlus 9 Pro (take 1)&lt;&#x2F;h2&gt;
&lt;p&gt;It begins. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lineageos.org&#x2F;&quot;&gt;LineageOS&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The oneplus 9 pro device is codename &lt;code&gt;lemonadep&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Useful howtos:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;install&quot;&gt;LineageOS official installation wiki page for OnePlus 9 pro lemonadep&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;348545&#x2F;how-to-install-lineageos-on-android&#x2F;&quot;&gt;How-To Geek: How to Install LineageOS on Android&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.androidauthority.com&#x2F;lineageos-install-guide-893303&#x2F;&quot;&gt;Android Authority: Beginner’s guide to installing LineageOS on your Android device&lt;&#x2F;a&gt; - lots more context and screenshots&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lineageosroms.com&#x2F;install-lineageos&#x2F;&quot;&gt;LineageOSROMS (unofficial)&lt;&#x2F;a&gt; - a very short 8 step guide
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lineageosroms.com&#x2F;lemonadep&#x2F;&quot;&gt;LineageOSROMS (unofficial) full guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;lineage-os-18-1-oneplus-9-9-pro&#x2F;&quot;&gt;GetDroidTips&lt;&#x2F;a&gt; - not sure there&#x27;s much extra useful here&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-18-builds-oneplus-9-pro-razer-phone-2-lenovo-p2&#x2F;&quot;&gt;XDADevelopers coverage of Lineage support for OnePlus 9 pro&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The steps:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Download latest nightly (there&#x27;s no stable&#x2F;unstable on this): &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;download.lineageos.org&#x2F;lemonadep&quot;&gt;https:&#x2F;&#x2F;download.lineageos.org&#x2F;lemonadep&lt;&#x2F;a&gt; - this has both the ROM (OS image) and the recovery image.&lt;&#x2F;li&gt;
&lt;li&gt;Download copy-partitions &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;androidfilehost.com&#x2F;?fid=2188818919693768129&quot;&gt;https:&#x2F;&#x2F;androidfilehost.com&#x2F;?fid=2188818919693768129&lt;&#x2F;a&gt; (as per wiki)
&lt;ul&gt;
&lt;li&gt;The sha256 for the copy I have is &lt;code&gt;200877dfd0869a0e628955b807705765a91e34dff3bfeca9f828e916346aa85f  copy-partitions-20210323_1922.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Verify all the sha256 sums: &lt;code&gt;sha256sum -c *.sha256&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Boot to fastboot&lt;&#x2F;li&gt;
&lt;li&gt;flash the lineage recovery:&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;LineageOS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ fastboot flash boot lineage-18.1-20211214-recovery-lemonadep.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sending &amp;#39;boot_a&amp;#39; (196608 KB)                       OKAY [  6.113s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Writing &amp;#39;boot_a&amp;#39;                                   OKAY [  0.655s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finished. Total time: 6.985s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;copy partitions as instructed
&lt;ul&gt;
&lt;li&gt;boot into recovery (vol-down + power)&lt;&#x2F;li&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload copy-partitions-20210323_1922.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Ignore unknown sig and &quot;continue&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;wipe
&lt;ul&gt;
&lt;li&gt;boot into recovery (vol-down + power) if not already in it&lt;&#x2F;li&gt;
&lt;li&gt;&quot;format data &#x2F; factory reset&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;OS install
&lt;ul&gt;
&lt;li&gt;boot into recovery (vol-down + power) if not already in it&lt;&#x2F;li&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;LineageOS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb sideload lineage-18.1-20211214-nightly-lemonadep-signed.zip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;serving: &amp;#39;lineage-18.1-20211214-nightly-lemonadep-signed.zip&amp;#39;  (~47%)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	adb: failed to read command: Success&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;apparently this is normal, but the failed to flash error on the phone is not, and rebooting drops me back into the existing Oxygen install. Dammit.... Try again&lt;&#x2F;li&gt;
&lt;li&gt;Second attempt ran fine
&lt;ul&gt;
&lt;li&gt;output: &lt;code&gt;step 1&#x2F;2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output: &lt;code&gt;step 2&#x2F;2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;then recovery logo comes back up and it just sits there&lt;&#x2F;li&gt;
&lt;li&gt;volume up to the back arrow at the top, power to press it&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;then&lt;&#x2F;em&gt; it says &quot;&lt;code&gt;install complete with status 0&lt;&#x2F;code&gt;&quot; (zero being unix-speak for no-issues)&lt;&#x2F;li&gt;
&lt;li&gt;but it doesn&#x27;t ever get past the lineage logo when booting, maybe because of the boot of oxygen. hmm&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=y2yB2dRrXiA&quot;&gt;hard-power-off&lt;&#x2F;a&gt; by holding down volume-up and power button&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;take 3,
&lt;ul&gt;
&lt;li&gt;back to recovery&lt;&#x2F;li&gt;
&lt;li&gt;re-wipe (factory reset)&lt;&#x2F;li&gt;
&lt;li&gt;reboot&lt;&#x2F;li&gt;
&lt;li&gt;this time it booted... briefly&lt;&#x2F;li&gt;
&lt;li&gt;it got to setup screen, then before I did anything rebooted into some kind of recovery failsafe and prompted to factory reset again, which I did. This time it rebooted and stayed up while I zipped through the wizard.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;go take a look - ignore the warning about doing gapps etc first just so we can see what vanilla Lineage looks like. We can always wipe &amp;amp; reflash
&lt;ul&gt;
&lt;li&gt;wonderfully empty app list!&lt;&#x2F;li&gt;
&lt;li&gt;basic main camera &amp;amp; selfie cam works&lt;&#x2F;li&gt;
&lt;li&gt;flashlight works&lt;&#x2F;li&gt;
&lt;li&gt;odd android verify notification, didn&#x27;t seem to work&lt;&#x2F;li&gt;
&lt;li&gt;top shelf only available on lockscreen, odd&lt;&#x2F;li&gt;
&lt;li&gt;no sim yet and wifi not connected yet, so not much else to test&lt;&#x2F;li&gt;
&lt;li&gt;vol-down + power still takes screenshots&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;connect-adb-see-if-we-get-root-shell&quot;&gt;Connect adb, see if we get root shell&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;command-line&#x2F;adb#Enabling&quot;&gt;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;command-line&#x2F;adb#Enabling&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;On the phone enable adb
&lt;ul&gt;
&lt;li&gt;settings &amp;gt; about phone &amp;gt; tap &quot;build number&quot; repeatedly&lt;&#x2F;li&gt;
&lt;li&gt;settings &amp;gt; system &amp;gt; advanced (grrrr) &amp;gt; developer options
&lt;ul&gt;
&lt;li&gt;usb debugging [on]&lt;&#x2F;li&gt;
&lt;li&gt;rooted debugging [on]&lt;&#x2F;li&gt;
&lt;li&gt;disable adb authorization timeout [on]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;connect usb cable to laptop&lt;&#x2F;li&gt;
&lt;li&gt;phone prompts &quot;Allow USB Debugging?&quot;
&lt;ul&gt;
&lt;li&gt;tick &quot;always allow&quot;&lt;&#x2F;li&gt;
&lt;li&gt;press &quot;allow&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;On the laptop &lt;code&gt;adb devices&lt;&#x2F;code&gt; should now show the phone&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Success with non-root:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OnePlus9Pro:&#x2F; $ ^D&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Root denied without flipping the &quot;rooted&quot; option:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb root &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ADB Root access is disabled by system setting - enable in Settings -&amp;gt; System -&amp;gt; Developer options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After enabling rooted debugging as above:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb root  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;restarting adbd as root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OnePlus9Pro:&#x2F; # whoami&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;getting-root-back&quot;&gt;Getting root back&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;grumble&quot;&gt;Grumble&lt;&#x2F;h4&gt;
&lt;p&gt;It really annoys me that on a laptop this isn&#x27;t even a step, yet on Android this is a whole additional drama. But I may have already mentioned that. Understanding the reasons doesn&#x27;t mean I have to like it.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;adb-root-shell&quot;&gt;adb root shell&lt;&#x2F;h4&gt;
&lt;p&gt;According to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-dropping-superuser-addonsu-implementation-favor-magisk-manager&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-dropping-superuser-addonsu-implementation-favor-magisk-manager&#x2F;&lt;&#x2F;a&gt; adb root shell is the official LineageOS way of getting root access to &quot;mess with important files&quot;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb root  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;restarting adbd as root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OnePlus9Pro:&#x2F; # whoami&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Worth knowing but not much help for running titanium backup as root.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;magisk&quot;&gt;Magisk&lt;&#x2F;h4&gt;
&lt;p&gt;According to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-dropping-superuser-addonsu-implementation-favor-magisk-manager&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;lineageos-dropping-superuser-addonsu-implementation-favor-magisk-manager&#x2F;&lt;&#x2F;a&gt; Magisk is the only real option now. I guess SuperSU still works but lacks the masking that allows you to fool android pay etc.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;warning-beware-of-fake-magisk-sites-warning&quot;&gt;⚠️ Beware of fake Magisk sites !! ⚠️&lt;&#x2F;h5&gt;
&lt;p&gt;Github is the official home for Magisk and it&#x27;s downloads: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;topjohnwu&#x2F;Magisk&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;topjohnwu&#x2F;Magisk&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;psa-magiskmanager-com-not-official-website-magisk&#x2F;amp&#x2F;&quot;&gt;&lt;strong&gt;Beware of clone sites&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; especially ones offering downloads.  &lt;code&gt;MagiskManager.com&lt;&#x2F;code&gt; is not legit or authorised and may host malware at some point. I&#x27;ve seen a few others too. They look like SEO optimised clones that could potentially be feeding some or all visitors malware.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s worth being extra-careful with things like recovery images and rooters because by definition they have full control of your device, malicious or malign.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;magisk-root-install&quot;&gt;Magisk root install&lt;&#x2F;h5&gt;
&lt;p&gt;LineageOS said not to boot before doing installing GApps, I&#x27;m not sure if that applies to Magisk too. I already have booted up. Not sure if a factory reset plus wipe will be enough or whether the image will have to be reflashed. I&#x27;ll try with just an install, if that doesn&#x27;t work I&#x27;ll try the reset and see what happens, and if &lt;em&gt;that&lt;&#x2F;em&gt; doesn&#x27;t work I&#x27;ll try a full reinstall.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Look at readme at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;topjohnwu&#x2F;Magisk&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;topjohnwu&#x2F;Magisk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Follow instructions &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;topjohnwu.github.io&#x2F;Magisk&#x2F;install.html&quot;&gt;https:&#x2F;&#x2F;topjohnwu.github.io&#x2F;Magisk&#x2F;install.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Download latest release &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;topjohnwu&#x2F;Magisk&#x2F;releases&#x2F;latest&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;topjohnwu&#x2F;Magisk&#x2F;releases&#x2F;latest&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;install the app with adb (with the phone on, and booted to LineageOS as per normal use)
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.droidviews.com&#x2F;install-apk-files-using-adb-commands&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.droidviews.com&#x2F;install-apk-files-using-adb-commands&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb install Magisk-v23.0.apk &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Performing Streamed Install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Success&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;On the phone, swipe up for the full app list (drawer), and there is a Magisk icon!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h6 id=&quot;getting-boot-img&quot;&gt;Getting boot.img&lt;&#x2F;h6&gt;
&lt;p&gt;The instructions for Magisk just say you need &lt;code&gt;boot.img&lt;&#x2F;code&gt;, leaving know clues how to get it. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;topjohnwu&#x2F;Magisk&#x2F;pull&#x2F;5132&quot;&gt;I&#x27;ve proposed explaining how to extract them in this pull request&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It turns out it&#x27;s embedded in the Lineage system image &lt;code&gt;lineage-18.1-20211214-nightly-lemonadep-signed.zip&lt;&#x2F;code&gt; that we&#x27;ve already downloaded.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s another payload extractor with easier dependencies that&#x27;s worth a try, especially if you don&#x27;t already have python: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ssut&#x2F;payload-dumper-go&quot;&gt;payload-dumper-go&lt;&#x2F;a&gt;
| &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ssut&#x2F;payload-dumper-go&#x2F;releases&#x2F;latest&quot;&gt;payload-dumper-go downloads&lt;&#x2F;a&gt;. I&#x27;ve now tested this and it works great. You don&#x27;t even have to unzip the zip.&lt;&#x2F;p&gt;
&lt;p&gt;Extract the &lt;code&gt;payload.bin&lt;&#x2F;code&gt; file from the &lt;code&gt;lineage-18.1-20211214-nightly-lemonadep-signed.zip&lt;&#x2F;code&gt; to the same folder as the python script.&lt;&#x2F;p&gt;
&lt;p&gt;Some instructions on using python to extract the boot image: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;guide-how-to-extract-payload-bin-from-ota.3830962&#x2F;&quot;&gt;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;guide-how-to-extract-payload-bin-from-ota.3830962&#x2F;&lt;&#x2F;a&gt; (ignore the file it&#x27;s older than the github one)&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;payload_dumper&lt;&#x2F;code&gt; file appears to be from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;vm03&#x2F;payload_dumper&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;vm03&#x2F;payload_dumper&lt;&#x2F;a&gt; assuming my googling is accurate.&lt;&#x2F;p&gt;
&lt;p&gt;I didn&#x27;t need to do the pip install.&lt;&#x2F;p&gt;
&lt;p&gt;I did change the python to python3 at the top of the py file and make it executable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;payload_dumper&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ .&#x2F;payload_dumper.py payload.bin &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;boot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dtbo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;odm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;product&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;system_ext&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vbmeta&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vbmeta_system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vendor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vendor_boot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;payload_dumper&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ll output &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 5.6G&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 192M Dec 20 23:20 boot.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim  24M Dec 20 23:20 dtbo.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 2.8M Dec 20 23:20 odm.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 1.3G Dec 20 23:21 product.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 267M Dec 20 23:21 system_ext.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 2.5G Dec 20 23:21 system.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 8.0K Dec 20 23:21 vbmeta.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 4.0K Dec 20 23:21 vbmeta_system.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 192M Dec 20 23:22 vendor_boot.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 1.3G Dec 20 23:22 vendor.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hurrah, now we have a &lt;code&gt;boot.img&lt;&#x2F;code&gt; to give to Magisk.&lt;&#x2F;p&gt;
&lt;h6 id=&quot;magisk-rooting&quot;&gt;Magisk rooting&lt;&#x2F;h6&gt;
&lt;p&gt;Copy the &lt;code&gt;boot.img&lt;&#x2F;code&gt; across:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;payload_dumper&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb push output&#x2F;boot.img &#x2F;sdcard&#x2F; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;output&#x2F;boot.img: 1 file pushed, 0 skipped. 177.5 MB&#x2F;s (201326592 bytes in 1.082s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Press install on the Magisk app.&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Select and Patch a File&quot;&lt;&#x2F;li&gt;
&lt;li&gt;hamburger in file browser &amp;gt; &quot;OnePlus 9 Pro&quot; (obviously, duh) &amp;gt; &lt;code&gt;boot.img&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;let&#x27;s go -&amp;gt;&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Magisk shows steps then&quot; output file is written to...&quot; and a path to download folder&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;payload_dumper&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OnePlus9Pro:&#x2F; # ls -lh &#x2F;sdcard&#x2F;Download&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 96M&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwx------ 1 u0_a163 u0_a163 192M 2021-12-14 13:21 magisk_patched-23000_BYMDt.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;pull the file back to the laptop &lt;code&gt;adb pull &#x2F;sdcard&#x2F;Download&#x2F;magisk_patched-23000_BYMDt.img&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Now flash the file to the phone:
&lt;ul&gt;
&lt;li&gt;(the vol-up + power didn&#x27;t work for me, just did a normal boot, vol-down + power is reccovery not fastboot)&lt;&#x2F;li&gt;
&lt;li&gt;Settings &amp;gt; system &amp;gt; advanced (ffs) &amp;gt; gestures (wtf?) &amp;gt; power menu &amp;gt; advanced restart [on]&lt;&#x2F;li&gt;
&lt;li&gt;power button (hold) &amp;gt; power &amp;gt; restart &amp;gt; fastboot&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;payload_dumper&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ fastboot flash boot magisk_patched-23000_BYMDt.img &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sending &amp;#39;boot_b&amp;#39; (196608 KB)                       OKAY [  6.035s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Writing &amp;#39;boot_b&amp;#39;                                   OKAY [  0.639s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finished. Total time: 6.853s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;power off&lt;&#x2F;li&gt;
&lt;li&gt;power on&lt;&#x2F;li&gt;
&lt;li&gt;open up the Magisk app - it shows installed version number now, hurrah&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Using Magisk:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Click the cog (top right) to optionally turn on &quot;MagiskHide&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Along the bottom are four icons
&lt;ul&gt;
&lt;li&gt;Home&lt;&#x2F;li&gt;
&lt;li&gt;Shield - shows root requests&lt;&#x2F;li&gt;
&lt;li&gt;bug - shows logs&lt;&#x2F;li&gt;
&lt;li&gt;jigsaw piece - shows modules, activate, deactivate &amp;amp; install&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;adb&quot;&gt;adb&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;command-line&#x2F;adb&quot;&gt;adb&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I consider this an important backup access to the phone. If the screen fails then this allows you to pull any important files off over usb.&lt;&#x2F;p&gt;
&lt;p&gt;Steps for this are above.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-lineage-for-microg-tried-rejected-for-now&quot;&gt;Installing &quot;Lineage for microG&quot; (tried, rejected for now)&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lineage.microg.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;lineage.microg.org&#x2F;&lt;&#x2F;a&gt; has install and download links&lt;&#x2F;li&gt;
&lt;li&gt;Download image from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;download.lineage.microg.org&#x2F;lemonadep&#x2F;&quot;&gt;https:&#x2F;&#x2F;download.lineage.microg.org&#x2F;lemonadep&#x2F;&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;check sha: &lt;code&gt;sha256sum -c lineage-18.1-20211220-microG-lemonadep.zip.sha256sum&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;run update_verifier python script:
&lt;ul&gt;
&lt;li&gt;download (or clone) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lineageos4microg&#x2F;update_verifier&quot;&gt;python update_verifier&lt;&#x2F;a&gt; - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lineageos4microg&#x2F;update_verifier&#x2F;archive&#x2F;refs&#x2F;heads&#x2F;master.zip&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;lineageos4microg&#x2F;update_verifier&#x2F;archive&#x2F;refs&#x2F;heads&#x2F;master.zip&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;setup python3 with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;asdf-vm.com&#x2F;&quot;&gt;asdf-vm&lt;&#x2F;a&gt; (I had python 3 but no pip, and I like to use adsf)&lt;&#x2F;li&gt;
&lt;li&gt;extract the zip, open terminal in extracted folder&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;asdf plugin add python&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;asdf install python 3.10.1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;asdf local python 3.10.1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;pip install -r requirements.txt&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;python update_verifier.py lineageos4microg_pubkey ..&#x2F;lineage-18.1-20211220-microG-lemonadep.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;output: &lt;code&gt;verified successfully&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Go back to lineage install instructions &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;install&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;install&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Boot to fastboot&lt;&#x2F;li&gt;
&lt;li&gt;flash the lineage-microG recovery: &lt;code&gt;fastboot flash boot lineage-18.1-20211220-microG-lemonadep-recovery.img&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;copy partitions as instructed
&lt;ul&gt;
&lt;li&gt;boot into recovery (vol-down + power)
&lt;ul&gt;
&lt;li&gt;or &quot;enter recovery&quot; from lineage fastboot&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload ..&#x2F;LineageOS&#x2F;copy-partitions-20210323_1922.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Ignore unknown sig and &quot;continue&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;wipe
&lt;ul&gt;
&lt;li&gt;boot into recovery (vol-down + power) if not already in it&lt;&#x2F;li&gt;
&lt;li&gt;&quot;format data &#x2F; factory reset&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;OS install
&lt;ul&gt;
&lt;li&gt;boot into recovery (vol-down + power) if not already in it&lt;&#x2F;li&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload lineage-18.1-20211220-microG-lemonadep.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;reboot&lt;&#x2F;li&gt;
&lt;li&gt;skip all the guided setup steps&lt;&#x2F;li&gt;
&lt;li&gt;open the microG app&lt;&#x2F;li&gt;
&lt;li&gt;run the self check (all green ticks for me, woo)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So now I have a clean LineageOS install with a FOSS re-implementation of google&#x27;s proprietary shared services. Win.&lt;&#x2F;p&gt;
&lt;p&gt;Now re-run magisk sideload from above to get root again.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;re-enable adb as before&lt;&#x2F;li&gt;
&lt;li&gt;re-enable advance power button menu&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb install Magisk-v23.0.apk&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;grab a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ssut&#x2F;payload-dumper-go&#x2F;releases&#x2F;latest&quot;&gt;payload-dumper-go binary release&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;payload-dumper-go_1.2.0_linux_amd64&#x2F;payload-dumper-go lineage-18.1-20211220-microG-lemonadep.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb push extracted_20211221_231517&#x2F;boot.img &#x2F;sdcard&#x2F;Download&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;run the patch in the phone Magisk UI (under &quot;install&quot;)&lt;&#x2F;li&gt;
&lt;li&gt;get the filename to pull: &lt;code&gt;adb shell ls &#x2F;sdcard&#x2F;Download&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb pull &#x2F;sdcard&#x2F;Download&#x2F;magisk_patched-23000_d5mu3.img&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;reboot to fastboot&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fastboot flash boot magisk_patched-23000_d5mu3.img&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;reboot system now&quot; in lineage fastboot menu&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Success, now I have root &lt;em&gt;and&lt;&#x2F;em&gt; microG.&lt;&#x2F;p&gt;
&lt;p&gt;Next, see if Aurora does the job, and if not how do I get google play on top of microG, if that&#x27;s even possible. Till next time...&lt;&#x2F;p&gt;
&lt;h3 id=&quot;getting-apps&quot;&gt;Getting apps&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;f-droid&quot;&gt;F-Droid&lt;&#x2F;h4&gt;
&lt;p&gt;F-Droid is preinstalled (stared blankly at app list for a while before spotting it!) so that was easy, this can install &lt;em&gt;many&lt;&#x2F;em&gt; open source apps, and warns about &quot;anti-features&quot; which is a nice touch.&lt;&#x2F;p&gt;
&lt;p&gt;Used F-Droid to install andOTP as a test (alternative to google authenticator 2FA app). Worked well.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;apps-from-play-store-aurora&quot;&gt;Apps from play store - Aurora&lt;&#x2F;h4&gt;
&lt;p&gt;Found Aurora in f-droid with a search, installed no problems, opened it up.&lt;&#x2F;p&gt;
&lt;p&gt;First thing it does is prompt for install type which is confusing and lacks enough context to know what it means. The four types are explained further here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;auroraoss.com&#x2F;faq&#x2F;#how-does-aurora-store-install-apps&quot;&gt;https:&#x2F;&#x2F;auroraoss.com&#x2F;faq&#x2F;#how-does-aurora-store-install-apps&lt;&#x2F;a&gt; thought I&#x27;m still not really sure. I don&#x27;t know what a &quot;split apk&quot; is yet, and I don&#x27;t see if there&#x27;s a difference between root and services as I could do either and they both say they do the same thing.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Session - recommended but not clear why, I think it&#x27;s saying it&#x27;s like &quot;Aurora Services&quot; but with more something-or-other&lt;&#x2F;li&gt;
&lt;li&gt;Native - doesn&#x27;t support split apks, that sounds bad, see below for what they are (see below for split apk research)&lt;&#x2F;li&gt;
&lt;li&gt;Root - auto install when downloaded&lt;&#x2F;li&gt;
&lt;li&gt;Aurora Services - auto install when downloaded&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;How to choose?  I guess I&#x27;ll go with the recommendation.&lt;&#x2F;p&gt;
&lt;p&gt;Couple of theme questions. Meh.&lt;&#x2F;p&gt;
&lt;p&gt;Installer question: &quot;Select a suitable installer&quot;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;External Storage Access [grant] - pops and allow dialog, clicked &quot;allow&quot;&lt;&#x2F;li&gt;
&lt;li&gt;External Storage Manager [grant] - required on R+ (aka android 11), which we are running, guess I&#x27;ll need that, - opened permissions screen, toggled to allow&lt;&#x2F;li&gt;
&lt;li&gt;Installer Permission [grant] - opened permissions screen, toggled to allow&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&quot;Finish&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Log in using:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Google&lt;&#x2F;li&gt;
&lt;li&gt;Anonymous&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It seems from what I&#x27;ve read in the FAQ and terms that using the real login is best because the anon accounts end up with random locales and app restrictions depending on where the login was generated.&lt;&#x2F;p&gt;
&lt;p&gt;[install keepassdroid and push my kdb across with adb to get the google login, eventually the kdb will be sync&#x27;d with syncthing]&lt;&#x2F;p&gt;
&lt;p&gt;... log in with google ...&lt;&#x2F;p&gt;
&lt;p&gt;And we&#x27;re in, app listing showing. Disconcerting to see disney+ etc in &quot;free&quot; app store on a &quot;free&quot; phone.&lt;&#x2F;p&gt;
&lt;p&gt;WhatsApp isn&#x27;t available in f-droid so let&#x27;s try that as an experiment... It&#x27;s in the list... it installed... it opened... it worked! (And logged me out of the other phone, fucking whatsapp).&lt;&#x2F;p&gt;
&lt;h5 id=&quot;what-s-a-split-apk&quot;&gt;What&#x27;s a split APK?&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;APK splitting - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;build&#x2F;configure-apk-splits&quot;&gt;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;build&#x2F;configure-apk-splits&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Android App Bundles - defers apk generatoin to play store &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.android.com&#x2F;guide&#x2F;app-bundle&quot;&gt;https:&#x2F;&#x2F;developer.android.com&#x2F;guide&#x2F;app-bundle&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Feature delivery - partial app additions and updates &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.android.com&#x2F;guide&#x2F;playcore&#x2F;feature-delivery&quot;&gt;https:&#x2F;&#x2F;developer.android.com&#x2F;guide&#x2F;playcore&#x2F;feature-delivery&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Old unsupported app &quot;SAI&quot; split apk installer:
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;guide-split-apk-installation.3934631&#x2F;&quot;&gt;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;guide-split-apk-installation.3934631&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Aefyr&#x2F;SAI&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Aefyr&#x2F;SAI&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;androiddev&#x2F;comments&#x2F;cenuvs&#x2F;what_is_it_with_publishing_split_apks_on_google&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;androiddev&#x2F;comments&#x2F;cenuvs&#x2F;what_is_it_with_publishing_split_apks_on_google&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;androiddev&#x2F;comments&#x2F;ci4a7r&#x2F;confused_about_split_apk&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;androiddev&#x2F;comments&#x2F;ci4a7r&#x2F;confused_about_split_apk&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-state-of-the-system&quot;&gt;The state of the system&lt;&#x2F;h3&gt;
&lt;p&gt;What&#x27;s working and what isn&#x27;t.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;google-voice-to-text-dead&quot;&gt;Google voice to text (dead)&lt;&#x2F;h4&gt;
&lt;p&gt;The keyboard has a little mic button which allows you to use google&#x27;s services to enter text anywhere you like by typing. This is useful as I hate phone keyboards. I use it quite a lot. Unsurprisingly with the microG setup that&#x27;s not working at all. The button is there but it does nothing.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;bluetooth-working&quot;&gt;Bluetooth (working)&lt;&#x2F;h4&gt;
&lt;p&gt;Headphones connected and played no problem.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-state-of-the-apps&quot;&gt;The state of the apps&lt;&#x2F;h3&gt;
&lt;p&gt;What&#x27;s working and what isn&#x27;t.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;banking-apps-mixed&quot;&gt;Banking apps (mixed)&lt;&#x2F;h4&gt;
&lt;p&gt;Let&#x27;s start with the big one. This is most likely to sink an open source effort as they try to protect themselves by joining in the lockdown.&lt;&#x2F;p&gt;
&lt;p&gt;Surprisingly two out of three of the banking apps I&#x27;d like to use actually worked on the rooted custom ROM with an unlocked bootloader. I had not turned on the magisk hide capability at this point. One banking app behaved as if nothing was different, one popped a warning but allowed the app to continue and one flat out refused to run. I&#x27;m not going to name the banks involved on the public internet as I don&#x27;t want to encourage anyone to test the security of my banking.&lt;&#x2F;p&gt;
&lt;p&gt;One of the apps logged me out of my other phone. The other functioning app offered to transfer a &quot;digital key&quot; to the new device, and without that allowed me to use the first phone to generate a login code and use that to poke around. I didn&#x27;t try transferring the key.&lt;&#x2F;p&gt;
&lt;p&gt;More worrying was the realisation that I&#x27;d been locked in to running a google&#x2F;iOS locked-down device by one of the banks as they are an &quot;app-first&quot; bank. You can&#x27;t even use the online banking without the phone app, and the phone app requires a locked and signed phone. It&#x27;s only by going on this very journey of actually trying to set up a phone that I control that I&#x27;d even noticed this insidious creeping embrace of platform-lockin. So now to truly escape the platform, I have to change banks as well.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;google-calendar-mostly-working&quot;&gt;Google calendar (mostly working)&lt;&#x2F;h4&gt;
&lt;p&gt;I&#x27;m afraid I still use google&#x27;s calendar, and there&#x27;s a high cost of change as I&#x27;ve got my other half using a shared calendar. The calendar worked fine, although oddly the &quot;widget&quot; (view of calendar that can be placed on the phone&#x27;s desktop when unlocked) was blank until I left the phone in the drawer with wifi off for two days. For who-knows-what reason when I got it out the drawer it has started working.&lt;&#x2F;p&gt;
&lt;p&gt;Oddly the events have shown up but reminders are missing. This is a bit of a problem as I use them a lot. It&#x27;s not that they&#x27;re local to my other phone because they show on the google calendar web interface too.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;amazon-things-working&quot;&gt;Amazon things (working)&lt;&#x2F;h4&gt;
&lt;p&gt;The amazon shopping app worked no problem.&lt;&#x2F;p&gt;
&lt;p&gt;To my surprise the amazon primve video app worked and played content as normal. I rather expected some kind of DRM smackdown to kick in on a rooted device.&lt;&#x2F;p&gt;
&lt;p&gt;Audible worked and played no problem.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;spotify-working&quot;&gt;Spotify (working)&lt;&#x2F;h4&gt;
&lt;p&gt;Again pleasingly working with no quibbling or warnings. This is more important to me at the moment than perhaps it should be.&lt;&#x2F;p&gt;
&lt;p&gt;Casting sound to chromecast audio not working.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;whatscrapp-working&quot;&gt;Whatscrapp (working)&lt;&#x2F;h4&gt;
&lt;p&gt;Much as I hate WhatsApp and it being owned by Facebook&#x2F;Meta .... thanks to network effect I kinda still need it. I&#x27;ve managed to get some of my contacts over to telegram&#x2F;signal but not everyone.&lt;&#x2F;p&gt;
&lt;p&gt;WhatsApp worked but signed me out of the other phone (ffs). Bonus points for receiving an important message from someone I haven&#x27;t heard from in about a year on the wrong phone. Ugh.&lt;&#x2F;p&gt;
&lt;p&gt;So on the plus side I&#x27;ve learned of another reason to dislike WhatsApp.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hiding-the-unlock-root&quot;&gt;Hiding the unlock &amp;amp; root&lt;&#x2F;h3&gt;
&lt;p&gt;Magisk has in its settings a &quot;hide&quot; option. This had no noticeable effect on the &quot;SafteyNet&quot; test (still three of three tests fail for me) built in to Magisk. I didn&#x27;t notice any change in app behaiour in my limited poking.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wifi-based-location-turn-on&quot;&gt;WiFi-based location (turn on)&lt;&#x2F;h3&gt;
&lt;p&gt;Understandably from a freedom-warrior point of view the wifi-based loction services are off by default, but this is a bit of a pain because if you&#x27;ve ever used pure GPS positioning you&#x27;ll know it&#x27;s shit at doing it in houses, offices and built up areas, takes ages to get a lock, and is a bit hit and miss in cars. The accuracy you normally see is much more a function of the ubiquity of wifi in our urban lives.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;screen-refresh-rate-60-120hz-increase&quot;&gt;Screen refresh rate 60&#x2F;120Hz (increase)&lt;&#x2F;h3&gt;
&lt;p&gt;The &quot;minimum screen refresh rate&quot; setting was set to 60Hz. There&#x27;s also a developer option for showing the current rate. In my experiment it sat at 60Hz all the time. This is fine till you scroll up and down, then you notice how much smoother the text scrolls at 120Hz. I upped the minimum to 120Hz which seemd to work.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s also a smooth-scroll option that I turned on that seems to produce a nicer effect.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-adb-to-do-backups&quot;&gt;Using adb to do backups&lt;&#x2F;h2&gt;
&lt;p&gt;It might be possible to backup a locked down phone without root by using adb&#x27;s backup capabilities. I haven&#x27;t looked into this much or tried it yet but here&#x27;s some quick research notes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;AnatomicJC&#x2F;e773dd55ae60ab0b2d6dd2351eb977c1&quot;&gt;gist: Backup android app, data included, no root needed, with adb&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;net2.com&#x2F;how-to-backup-and-restore-your-android-device-with-adb-on-ubuntu&#x2F;&quot;&gt;https:&#x2F;&#x2F;net2.com&#x2F;how-to-backup-and-restore-your-android-device-with-adb-on-ubuntu&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.paulligocki.com&#x2F;backup-restore-android-with-adb&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.paulligocki.com&#x2F;backup-restore-android-with-adb&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackpointer.io&#x2F;mobile&#x2F;android-adb-backup-extract-restore-repack&#x2F;372&#x2F;&quot;&gt;https:&#x2F;&#x2F;stackpointer.io&#x2F;mobile&#x2F;android-adb-backup-extract-restore-repack&#x2F;372&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;19225467&#x2F;backing-up-android-device-using-adb&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;19225467&#x2F;backing-up-android-device-using-adb&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;69567&#x2F;what-all-does-adb-backup-and-how-do-i-restore-part-of-it&quot;&gt;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;69567&#x2F;what-all-does-adb-backup-and-how-do-i-restore-part-of-it&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This might give me a way of rescuing some of my data from my old phone that de-rooted itself in an OS upgrade and fucked my titanium backups (still bitter).&lt;&#x2F;p&gt;
&lt;p&gt;Oh but wait...&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;69567&#x2F;what-all-does-adb-backup-and-how-do-i-restore-part-of-it#comment125038_69576&quot;&gt;Devs can set the ALLOW_BACKUP flag to &quot;No&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Argh, what is wrong with this platform.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;customisations&quot;&gt;Customisations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Turn on all the power button options:
&lt;ul&gt;
&lt;li&gt;Settings &amp;gt; system &amp;gt; advanced (ffs) &amp;gt; gestures (wtf?) &amp;gt; power menu &amp;gt; advanced restart [on]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;options-what-now&quot;&gt;Options - what now?&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s been an enlightening exercise in &quot;is this even possible&quot;. I&#x27;ve learned a huge amount about the current state of the phone ecosystem. I&#x27;m in equal measure dismayed and hopeful, there are some unpleasant trends and circumstances, and some really encouraging signs of hope for the open ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;There really isn&#x27;t a clear answer for me for where to go from here. There are downsides and challenges in every direction.&lt;&#x2F;p&gt;
&lt;p&gt;The options available seem to be in increasing order of freedom and somewhat decreasing order of utility:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Get an iPhone and abandon my principles and control, go live in a digital nursing home. - YeahNo.
&lt;ul&gt;
&lt;li&gt;get banking apps galore&lt;&#x2F;li&gt;
&lt;li&gt;never get root again&lt;&#x2F;li&gt;
&lt;li&gt;trust apple to administer the correct dosage of backups&lt;&#x2F;li&gt;
&lt;li&gt;forever more fight the divide between iOS and my linux laptops&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Install Oxygen 11, relock the bootloader, live without root, have no upgrade path because Oxygen is dead. - No.
&lt;ul&gt;
&lt;li&gt;possibly brick the phone trying to lock it&lt;&#x2F;li&gt;
&lt;li&gt;get banking apps&lt;&#x2F;li&gt;
&lt;li&gt;never get root again&lt;&#x2F;li&gt;
&lt;li&gt;never have decent backups&lt;&#x2F;li&gt;
&lt;li&gt;forever more fight the divide between iOS and my linux laptops&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Install lineage and one of the google apps installers
&lt;ul&gt;
&lt;li&gt;still no bank&lt;&#x2F;li&gt;
&lt;li&gt;probably get reliable google goodness&lt;&#x2F;li&gt;
&lt;li&gt;get stalked by google (no change there, I dno&#x27;t mind as much as some about this)&lt;&#x2F;li&gt;
&lt;li&gt;unknown time-to-failure&lt;&#x2F;li&gt;
&lt;li&gt;I think this is probably the most &quot;mainstream&quot; of the subversive options so is most likely to continue to have a forward path for the next few years&lt;&#x2F;li&gt;
&lt;li&gt;worry about security of unlocked evenrything and the security of lineage - I think it&#x27;s probably no worse than linux at this point but who knows&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Install lineage-for-microG (current experiment)
&lt;ul&gt;
&lt;li&gt;no bank, no voice-to-text&lt;&#x2F;li&gt;
&lt;li&gt;worry more about the security of build servers for this niche option&lt;&#x2F;li&gt;
&lt;li&gt;I don&#x27;t know how sustainable this project is, it&#x27;s certainly noble&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;go all in and run a linux distro
&lt;ul&gt;
&lt;li&gt;definitely no apps for you&lt;&#x2F;li&gt;
&lt;li&gt;get to take the moral high ground&lt;&#x2F;li&gt;
&lt;li&gt;lose touch with everyone who is on whatsapp&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It would be nice to think that by choosing to run the most open thing I can I am in some way helping, but I think the truth is users really don&#x27;t make much difference to projects like this unless they come in enough numbers to sway app vendors like WhatsCrapp to support more obscure platforms. It&#x27;s only the hackers and those who can financially fund projects who really make a difference here. So while I want to run the most open thing I can it doesn&#x27;t really matter a hill of beans outside of my own brain whether I do or not.&lt;&#x2F;p&gt;
&lt;p&gt;I think having written down the options I&#x27;m swinging towards lineage + proprietary google services. This seems to solve the immediate problem of getting unlocked and rooted and getting working backups again without losing everything that&#x27;s useful to me in the process.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m glad I&#x27;ve tried the microG version, and hope we see open source slowly chip away at the power of the two giants just like Linux did in the desktop space over decades.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-lineageos-google-services-on-oneplus-9-pro-take-2-fail&quot;&gt;Installing LineageOS + google services on OnePlus 9 Pro (take 2) - fail&lt;&#x2F;h2&gt;
&lt;p&gt;I now have the lineage bootloader so the steps to get into recovery etc are a bit different than with stock or TWRP.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Note: If you want the Google Apps add-on on your device, you must follow this step before booting into LineageOS for the first time!&quot; ~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;install#installing-lineageos-from-recovery&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;install#installing-lineageos-from-recovery&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Download latest nightly (there&#x27;s no stable&#x2F;unstable on this): &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;download.lineageos.org&#x2F;lemonadep&quot;&gt;https:&#x2F;&#x2F;download.lineageos.org&#x2F;lemonadep&lt;&#x2F;a&gt; - this has both the ROM (OS image) and the recovery image.&lt;&#x2F;li&gt;
&lt;li&gt;Download copy-partitions &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;androidfilehost.com&#x2F;?fid=2188818919693768129&quot;&gt;https:&#x2F;&#x2F;androidfilehost.com&#x2F;?fid=2188818919693768129&lt;&#x2F;a&gt; (as per wiki)
&lt;ol&gt;
&lt;li&gt;The sha256 for the copy I have is &lt;code&gt;200877dfd0869a0e628955b807705765a91e34dff3bfeca9f828e916346aa85f  copy-partitions-20210323_1922.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Verify all the sha256 sums: &lt;code&gt;sha256sum -c *.sha256&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Boot to fastboot&lt;&#x2F;li&gt;
&lt;li&gt;flash the lineage recovery: &lt;code&gt;fastboot flash boot lineage-18.1-20211228-recovery-lemonadep.img&lt;&#x2F;code&gt;
&lt;ol&gt;
&lt;li&gt;don&#x27;t reboot yet&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;copy partitions as instructed
&lt;ol&gt;
&lt;li&gt;switch to recovery&lt;&#x2F;li&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload copy-partitions-20210323_1922.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Ignore unknown sig and &quot;continue&quot;&lt;&#x2F;li&gt;
&lt;li&gt;come back out of recovery menu (don&#x27;t reboot yet)&lt;&#x2F;li&gt;
&lt;li&gt;don&#x27;t reboot yet&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&quot;factory reset&quot; &amp;gt; &quot;wipe all data&quot;
&lt;ol&gt;
&lt;li&gt;don&#x27;t reboot yet&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;flash OS:
&lt;ol&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload lineage-18.1-20211228-nightly-lemonadep-signed.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;don&#x27;t reboot yet&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;MindTheGapps - I haven&#x27;t found any instructions for this anywhere
&lt;ol&gt;
&lt;li&gt;check the arch (it&#x27;s &lt;code&gt;arm64&lt;&#x2F;code&gt;) here &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Download the arm64 build from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;androidfilehost.com&#x2F;?w=files&amp;amp;flid=322935&quot;&gt;https:&#x2F;&#x2F;androidfilehost.com&#x2F;?w=files&amp;amp;flid=322935&lt;&#x2F;a&gt;
&lt;ol&gt;
&lt;li&gt;or the &quot;mirror&quot; &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;downloads.codefi.re&#x2F;jdcteam&#x2F;javelinanddart&#x2F;gapps&quot;&gt;http:&#x2F;&#x2F;downloads.codefi.re&#x2F;jdcteam&#x2F;javelinanddart&#x2F;gapps&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Given there&#x27;s no shas anywhere I downloaded from several mirrors and cross-checked the hashes. &lt;code&gt;85481cb98c8a8692f52c033ead1db436870af385498a917701fcd8c6182e145c  MindTheGapps-11.0.0-arm64-20210920_084011.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload MindTheGapps-11.0.0-arm64-20210920_084011.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;ignore signature warning (the price of escaping a closed ecosystem)&lt;&#x2F;li&gt;
&lt;li&gt;error shown on phone, roughly:&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;low resource device detected, removing large extras&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;not enough space for gapps! aborting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error in &#x2F;sideload&#x2F;package.zip (status 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;MindTheGapps&#x2F;vendor_gapps&#x2F;-&#x2F;commit&#x2F;0f6b4560288267b644c49de0fdc538fa30980708&quot;&gt;patch that adds error message&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;MindTheGapps&#x2F;vendor_gapps&#x2F;-&#x2F;blob&#x2F;de0847802034654d63150c3de3ca05f1af326316&#x2F;build&#x2F;meta&#x2F;com&#x2F;google&#x2F;android&#x2F;update-binary#L38&quot;&gt;current message on &lt;code&gt;sigma&lt;&#x2F;code&gt; branch&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;In lineage recovery, mount &lt;code&gt;sytsem&lt;&#x2F;code&gt; and enable adb, run df:&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OnePlus9Pro:&#x2F; # df -h &#x2F;mnt&#x2F;system                                                                                            &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem      Size  Used Avail Use% Mounted on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;block&#x2F;dm-2 0.9G  0.9G  3.0M 100% &#x2F;mnt&#x2F;system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;That is indeed quite full. Annoyingly the installer doesn&#x27;t say which partition is full.&lt;&#x2F;li&gt;
&lt;li&gt;Some ideas here &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;q-insufficient-storage-space-in-system-partition.3018464&#x2F;&quot;&gt;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;q-insufficient-storage-space-in-system-partition.3018464&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Try format &amp;amp; reboot to recovery, nope.&lt;&#x2F;li&gt;
&lt;li&gt;hint that it could be slot related &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;fuykda&#x2F;lineage_os_171_opengapps_error_not_sufficient&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;fuykda&#x2F;lineage_os_171_opengapps_error_not_sufficient&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;let&#x27;s try a swap slot as per &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;fqashj&#x2F;difficulty_installing_gapps_after_lineage_os&#x2F;fluhd8s&#x2F;?context=3&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;fqashj&#x2F;difficulty_installing_gapps_after_lineage_os&#x2F;fluhd8s&#x2F;?context=3&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;enter fastboot&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;MindTheGapps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ fastboot set_active other&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Setting current slot to &amp;#39;b&amp;#39;                        OKAY [  0.043s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finished. Total time: 0.044s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol&gt;
&lt;li&gt;enter recovery&lt;&#x2F;li&gt;
&lt;li&gt;re-run the sideload&lt;&#x2F;li&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload MindTheGapps-11.0.0-arm64-20210920_084011.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;ignore signature warning (the price of escaping a closed ecosystem)&lt;&#x2F;li&gt;
&lt;li&gt;same space error. sigh&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;possible-cause-of-space-error&quot;&gt;Possible cause of space error&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;q-insufficient-storage-space-in-system-partition.3018464&#x2F;post-76072942&quot;&gt;Partition not mounted at all&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;q-insufficient-storage-space-in-system-partition.3018464&#x2F;#post-84651523&quot;&gt;LineageOS image has partitions that are too small&lt;&#x2F;a&gt; to fit extra g-apps in.
&lt;ul&gt;
&lt;li&gt;Maybe use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;dev-kernel-4-4-android-8-0-oreo.3688948&#x2F;&quot;&gt;TWRP BigSys&lt;&#x2F;a&gt; to get bigger partitions??&lt;&#x2F;li&gt;
&lt;li&gt;Manually re-partition? Alegedly dangerous.
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;216123&#x2F;android-how-to-increase-system-partition-and-decrease-data-partition#comment276924_216123&quot;&gt;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;216123&#x2F;android-how-to-increase-system-partition-and-decrease-data-partition#comment276924_216123&lt;&#x2F;a&gt; warning of brickability if you touch wrong device&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;Android&#x2F;comments&#x2F;2o8lvf&#x2F;why_cant_we_resize_partitions_on_android_but_on&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;Android&#x2F;comments&#x2F;2o8lvf&#x2F;why_cant_we_resize_partitions_on_android_but_on&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;fu70jg&#x2F;linageos_171_unable_to_install_gapps&#x2F;&quot;&gt;Incompatibility with Lineage bootloader - use TWRP instead&lt;&#x2F;a&gt; - worth a try I think, probably the next thing I&#x27;ll try.&lt;&#x2F;li&gt;
&lt;li&gt;Ruled Out: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;fuykda&#x2F;lineage_os_171_opengapps_error_not_sufficient&#x2F;&quot;&gt;Wrong&#x2F;stale slot in use&lt;&#x2F;a&gt; - tried swap slot (above), no change.&lt;&#x2F;li&gt;
&lt;li&gt;Ruled out: Booting phone before gapps install (didn&#x27;t do this so not this).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;patching-the-installer-abandoned&quot;&gt;Patching the installer - abandoned&lt;&#x2F;h3&gt;
&lt;p&gt;It seems to me having read around that the error message is hiding useful information on the state of the device and what exactly failed. (Which partition is out of space? Is it just read only or something?). I&#x27;n not feeling like playing with partitioning given the warnings I saw on a forum of potentially bricking a device&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s links to the source above and I did start fiddling with this, but you have to figure out how to re-sign the zip to get it to install at which point I fell down an android-sized rabbit hole.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;signing-zips-and-apks&quot;&gt;Signing zips and apks&lt;&#x2F;h4&gt;
&lt;p&gt;Here&#x27;s what I found so far, I haven&#x27;t got it working yet.&lt;&#x2F;p&gt;
&lt;p&gt;I &lt;em&gt;think&lt;&#x2F;em&gt; it&#x27;s the same signing that you have to do to &lt;code&gt;apk&lt;&#x2F;code&gt; files, and &lt;code&gt;apk&lt;&#x2F;code&gt; is just a special shaped &lt;code&gt;zip&lt;&#x2F;code&gt; file. Off into learning-android-sdk-land I went...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;There&#x27;s some kind of strange android app that can sign zips called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;forums&#x2F;topic&#x2F;zipsigner&#x2F;&quot;&gt;ZipSigner&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;archive&#x2F;p&#x2F;zip-signer&#x2F;issues&#x2F;3&quot;&gt;ZipSigner is missing source code&lt;&#x2F;a&gt; so you are relying on random binaries. Dodgy but probably well intentioned.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;222262&#x2F;how-to-create-manually-create-my-own-%e1%b4%8f%e1%b4%9b%e1%b4%80-update-file-to-be-used-for-adb-sideload&quot;&gt;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;222262&#x2F;how-to-create-manually-create-my-own-%e1%b4%8f%e1%b4%9b%e1%b4%80-update-file-to-be-used-for-adb-sideload&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;95425&#x2F;update-zip-just-for-fixing-file-permissions-possible&quot;&gt;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;95425&#x2F;update-zip-just-for-fixing-file-permissions-possible&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;tutorial-the-updater-script-completely-explained.2377695&#x2F;&quot;&gt;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;tutorial-the-updater-script-completely-explained.2377695&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bettermobileapp.com&#x2F;article&#x2F;10558021&#x2F;Updater-script&quot;&gt;https:&#x2F;&#x2F;www.bettermobileapp.com&#x2F;article&#x2F;10558021&#x2F;Updater-script&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;191043&#x2F;edditing-updater-script&quot;&gt;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;191043&#x2F;edditing-updater-script&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;androidforums.com&#x2F;threads&#x2F;custom-rom-updater-scipt-troubleshooting.701752&#x2F;&quot;&gt;https:&#x2F;&#x2F;androidforums.com&#x2F;threads&#x2F;custom-rom-updater-scipt-troubleshooting.701752&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;35600&#x2F;how-to-create-an-update-zip-file-that-can-copy-rename-a-file&quot;&gt;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;35600&#x2F;how-to-create-an-update-zip-file-that-can-copy-rename-a-file&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;command-line&#x2F;zipalign&quot;&gt;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;command-line&#x2F;zipalign&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;publish&#x2F;app-signing#opt-out&quot;&gt;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;publish&#x2F;app-signing#opt-out&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;command-line&#x2F;apksigner&quot;&gt;https:&#x2F;&#x2F;developer.android.com&#x2F;studio&#x2F;command-line&#x2F;apksigner&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.addictivetips.com&#x2F;mobile&#x2F;what-is-zipalign-in-android-and-how-it-works-complete-guide&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.addictivetips.com&#x2F;mobile&#x2F;what-is-zipalign-in-android-and-how-it-works-complete-guide&#x2F;&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3994035&#x2F;what-is-aligned-memory-allocation&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3994035&#x2F;what-is-aligned-memory-allocation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.androidcentral.com&#x2F;installing-android-sdk-windows-mac-and-linux-tutorial&quot;&gt;https:&#x2F;&#x2F;www.androidcentral.com&#x2F;installing-android-sdk-windows-mac-and-linux-tutorial&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;let-s-try-twrp-lineage-mindthegapps-fail&quot;&gt;Let&#x27;s try TWRP+Lineage+MindTheGapps - fail&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;install-twrp&quot;&gt;Install TWRP&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;replace-lineageos-recovery-twrp&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.getdroidtips.com&#x2F;replace-lineageos-recovery-twrp&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reboot phone to fastboot or something (the built-in one where the volume key changes options), leave it in that state&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fastboot devices&lt;&#x2F;code&gt; on linux should show the phone&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fastboot boot twrp.img&lt;&#x2F;code&gt; (already downloaded and symlinked above)&lt;&#x2F;li&gt;
&lt;li&gt;Phone reboots into twrp temporarily&lt;&#x2F;li&gt;
&lt;li&gt;Advanced &amp;gt; flash current twrp&lt;&#x2F;li&gt;
&lt;li&gt;Reboot (ok the no-OS warning)&lt;&#x2F;li&gt;
&lt;li&gt;Yay, booted into twrp, comforting&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;install-lineageos-yet-again&quot;&gt;Install LineageOS (yet again)&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Well, let&#x27;s get a new nightly&lt;&#x2F;li&gt;
&lt;li&gt;Instructions say check model...
&lt;ul&gt;
&lt;li&gt;Reboot to twrp (recovery) with USB connected to laptop&lt;&#x2F;li&gt;
&lt;li&gt;Laptop pops window for new mount &lt;code&gt;mtp:&#x2F;&#x2F;OnePlus_LE2123_dade278d&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Yep, LE2123 is in the supported list. Phew.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Skip all the &quot;recovery&quot; steps in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;install&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;install&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;m guessing I don&#x27;t need to run &quot;copy partitions&quot; again because that&#x27;s to avoid only having one working slot, and I already have to having done this before. Tell me if I&#x27;m wrong!&lt;&#x2F;li&gt;
&lt;li&gt;Give up waiting for new image download (~1GB), continue with older image...&lt;&#x2F;li&gt;
&lt;li&gt;Factory reset
&lt;ul&gt;
&lt;li&gt;TWRP &amp;gt; Wipe &amp;gt; Swipe for factory reset&lt;&#x2F;li&gt;
&lt;li&gt;back&lt;&#x2F;li&gt;
&lt;li&gt;Format Data (button)&lt;&#x2F;li&gt;
&lt;li&gt;type yes to continue (wiping all apps &amp;amp; data)&lt;&#x2F;li&gt;
&lt;li&gt;back to main menu (android back button lots of times)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Flash lineage
&lt;ul&gt;
&lt;li&gt;Still in TWRP&lt;&#x2F;li&gt;
&lt;li&gt;Advanced &amp;gt; ADB Sideload&lt;&#x2F;li&gt;
&lt;li&gt;Tick the wipe boxes (&quot;Dalvik cache&quot; + &quot;cache&quot;)&lt;&#x2F;li&gt;
&lt;li&gt;Swipe to sart sideload&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload lineage-18.1-20211228-nightly-lemonadep-signed.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;back&lt;&#x2F;li&gt;
&lt;li&gt;Don&#x27;t reboot yet&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Add MindTheGaps
&lt;ul&gt;
&lt;li&gt;still in TWRP&lt;&#x2F;li&gt;
&lt;li&gt;ADB Sideload&lt;&#x2F;li&gt;
&lt;li&gt;swipe (cache wipe still selected)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload MindTheGapps-11.0.0-arm64-20210920_084011.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;fail. log:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**********************&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MindTheGapps installer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**********************&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Extracting files&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Setting up environment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Mounting partitions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Could not mount &#x2F;mnt&#x2F;system! Aborting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Updater process ended with ERROR: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For goodness sake.&lt;&#x2F;p&gt;
&lt;p&gt;Fuck it, let&#x27;s try the other gapps even though it says not to....&lt;&#x2F;p&gt;
&lt;p&gt;Reboot just to have a look... Lineage running fine, no sign of any gapps.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;let-s-try-twrp-lineage-opengapps-fail&quot;&gt;Let&#x27;s try TWRP+Lineage+OpenGApps - fail&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Power off&lt;&#x2F;li&gt;
&lt;li&gt;power + vol-down - ended up in lineage recovery, wat?? swap slot??&lt;&#x2F;li&gt;
&lt;li&gt;reboot to bootloader? no that&#x27;s the built-in pixelated bright green &quot;START&quot; thing, oh actually that&#x27;s fine, that&#x27;s the fastboot thing.&lt;&#x2F;li&gt;
&lt;li&gt;switch slot as above&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot set_active other&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Setting current slot to &amp;#39;b&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;... OKAY [  0.048s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finished. Total time: 0.056s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;reboot to recovery&lt;&#x2F;li&gt;
&lt;li&gt;back in TWRP&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That&#x27;s cool! I have lineage recovery in slot &lt;code&gt;a&lt;&#x2F;code&gt; and TWRP in slot &lt;code&gt;b&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Okay, back to the plan.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;lineage-again-again-again&quot;&gt;Lineage (again again again...)&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Repeat the lineage intall steps above (no idea if that&#x27;s really necessary but &lt;em&gt;shrug&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;opengapps-install-fail&quot;&gt;OpenGApps install - fail&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Download &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;opengapps.org&#x2F;?api=11.0&amp;amp;variant=nano&quot;&gt;https:&#x2F;&#x2F;opengapps.org&#x2F;?api=11.0&amp;amp;variant=nano&lt;&#x2F;a&gt; - ARM64 &#x2F; 11 &#x2F; nano
&lt;ul&gt;
&lt;li&gt;(manually changed from 10 to 11 from link on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;gapps&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;gapps&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;download the md5 too&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;md5sum -c *.md5&lt;&#x2F;code&gt; to validate...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Back to ADB Sideload in TWRP (cache wipe ticked x2), swipe to start&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload open_gapps-arm64-11.0-nano-20220215.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;cross fingers&lt;&#x2F;li&gt;
&lt;li&gt;bah. failed, basically same error.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Performing system space calculations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Insufficient storage space available in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;System partition. ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error Code: 70&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;grap logs as instructed: &lt;code&gt;adb pull &#x2F;sdcard&#x2F;open_gapps_log.txt&lt;&#x2F;code&gt; - success&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;c4f16fd656f3faf8a16d06aa113e0346&quot;&gt;gist of log file open_gapps_log.txt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Important bit here is that there is &lt;strong&gt;ZERO&lt;&#x2F;strong&gt; space, so choosing smaller install is not going to work.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Current Free Space |         0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well on the plus side the diagnostics are muuuuch better in OpenGApps so that&#x27;s saved me fucking around trying to patch MindTheGaps&#x27; installer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;two-phone-timmy-the-burner-phone&quot;&gt;Two-phone-Timmy - the burner phone&lt;&#x2F;h2&gt;
&lt;p&gt;Having spent some time completely stumped by the space issue and giving it some thought I realize that this battle with Android will never end. Trying to get an unholy mix of Libre and proprietary to mix is like oil and water.&lt;&#x2F;p&gt;
&lt;p&gt;I can opt out of that battle by running two phones.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A &quot;primary&quot; phone that I use as much as possible, running the Free-est thing I can muster. This would get the sim card. This would be the OnePlus 9 pro, ideally running PureOS as per the Librem 5 phone, but if not that then Lineage without the GApps that I couldn&#x27;t get to work.&lt;&#x2F;li&gt;
&lt;li&gt;A burner phonee that&#x27;s basically stock Android so that I can fall back to this for everything that can&#x27;t or won&#x27;t work on a free-er &amp;amp; unlocked base OS. (My existing OnePlus 5t for now while it lasts, reset to stock OxygenOS). This one can the get internet by tethering to the primary. I don&#x27;t think any of the apps actually require the sim to be present. I guess we&#x27;ll see.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;the-primary-9-pro&quot;&gt;The primary (9 Pro)&lt;&#x2F;h3&gt;
&lt;p&gt;The idea here is to get the free-est possible base layer (i.e. operating system), and then get maximum functionality within that. Anything that doesn&#x27;t work or I can&#x27;t find a working alternative to gets punted to the burner phone while we wait for hell to freeze over again. This will be the compromise for now.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Research trying PureOS, see what the app ecosystem is like - done - nope
&lt;ul&gt;
&lt;li&gt;research done, doesn&#x27;t seem to be possible to install on the OnePlus. Next...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Continue with Lineage (I left the phone with a working but empty install of this)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Don&#x27;t install proprietary google play services or play store at all.&lt;&#x2F;strong&gt; - This is the line in the sand. I would have accepted it for now, but given I couldn&#x27;t install it, I&#x27;ll take it as the new battle line for free vs proprietary.&lt;&#x2F;li&gt;
&lt;li&gt;Install microG for re-implementation of shared services (i.e. location, polling for updates from servers etc)&lt;&#x2F;li&gt;
&lt;li&gt;Install Aurora play store proxy again to be able to try out app store apps&lt;&#x2F;li&gt;
&lt;li&gt;See how close I can get to a usable phone.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-burner-5t&quot;&gt;The burner (5t)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Factory reset the 5t&lt;&#x2F;li&gt;
&lt;li&gt;Install just what I couldn&#x27;t get to work on the primary&lt;&#x2F;li&gt;
&lt;li&gt;Cry because the backups were shit and now I&#x27;ve lost access to something I care about (I predict)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;primary-setup-experimenting&quot;&gt;Primary setup - experimenting&lt;&#x2F;h2&gt;
&lt;p&gt;Fired up the lineage (minus all google stuff) that I&#x27;d installed and then failed to get any gapps on (space issue above, no longer care).&lt;&#x2F;p&gt;
&lt;p&gt;Went through language prompt, was looking at time prompt in setup wizard when the phone rebooted with some kind of couldn&#x27;t read data error. Disturbing. Rebooted, selected &quot;try again&quot; and it didn&#x27;t do it this time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setup-wizard&quot;&gt;Setup wizard&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- selected UK location,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- GMT timezone.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Put in wifi password (incorrectly)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- set up pin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- set up fingerprint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- booted into OS (yay, pleasing to see Lineage in action)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;os-update-with-on-phone-updater&quot;&gt;OS update with on-phone updater&lt;&#x2F;h3&gt;
&lt;p&gt;settings &amp;gt; advanced &amp;gt; updater&lt;&#x2F;p&gt;
&lt;p&gt;shows list of OS updates. hit refresh, nothing new. latest is 18.1 26th Apr 2022&lt;&#x2F;p&gt;
&lt;p&gt;tap download ....&lt;&#x2F;p&gt;
&lt;p&gt;tap intall (even longer pause ... installing ... finalising package installation ...) ..&lt;&#x2F;p&gt;
&lt;p&gt;reboot (press button that&#x27;s presented)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;config&quot;&gt;config&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;turn off annoying sounds
&lt;ul&gt;
&lt;li&gt;settings &amp;gt; sound &amp;gt; advanced&lt;&#x2F;li&gt;
&lt;li&gt;screen locking sound - off&lt;&#x2F;li&gt;
&lt;li&gt;touch sounds - off&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;todo&quot;&gt;todo&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;replacement contact management (currently using google)&lt;&#x2F;li&gt;
&lt;li&gt;replacement calendar management (currently using google)&lt;&#x2F;li&gt;
&lt;li&gt;insert sim&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;already-google-free&quot;&gt;already google-free&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;email (fastmail domain + k9mail app)&lt;&#x2F;li&gt;
&lt;li&gt;broswer - firefox&lt;&#x2F;li&gt;
&lt;li&gt;search - duckduckgo&lt;&#x2F;li&gt;
&lt;li&gt;OTP - andOTP&lt;&#x2F;li&gt;
&lt;li&gt;maps&#x2F;satnav (partially) - could use waze + maps.me (google maps is a decent car satnav, not found a perfect equivalent)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;burner-phone&quot;&gt;burner phone&lt;&#x2F;h2&gt;
&lt;p&gt;No sim in this one, use wifi and&#x2F;or bluetooth tethering to get internet on it.&lt;&#x2F;p&gt;
&lt;p&gt;Things I can&#x27;t escape the googly jail for&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;google maps?&lt;&#x2F;li&gt;
&lt;li&gt;apps for clients
&lt;ul&gt;
&lt;li&gt;microsoft outlook&lt;&#x2F;li&gt;
&lt;li&gt;securid (vpn stuff)&lt;&#x2F;li&gt;
&lt;li&gt;google authenticator (use andOTP instead wherever possible)&lt;&#x2F;li&gt;
&lt;li&gt;microsoft authenticator (yuck, what&#x27;s wrong with the OTP standard?!?!)&lt;&#x2F;li&gt;
&lt;li&gt;digidentity&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;banking apps that don&#x27;t work on the primary phone (not naming because haxxors)&lt;&#x2F;li&gt;
&lt;li&gt;google pay (never used it, just use an actual card)&lt;&#x2F;li&gt;
&lt;li&gt;google home for controlling the chromecast&lt;&#x2F;li&gt;
&lt;li&gt;spotify just for casting to the chromecast audio&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To my horror I have discovered that android allows apps to force remote admin privs so that IT departments can snoop on your BYOD. Hello Microsoft Outlook + Active Directory. Yet more erosion of user rights in the name of security. There&#x27;s no way in hell I&#x27;m allowing a client to be an admin on my primary phone so this is burner phone territory if at all necessary; though I just won&#x27;t install any of that junk at all and will be uncontactable within their network unless on their supplied devices. Shrug.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;primary-phone-microg&quot;&gt;Primary phone - microG&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;lineage-microg-failed-install&quot;&gt;lineage+microG - failed install&lt;&#x2F;h3&gt;
&lt;p&gt;Re-run setup in section: Installing “Lineage for microG”&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;OS install
&lt;ul&gt;
&lt;li&gt;power off&lt;&#x2F;li&gt;
&lt;li&gt;boot into lineage recovery (vol-down + power) (currently slot &quot;b&quot; is active)&lt;&#x2F;li&gt;
&lt;li&gt;&quot;apply update&quot; &amp;gt; &quot;apply from adb&quot; (aka sideload)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb sideload lineage-18.1-20211220-microG-lemonadep.zip&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;it seems this is flashed to slot a and then slot is automatically swapped&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;ignore signature warning&lt;&#x2F;li&gt;
&lt;li&gt;accept downgrade warning&lt;&#x2F;li&gt;
&lt;li&gt;completed&lt;&#x2F;li&gt;
&lt;li&gt;back back&lt;&#x2F;li&gt;
&lt;li&gt;factory reset&lt;&#x2F;li&gt;
&lt;li&gt;reboot&lt;&#x2F;li&gt;
&lt;li&gt;drops to bootloader thing&lt;&#x2F;li&gt;
&lt;li&gt;&quot;start&quot; (power button to accept)&lt;&#x2F;li&gt;
&lt;li&gt;loops back to bootloader thing. damn.&lt;&#x2F;li&gt;
&lt;li&gt;vol down vol down - Recovery - power button to accept&lt;&#x2F;li&gt;
&lt;li&gt;starts lineage recovery - &quot;Active slot: a&quot; - hmmm&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;try swap slot&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ fastboot set_active other&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Setting current slot to &amp;#39;b&amp;#39;                        (bootloader) Changing the active slot with a snapshot applied may cancel the update.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OKAY [  0.038s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finished. Total time: 0.040s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;power off, power on&lt;&#x2F;p&gt;
&lt;p&gt;that worked, now enters the lineage setup steps&lt;&#x2F;p&gt;
&lt;p&gt;oh but it&#x27;s back to the blank OS, the apr 2022 version!.&lt;&#x2F;p&gt;
&lt;p&gt;guess there&#x27;s a slot for two OSes!&lt;&#x2F;p&gt;
&lt;p&gt;swap slot again, back to the bootloader loop. interesting.&lt;&#x2F;p&gt;
&lt;p&gt;let&#x27;s try installing again&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot set_active other&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Setting current slot to &amp;#39;a&amp;#39;                        OKAY [  0.060s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finished. Total time: 0.061s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG      &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb sideload lineage-18.1-20211220-microG-lemonadep.zip                                                                     &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;serving: &amp;#39;lineage-18.1-20211220-microG-lemonadep.zip&amp;#39;  (~21%)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;factory reset&lt;&#x2F;p&gt;
&lt;p&gt;reboot&lt;&#x2F;p&gt;
&lt;p&gt;cross fingers. nope. still just drops back to bootloader&lt;&#x2F;p&gt;
&lt;p&gt;recovery &amp;gt; factory reset &amp;gt; reboot&lt;&#x2F;p&gt;
&lt;p&gt;nope still fooked
reboot to bootloader which says &quot;Active slot: b&quot; which is a bit odd. Maybe it does a swap slot automatically after flashing?&lt;&#x2F;p&gt;
&lt;p&gt;so at this point slot a has a fooked lineage-microG (maybe) and slot b has a functioning but blank vanilla lineage. I think.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;GooglePixel&#x2F;comments&#x2F;8cz6m9&#x2F;google_pixel_bootslot_b_brick&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;GooglePixel&#x2F;comments&#x2F;8cz6m9&#x2F;google_pixel_bootslot_b_brick&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;grab the vars with &lt;code&gt;fastboot getvar all 2&amp;gt;&amp;amp;1 | sort &amp;gt; fastboot-getvar.txt&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;output (sensitive things redacted with XXXX) - interesting but not super helpful:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;all: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) battery-voltage:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) cpu-abi:arm64-v8a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) current-slot:b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) dynamic-partition:true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) first-api-level:30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:abl_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:abl:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:ALIGN_TO_128K_1:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:ALIGN_TO_128K_2:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:android_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:aop:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:apdp_full:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:apdp:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:bluetooth:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:boot:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:carrier:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:cdt:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:connsec:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:cpucp:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:ddr:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:devcfg:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:devinfo:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:dinfo:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:dip:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:DRIVER:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:dsp:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:dtbo:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:engineering_cdt:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:featenabler:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:frp:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:fsc:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:fsg:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:hyp_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:hyp:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:imagefv:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:kernel_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:keymaster:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:keystore:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:limits-cdsp:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:limits:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:logdump:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:logfs:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:mdcompress:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:mdtpsecapp:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:mdtp:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:metadata:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:misc:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:modemdump:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:modemst1:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:modemst2:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:modem:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:multiimgoem:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:ocdt:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:odm_b-cow:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:odm:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:oplusdycnvbk:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:opluslog:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:oplusreserve1:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:oplusreserve2:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:oplusreserve3:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:oplusreserve4:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:oplusreserve5:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:oplus_sec:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:oplusstanvbk:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:param:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:persist_bkp:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:persist:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:product_b-cow:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:product:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:qmcs:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:qsee_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:qupfw:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:qweslicstore:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:rawdump:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:rtice:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:sda:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:sdb:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:sdc:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:sdd:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:sde:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:sdf:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:secdata:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:shrm:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:splash:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:spunvm:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:ssd:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:storsec:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:super:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:system_b-cow:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:system_ext_b-cow:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:system_ext:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:system:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:tzsc:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:tz:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:uefisecapp:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:uefivarstore:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:userdata:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:vbmeta_system:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:vbmeta_vendor:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:vbmeta:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:vendor_b-cow:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:vendor_boot:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:vendor:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:vm-bootsys:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:vm-data:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:xbl_config:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) has-slot:xbl:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) hw-revision:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:abl_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:abl_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:abl_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:ALIGN_TO_128K_1:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:ALIGN_TO_128K_2:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:android_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:aop_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:aop_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:apdp_full:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:apdp:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:bluetooth_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:bluetooth_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:boot_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:boot_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:carrier:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:cdt:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:connsec:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:cpucp_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:cpucp_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:ddr:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:devcfg_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:devcfg_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:devinfo:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:dinfo:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:dip:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:DRIVER:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:dsp_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:dsp_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:dtbo_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:dtbo_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:engineering_cdt_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:engineering_cdt_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:featenabler_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:featenabler_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:frp:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:fsc:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:fsg:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:hyp_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:hyp_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:hyp_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:imagefv_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:imagefv_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:kernel_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:keymaster_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:keymaster_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:keystore:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:limits-cdsp:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:limits:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:logdump:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:logfs:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:mdcompress:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:mdtp_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:mdtp_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:mdtpsecapp_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:mdtpsecapp_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:metadata:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:misc:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:modem_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:modem_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:modemdump:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:modemst1:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:modemst2:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:multiimgoem_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:multiimgoem_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:ocdt:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:odm_b-cow:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:odm_b:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplusdycnvbk:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:opluslog:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplusreserve1:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplusreserve2:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplusreserve3:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplusreserve4:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplusreserve5:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplus_sec_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplus_sec_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplusstanvbk_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:oplusstanvbk_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:param:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:persist_bkp:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:persist:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:product_b-cow:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:product_b:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:qmcs:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:qsee_log:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:qupfw_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:qupfw_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:qweslicstore_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:qweslicstore_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:rawdump:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:rtice:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:sda:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:sdb:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:sdc:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:sdd:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:sde:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:sdf:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:secdata:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:shrm_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:shrm_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:splash_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:splash_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:spunvm:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:ssd:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:storsec:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:super:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:system_b-cow:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:system_b:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:system_ext_b-cow:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:system_ext_b:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:tz_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:tz_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:tzsc:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:uefisecapp_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:uefisecapp_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:uefivarstore:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:userdata:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vbmeta_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vbmeta_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vbmeta_system_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vbmeta_system_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vbmeta_vendor_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vbmeta_vendor_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vendor_b-cow:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vendor_boot_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vendor_boot_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vendor_b:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vm-bootsys_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vm-bootsys_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:vm-data:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:xbl_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:xbl_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:xbl_config_a:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-logical:xbl_config_b:no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) is-userspace:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) max-download-size:0x10000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:abl_a:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:abl_b:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:abl_log:0xFD0000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:ALIGN_TO_128K_1:0x1A000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:ALIGN_TO_128K_2:0x1A000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:android_log:0xFD0000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:aop_a:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:aop_b:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:apdp:0x40000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:apdp_full:0x40000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:bluetooth_a:0x200000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:bluetooth_b:0x200000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:boot_a:0xC000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:boot_b:0xC000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:carrier:0x4000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:cdt:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:connsec:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:cpucp_a:0x100000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:cpucp_b:0x100000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:ddr:0x100000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:devcfg_a:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:devcfg_b:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:devinfo:0x1000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:dinfo:0x4000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:dip:0x100000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:DRIVER:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:dsp_a:0x4000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:dsp_b:0x4000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:dtbo_a:0x1800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:dtbo_b:0x1800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:engineering_cdt_a:0x100000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:engineering_cdt_b:0x100000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:featenabler_a:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:featenabler_b:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:frp:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:fsc:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:fsg:0x300000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:hyp_a:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:hyp_b:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:hyp_log:0xFD0000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:imagefv_a:0x200000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:imagefv_b:0x200000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:kernel_log:0xFD0000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:keymaster_a:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:keymaster_b:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:keystore:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:limits:0x1000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:limits-cdsp:0x1000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:logdump:0x4000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:logfs:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:mdcompress:0x1400000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:mdtp_a:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:mdtp_b:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:mdtpsecapp_a:0x400000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:mdtpsecapp_b:0x400000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:metadata:0x1000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:misc:0x100000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:modem_a:0x14A00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:modem_b:0x14A00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:modemdump:0x12C00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:modemst1:0x300000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:modemst2:0x300000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:multiimgoem_a:0x8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:multiimgoem_b:0x8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:ocdt:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:odm_b:0x2BD000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:odm_b-cow:0x2C1000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplusdycnvbk:0xA00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:opluslog:0x10000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplusreserve1:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplusreserve2:0x10000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplusreserve3:0x4000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplusreserve4:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplusreserve5:0x4000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplus_sec_a:0xA00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplus_sec_b:0xA00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplusstanvbk_a:0xA00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:oplusstanvbk_b:0xA00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:param:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:persist:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:persist_bkp:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:product_b:0x1652F000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:product_b-cow:0x16696000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:qmcs:0x1E00000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:qsee_log:0xFD0000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:qupfw_a:0x14000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:qupfw_b:0x14000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:qweslicstore_a:0x40000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:qweslicstore_b:0x40000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:rawdump:0x8000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:rtice:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:sda:0x3A10800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:sdb:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:sdc:0x800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:sdd:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:sde:0x180000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:sdf:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:secdata:0x7000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:shrm_a:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:shrm_b:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:splash_a:0x20A4000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:splash_b:0x20A4000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:spunvm:0x2000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:ssd:0x2000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:storsec:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:super:0x29B000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:system_b:0x406A4000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:system_b-cow:0x40AAC000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:system_ext_b:0xDF3A000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:system_ext_b-cow:0xE01B000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:tz_a:0x400000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:tz_b:0x400000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:tzsc:0x20000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:uefisecapp_a:0x200000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:uefisecapp_b:0x200000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:uefivarstore:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:userdata:0x3751FB3000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vbmeta_a:0x10000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vbmeta_b:0x10000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vbmeta_system_a:0x10000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vbmeta_system_b:0x10000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vbmeta_vendor_a:0x10000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vbmeta_vendor_b:0x10000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vendor_b:0x50520000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vendor_b-cow:0x50A27000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vendor_boot_a:0xC000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vendor_boot_b:0xC000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vm-bootsys_a:0x10625000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vm-bootsys_b:0x10625000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:vm-data:0x20A4000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:xbl_a:0x600000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:xbl_b:0x600000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:xbl_config_a:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) partition-size:xbl_config_b:0x80000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) product:OnePlus9Pro&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) secure:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) security-patch-level:2021-12-05&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) serialno:XXXXXXX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) slot-count:2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) snapshot-update-status:snapshotted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) super-partition-name:super&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) system-fingerprint:OnePlus&#x2F;OnePlus9Pro_EEA&#x2F;OnePlus9Pro:11&#x2F;RKQ1.201105.002&#x2F;2111112053:user&#x2F;release-keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) treble-enabled:true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) unlocked:yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) vendor-fingerprint:OnePlus&#x2F;OnePlus9Pro_EEA&#x2F;OnePlus9Pro:11&#x2F;RKQ1.201105.002&#x2F;2111112053:user&#x2F;release-keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) version:0.4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) version-baseband:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) version-bootloader:unknown&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) version-os:11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(bootloader) version-vndk:30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finished. Total time: 1.181s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Fuck. Again. ... TBC. AGAIN. how many more yaks are left to shave one wonders.&lt;&#x2F;p&gt;
&lt;p&gt;todo:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;skip all the guided setup steps&lt;&#x2F;li&gt;
&lt;li&gt;open the microG app&lt;&#x2F;li&gt;
&lt;li&gt;run the self check&lt;&#x2F;li&gt;
&lt;li&gt;magisk root if needed&lt;&#x2F;li&gt;
&lt;li&gt;everything else&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;config-1&quot;&gt;config&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;settings
&lt;ul&gt;
&lt;li&gt;sound&lt;&#x2F;li&gt;
&lt;li&gt;advanced
&lt;ul&gt;
&lt;li&gt;screen locking sound - off&lt;&#x2F;li&gt;
&lt;li&gt;touch sounds - off&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;system&lt;&#x2F;li&gt;
&lt;li&gt;advanced
&lt;ul&gt;
&lt;li&gt;gestures
&lt;ul&gt;
&lt;li&gt;power menu
&lt;ul&gt;
&lt;li&gt;advanced restart - on&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;lineage-microg-magisk-again-success&quot;&gt;Lineage+microG+Magisk again - success!&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s try downloading the latest and flashing again.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;download.lineage.microg.org&#x2F;lemonadep&#x2F;?sort=time&amp;amp;order=asc&quot;&gt;https:&#x2F;&#x2F;download.lineage.microg.org&#x2F;lemonadep&#x2F;?sort=time&amp;amp;order=asc&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ll lineage-18.1-2022040*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 192M Apr 30 20:38 lineage-18.1-20220401-microG-lemonadep-recovery.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 1.1G Apr 30 20:39 lineage-18.1-20220405-microG-lemonadep.zip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim 3.9K Apr 30 20:37 lineage-18.1-20220405-microG-lemonadep.zip.prop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-rw-r-- 1 tim tim  109 Apr 30 20:37 lineage-18.1-20220405-microG-lemonadep.zip.sha256sum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sha256sum -c lineage-18.1-20220405-microG-lemonadep.zip.sha256sum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lineage-18.1-20220405-microG-lemonadep.zip: OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cd update_verifier-master &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;update_verifier-master&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ python update_verifier.py lineageos4microg_pubkey ..&#x2F;lineage-18.1-20220405-microG-lemonadep.zip     &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;verified successfully&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We&#x27;ll do a swap slot again so that it won&#x27;t overwrite the currently working lineage install.&lt;&#x2F;p&gt;
&lt;p&gt;Vol-down + power button to enter recovery (from powered off).&lt;&#x2F;p&gt;
&lt;p&gt;Lineage recovery says &quot;Active slot: b&quot; at the top. Let&#x27;s boot it, check what we have, swap, boot again to see the other...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;slot b: broken install - drops to bootloader&lt;&#x2F;li&gt;
&lt;li&gt;slot a: also broken ...., erm I swear I booted that. wtf. phones.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;so that means I should swap slot so that &quot;a&quot; is active, so that fastboot flashes over the broken &quot;b&quot; and then swaps to it without touching the currently working &quot;a&quot; slot.&lt;&#x2F;p&gt;
&lt;p&gt;Use lineage bootloader to format the system just to see if that fixes the broken install. .... Nope. Both slots still fubar.&lt;&#x2F;p&gt;
&lt;p&gt;Right, well, flashing time either way.&lt;&#x2F;p&gt;
&lt;p&gt;put phone into recover &quot;update &amp;gt; apply from adb&quot; mode&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;adb sideload lineage-18.1-20220405-microG-lemonadep.zip&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;long pause...&lt;&#x2F;p&gt;
&lt;p&gt;back &amp;gt; reboot system&lt;&#x2F;p&gt;
&lt;p&gt;hurrah, a lineage boot animation&lt;&#x2F;p&gt;
&lt;p&gt;rattle through setup steps again, did wifi, nothing else&lt;&#x2F;p&gt;
&lt;p&gt;todo: fingerprint and pin&lt;&#x2F;p&gt;
&lt;p&gt;todo: re-root with magisk before doing anything else&lt;&#x2F;p&gt;
&lt;p&gt;new things compared to plain lineage: f-droid &amp;amp; microG apps&lt;&#x2F;p&gt;
&lt;p&gt;installed andOTP &amp;amp; vespucci (OSM editor) from f-droid&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;enable developer options (system &amp;gt; about phone, tap lots of times)&lt;&#x2F;p&gt;
&lt;p&gt;system &amp;gt; advanced &amp;gt; developer options &amp;gt; usb debugging ON  + Disable adb authorisation timeout (so that if my screen fails or the software misbehaves I can get my files over a usb cable)&lt;&#x2F;p&gt;
&lt;p&gt;Install Magisk by John Wu via F-Droid instead of adb this time&lt;&#x2F;p&gt;
&lt;p&gt;Extract the updated payload:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cd payload &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;payload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ..&#x2F;..&#x2F;payload-dumper-go&#x2F;payload-dumper-go_1.2.0_linux_amd64&#x2F;payload-dumper-go ..&#x2F;lineage-18.1-20220405-microG-lemonadep.zip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Please wait while extracting payload.bin from the archive.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;payload.bin: &#x2F;tmp&#x2F;payload_208101762.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Payload Version: 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Payload Manifest Length: 94295&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Payload Manifest Signature Length: 267&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found partitions:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;boot (201 MB), dtbo (25 MB), odm (2.9 MB), product (378 MB), system (1.1 GB), system_ext (234 MB), vbmeta (8.2 kB), vbmeta_system (4.1 kB), vendor (1.3 GB), vendor_boot (201 MB)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of workers: 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;odm (2.9 MB)            [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;boot (201 MB)           [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dtbo (25 MB)            [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;product (378 MB)        [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;system (1.1 GB)         [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;system_ext (234 MB)     [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vbmeta (8.2 kB)         [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vbmeta_system (4.1 kB)  [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vendor (1.3 GB)         [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vendor_boot (201 MB)    [==============================================================================================] 100 %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;payload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ll&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 4.0K&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 2 tim tim 4.0K Apr 30 21:34 extracted_20220430_213414&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;payload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ll extracted_20220430_213414 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 3.3G&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 192M Apr 30 21:34 boot.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim  24M Apr 30 21:34 dtbo.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 2.8M Apr 30 21:34 odm.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 361M Apr 30 21:34 product.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 224M Apr 30 21:34 system_ext.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 1.1G Apr 30 21:34 system.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 8.0K Apr 30 21:34 vbmeta.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 4.0K Apr 30 21:34 vbmeta_system.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 192M Apr 30 21:34 vendor_boot.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rwxr-xr-x 1 tim tim 1.3G Apr 30 21:35 vendor.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;send to phone:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;payload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb push extracted_20220430_213414&#x2F;boot.img &#x2F;sdcard&#x2F;Download&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;extracted_20220430_213414&#x2F;boot.img: 1 file pushed, 0 skipped. 192.7 MB&#x2F;s (201326592 bytes in 0.996s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;run the patch in the phone Magisk UI (under “install”)&lt;&#x2F;p&gt;
&lt;p&gt;get the patched file back:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;im@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;payload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ patched=`adb shell ls &#x2F;sdcard&#x2F;Download&#x2F;magisk_patched*`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;payload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ adb pull $patched&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;sdcard&#x2F;Download&#x2F;magisk_patched-24300_v4xhs.img: 1 file pulled, 0 skipped. 34.7 MB&#x2F;s (201326592 bytes in 5.532s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;turn on advanced reboot again in settings&lt;&#x2F;p&gt;
&lt;p&gt;reboot to fastboot&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;payload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ fastboot flash boot magisk_patched-24300_v4xhs.img &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sending &amp;#39;boot_a&amp;#39; (196608 KB)                       OKAY [  6.597s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Writing &amp;#39;boot_a&amp;#39;                                   OKAY [  0.611s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finished. Total time: 7.387s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&quot;reboot now&quot;&lt;&#x2F;p&gt;
&lt;p&gt;success. open up magisk, shows as installed (v24.3)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;f-droid-app-list&quot;&gt;F-Droid app list&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;turn-on-install-history&quot;&gt;Turn On Install history&lt;&#x2F;h3&gt;
&lt;p&gt;Before starting installations do this so that we (might) have an exportable record to share.&lt;&#x2F;p&gt;
&lt;p&gt;Turn on install history before starting so that we can export at the end - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;fdroid&#x2F;fdroidclient&#x2F;-&#x2F;issues&#x2F;70#note_89110104&quot;&gt;https:&#x2F;&#x2F;gitlab.com&#x2F;fdroid&#x2F;fdroidclient&#x2F;-&#x2F;issues&#x2F;70#note_89110104&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Settings &amp;gt; Expert mode &amp;gt; Keep install history&lt;&#x2F;p&gt;
&lt;h3 id=&quot;export-list-when-done&quot;&gt;Export list when done&lt;&#x2F;h3&gt;
&lt;p&gt;Settings &amp;gt; Install history and metrics &amp;gt; Share (share icon with 3 linked dots at top) &amp;gt; fail, no apps that know what to do with the file installed yet. gah.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;google-contacts-calendar-gmail-fail&quot;&gt;Google contacts, calendar &amp;amp; gmail - fail&lt;&#x2F;h3&gt;
&lt;p&gt;via aurora&lt;&#x2F;p&gt;
&lt;p&gt;Install contacts...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Sign in&lt;&#x2F;li&gt;
&lt;li&gt;Goes to microG&lt;&#x2F;li&gt;
&lt;li&gt;Then to official google sign in&lt;&#x2F;li&gt;
&lt;li&gt;Sign in succeeds&lt;&#x2F;li&gt;
&lt;li&gt;Acc now listed in settings &amp;gt; accounts&lt;&#x2F;li&gt;
&lt;li&gt;google contacts still shows no accounts &amp;amp; no contacts. Damn&lt;&#x2F;li&gt;
&lt;li&gt;tap acc, tap any of the settings (all go to same place) turn on &quot;Allow apps to find contacts&quot;&lt;&#x2F;li&gt;
&lt;li&gt;now google contacts shows the account, but still doesn&#x27;t sync.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Hrmm. Need this or equivalent obviously. Switching will be non trivial.&lt;&#x2F;p&gt;
&lt;p&gt;Same problem for gmail.&lt;&#x2F;p&gt;
&lt;p&gt;Calendar app works and has all events, desktop widget broken (shows no events)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;research&quot;&gt;Research&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;alternatives&quot;&gt;Alternatives&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;alternativeto.net&#x2F;software&#x2F;google-contacts&#x2F;&quot;&gt;https:&#x2F;&#x2F;alternativeto.net&#x2F;software&#x2F;google-contacts&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;7wnwpe&#x2F;alternative_to_google_calender_or_contacts_sync&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;7wnwpe&#x2F;alternative_to_google_calender_or_contacts_sync&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;8qv3p3&#x2F;alternative_services_to_google_calendar_and&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;8qv3p3&#x2F;alternative_services_to_google_calendar_and&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;pt5ce7&#x2F;are_the_contacts_and_telephone_apps_built_by&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;pt5ce7&#x2F;are_the_contacts_and_telephone_apps_built_by&#x2F;&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;en&#x2F;packages&#x2F;com.simplemobiletools.contacts.pro&#x2F;&quot;&gt;https:&#x2F;&#x2F;f-droid.org&#x2F;en&#x2F;packages&#x2F;com.simplemobiletools.contacts.pro&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;en&#x2F;packages&#x2F;com.simplemobiletools.contacts.pro&#x2F;&quot;&gt;https:&#x2F;&#x2F;f-droid.org&#x2F;en&#x2F;packages&#x2F;com.simplemobiletools.contacts.pro&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;making-it-work&quot;&gt;Making it work&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;microg&#x2F;GmsCore&#x2F;issues&#x2F;585&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;microg&#x2F;GmsCore&#x2F;issues&#x2F;585&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tomwiggers&#x2F;Magisk-ConCal-Sync-MicroG&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;tomwiggers&#x2F;Magisk-ConCal-Sync-MicroG&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tomwiggers&#x2F;Magisk-ConCal-Sync-MicroG&#x2F;archive&#x2F;refs&#x2F;heads&#x2F;master.zip&quot;&gt;download Magisk-ConCal-Sync-MicroG repo zip&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;extract, go into inner folder and zip up the four items&lt;&#x2F;li&gt;
&lt;li&gt;copy to phone with syncthing&lt;&#x2F;li&gt;
&lt;li&gt;magisk &amp;gt; modules &amp;gt; install from storage &amp;gt; select the zip &amp;gt; done&lt;&#x2F;li&gt;
&lt;li&gt;reboot phone&lt;&#x2F;li&gt;
&lt;li&gt;boot loop. FUUUUUUUUCK&lt;&#x2F;li&gt;
&lt;li&gt;reported issue for what it&#x27;s worth, including &lt;code&gt;logcat&lt;&#x2F;code&gt; logs: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tomwiggers&#x2F;Magisk-ConCal-Sync-MicroG&#x2F;issues&#x2F;3&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;tomwiggers&#x2F;Magisk-ConCal-Sync-MicroG&#x2F;issues&#x2F;3&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;remove modules
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.thecustomdroid.com&#x2F;uninstall-magisk-modules-in-twrp-recovery-guide&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.thecustomdroid.com&#x2F;uninstall-magisk-modules-in-twrp-recovery-guide&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;connect phone usb&lt;&#x2F;li&gt;
&lt;li&gt;run &lt;code&gt;adb wait-for-device shell magisk --remove-modules&lt;&#x2F;code&gt; on laptop&lt;&#x2F;li&gt;
&lt;li&gt;boot up phone normally&lt;&#x2F;li&gt;
&lt;li&gt;phone booted into lock screen, phew!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;calendar&quot;&gt;Calendar&lt;&#x2F;h4&gt;
&lt;p&gt;bearable, widget broken but app itself works and syncs&lt;&#x2F;p&gt;
&lt;p&gt;have to manually turn on sync for additional calendars&lt;&#x2F;p&gt;
&lt;h4 id=&quot;contacts&quot;&gt;Contacts&lt;&#x2F;h4&gt;
&lt;p&gt;Need alternative, perhaps fastmail&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Let&#x27;s try fastmail&#x27;s contacts...
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;contacts.google.com&#x2F;&quot;&gt;google contacts web app&lt;&#x2F;a&gt; &amp;gt; export from google contacts &amp;gt; vCard&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.fastmail.com&#x2F;settings&#x2F;setup&#x2F;importexport&quot;&gt;fastmail web app &amp;gt; dropdown thing &amp;gt; settings&lt;&#x2F;a&gt; &amp;gt; import &amp;gt; contacts &amp;gt; upload addressbook file &amp;gt; choose the vcf
&lt;ul&gt;
&lt;li&gt;imported all but two, showed me the errors, not ones I care about.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;check fastmail phone app, contacts come flooding in.&lt;&#x2F;li&gt;
&lt;li&gt;but no sign of them in the main phone contacts app. damn.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;fastmail&#x2F;comments&#x2F;f2akqj&#x2F;dealing_with_contacts&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;fastmail&#x2F;comments&#x2F;f2akqj&#x2F;dealing_with_contacts&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I&#x27;ve messaged fastmail support to ask them why they have a completely separate contact section in the fastmail app rather than using the shared contacts store in Android&#x2F;LineageOS.&lt;&#x2F;p&gt;
&lt;p&gt;Because I&#x27;m short of good options I will reluctantly try the DAVx app that everyone points to. I really don&#x27;t want yet another sync involved in the whole thing but I also don&#x27;t want to run and maintain a NextCloud install (which lots of people suggest).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Installing DAVx5
&lt;ul&gt;
&lt;li&gt;It&#x27;s listed in Aurora (the play store proxy) and shows &quot;£4.29&quot; instead of the usual &quot;Install&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Pressed money button to see what happens &amp;gt; error &quot;Download failed, app not purchased&quot;. Cool.&lt;&#x2F;li&gt;
&lt;li&gt;Go to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;apps&#x2F;details?id=at.bitfire.davdroid&quot;&gt;DAVx5 on play store&lt;&#x2F;a&gt; and make the purchase
&lt;ul&gt;
&lt;li&gt;concerningly for the future the play store pops an &quot;install to blah device&quot;, which is fine now because it knows about my &lt;em&gt;old&lt;&#x2F;em&gt; phone, but what if I didn&#x27;t have the old phone some time, does that mean I could no longer get paid apps and install them with Aurora?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Back on the new phone Aurora install now works. Win.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Setting up DAVx5
&lt;ul&gt;
&lt;li&gt;rattled through default wizard without changing (or understanding) anything&lt;&#x2F;li&gt;
&lt;li&gt;interesting warning about oneplus blocking sync that points to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.davx5.com&#x2F;faq&#x2F;synchronization-is-not-run-as-expected&quot;&gt;https:&#x2F;&#x2F;www.davx5.com&#x2F;faq&#x2F;synchronization-is-not-run-as-expected&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Create app password in fastmail web interface for DAVx&lt;&#x2F;li&gt;
&lt;li&gt;Login to DAVx app with email + app-password ... fail, presumably because it&#x27;s a custom domain&lt;&#x2F;li&gt;
&lt;li&gt;Use custom base url option - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.davx5.com&#x2F;tested-with&#x2F;fastmail&quot;&gt;https:&#x2F;&#x2F;www.davx5.com&#x2F;tested-with&#x2F;fastmail&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Base url: &lt;code&gt;https:&#x2F;&#x2F;carddav.fastmail.com&lt;&#x2F;code&gt; + email + app-password .... success&lt;&#x2F;li&gt;
&lt;li&gt;Create account: account name? (defaults to tim@timwise.co.uk) - &quot;Use your email address as account name because Android will use the account name as ORGANIZER field for events you create. You can&#x27;t have two accounts with the same name.&quot; - probably fine, left default&lt;&#x2F;li&gt;
&lt;li&gt;Contact group method:
&lt;ul&gt;
&lt;li&gt;&quot;Groups are separate vCards&quot; - default, left as this&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Groups are per-contact categories&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Next&lt;&#x2F;li&gt;
&lt;li&gt;No contacts sync (missing permissions) &amp;gt; Permissions &amp;gt; All of the below to &quot;on&quot; &amp;gt; grant dialogs&lt;&#x2F;li&gt;
&lt;li&gt;Shows two unchecked checkboxes, but don&#x27;t know what they mean
&lt;ul&gt;
&lt;li&gt;&quot;Global Address Book&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;personal&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Trying out ticking &quot;personal&quot;, tick it and press orange sync now button&lt;&#x2F;li&gt;
&lt;li&gt;woo, main contacts app now full of contacts. sim switch time!!!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;gmail&quot;&gt;GMail&lt;&#x2F;h4&gt;
&lt;p&gt;todo, probably set up imap and use k9mail + web interface on laptop&lt;&#x2F;p&gt;
&lt;h3 id=&quot;f-droid-app-list-1&quot;&gt;F-Droid app list&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Vespucci (open-streetmap (OSM) editor)&lt;&#x2F;li&gt;
&lt;li&gt;andOTP (one time password generator with backup&#x2F;restore capability)&lt;&#x2F;li&gt;
&lt;li&gt;Aurora play store proxy - configure as per above section&lt;&#x2F;li&gt;
&lt;li&gt;Syncthing&lt;&#x2F;li&gt;
&lt;li&gt;OAndBackupX - to replace proprietary (but very good) titanium backup
&lt;ul&gt;
&lt;li&gt;Needs root, provided by Magisk. Without root no apps can access the data of other apps. This is the primary reason that root is so important to me. I want a backup system that I can actually trust because it&#x27;s not some proprietary cloud magic pixie dust, it&#x27;s instead a straight-forward grab-the-files-and-put-them-somewhere-safe operation that I can inspect and get to without more proprietary black magic.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.keepassdx.com&#x2F;&quot;&gt;KeepassDX&lt;&#x2F;a&gt; - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Kunzisoft&#x2F;KeePassDX&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Kunzisoft&#x2F;KeePassDX&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;k9mail&lt;&#x2F;li&gt;
&lt;li&gt;vlc&lt;&#x2F;li&gt;
&lt;li&gt;markor&lt;&#x2F;li&gt;
&lt;li&gt;antennapod - todo restore state&lt;&#x2F;li&gt;
&lt;li&gt;qr &amp;amp; barcode scanner&lt;&#x2F;li&gt;
&lt;li&gt;aTimeLogger&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;en&#x2F;packages&#x2F;org.billthefarmer.editor&#x2F;&quot;&gt;Editor&lt;&#x2F;a&gt; (replacement for droidedit?)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;en&#x2F;packages&#x2F;com.mendhak.gpslogger&#x2F;&quot;&gt;GPSLogger&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;todo-more-apps-f-droid-where-possible&quot;&gt;todo - more apps (f-droid where possible)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;VLC&lt;&#x2F;li&gt;
&lt;li&gt;AntennaPod&lt;&#x2F;li&gt;
&lt;li&gt;Audible&lt;&#x2F;li&gt;
&lt;li&gt;Maverick (for recording and viewing gps traces, could do with a replacement, the map tiles seem to have died and it&#x27;s getting buggy)&lt;&#x2F;li&gt;
&lt;li&gt;google home (for chromecast &amp;amp; google mini integration)&lt;&#x2F;li&gt;
&lt;li&gt;RainAlarm (paid for ad-free)&lt;&#x2F;li&gt;
&lt;li&gt;Google calendar (or find a non-google replacement)&lt;&#x2F;li&gt;
&lt;li&gt;Google contacts (or find a non-google replacement)&lt;&#x2F;li&gt;
&lt;li&gt;Waze&lt;&#x2F;li&gt;
&lt;li&gt;Google maps (for satnav, route planning and finding local businesses)&lt;&#x2F;li&gt;
&lt;li&gt;LinkedIn&lt;&#x2F;li&gt;
&lt;li&gt;Twitter&lt;&#x2F;li&gt;
&lt;li&gt;Telegram FOSS (a slightly free-er version of telegram)&lt;&#x2F;li&gt;
&lt;li&gt;...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;other-f-droid-app-suggestions&quot;&gt;Other f-droid app suggestions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;fdroid&#x2F;comments&#x2F;lzzdbg&#x2F;a_list_of_some_fdroid_apps_i_installed_to_get_you&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;fdroid&#x2F;comments&#x2F;lzzdbg&#x2F;a_list_of_some_fdroid_apps_i_installed_to_get_you&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;play-store-app-list-via-aurora&quot;&gt;Play store app list (via Aurora)&lt;&#x2F;h2&gt;
&lt;p&gt;Only things not available in f-droid&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;maps.me&lt;&#x2F;li&gt;
&lt;li&gt;Spotify&lt;&#x2F;li&gt;
&lt;li&gt;Audible&lt;&#x2F;li&gt;
&lt;li&gt;Firefox&lt;&#x2F;li&gt;
&lt;li&gt;google maps - works flawlessly!&lt;&#x2F;li&gt;
&lt;li&gt;signal messemger
&lt;ul&gt;
&lt;li&gt;surprisingly not in f-droid!&lt;&#x2F;li&gt;
&lt;li&gt;can&#x27;t be on multiple phones at once, can only &quot;transfer&quot;. Grumble.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;banking apps (2&#x2F;3 work)&lt;&#x2F;li&gt;
&lt;li&gt;sunsama&lt;&#x2F;li&gt;
&lt;li&gt;trello&lt;&#x2F;li&gt;
&lt;li&gt;slack&lt;&#x2F;li&gt;
&lt;li&gt;rain alarm - todo restore paid version&lt;&#x2F;li&gt;
&lt;li&gt;zoom&lt;&#x2F;li&gt;
&lt;li&gt;bulb energy&lt;&#x2F;li&gt;
&lt;li&gt;YNAB&lt;&#x2F;li&gt;
&lt;li&gt;Ring (doorbell)&lt;&#x2F;li&gt;
&lt;li&gt;Google home&lt;&#x2F;li&gt;
&lt;li&gt;Life360 (shared gps locations for family, saves a bunch of &quot;have you left yet?&quot; text messages)&lt;&#x2F;li&gt;
&lt;li&gt;Fastmail - not for the mail, prefer k9mail, but to see if it can do contacts as well as goooooooogle&lt;&#x2F;li&gt;
&lt;li&gt;DroidEdit&lt;&#x2F;li&gt;
&lt;li&gt;Ringo&lt;&#x2F;li&gt;
&lt;li&gt;National rail&lt;&#x2F;li&gt;
&lt;li&gt;Goodreads&lt;&#x2F;li&gt;
&lt;li&gt;Pluralsight&lt;&#x2F;li&gt;
&lt;li&gt;LinkedIn&lt;&#x2F;li&gt;
&lt;li&gt;FreeAgent&lt;&#x2F;li&gt;
&lt;li&gt;BBC
&lt;ul&gt;
&lt;li&gt;Weather&lt;&#x2F;li&gt;
&lt;li&gt;Sounds&lt;&#x2F;li&gt;
&lt;li&gt;iPlayer&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Amazon Shopping&lt;&#x2F;li&gt;
&lt;li&gt;Amazon Prime&lt;&#x2F;li&gt;
&lt;li&gt;YouTube&lt;&#x2F;li&gt;
&lt;li&gt;Microsoft authenticator&lt;&#x2F;li&gt;
&lt;li&gt;Google authenticator&lt;&#x2F;li&gt;
&lt;li&gt;Bandcamp&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;apps&#x2F;details?id=livio.pack.lang.en_US&quot;&gt;Offline English Dictionary by Livio&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Strava&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;built-in-apps&quot;&gt;Built-in apps&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;camera-configure&quot;&gt;Camera - configure&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Hamburger
&lt;ul&gt;
&lt;li&gt;GPS &amp;gt; on&lt;&#x2F;li&gt;
&lt;li&gt;Touch focus duration &amp;gt; infinite (man that has always annoyed me! Default 3 seconds, why?!)&lt;&#x2F;li&gt;
&lt;li&gt;shutter sound &amp;gt; disabled&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;browser-disable&quot;&gt;Browser - disable&lt;&#x2F;h3&gt;
&lt;p&gt;Disable (using firefox instead)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;messaging-disable&quot;&gt;Messaging - disable&lt;&#x2F;h3&gt;
&lt;p&gt;Messaging &amp;gt; long press &amp;gt; app info &amp;gt; disable&lt;&#x2F;p&gt;
&lt;h2 id=&quot;individual-app-setup&quot;&gt;Individual app setup&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;syncthing&quot;&gt;Syncthing&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Open web gui&lt;&#x2F;li&gt;
&lt;li&gt;Disable all non-LAN&lt;&#x2F;li&gt;
&lt;li&gt;Remove default folder (Camera)&lt;&#x2F;li&gt;
&lt;li&gt;Set device name&lt;&#x2F;li&gt;
&lt;li&gt;Connect to existing machine(s).&lt;&#x2F;li&gt;
&lt;li&gt;Add &lt;code&gt;&#x2F;storage&#x2F;emulated&#x2F;0&lt;&#x2F;code&gt; folder (can&#x27;t do this in non-web gui, stupid security warning. Nanny state of android.)
&lt;ul&gt;
&lt;li&gt;Warnings about failure to sync &lt;code&gt;Android&#x2F;data&lt;&#x2F;code&gt; and &lt;code&gt;Android&#x2F;obb&lt;&#x2F;code&gt;. Looks like they&#x27;ve tightened up security more, either that or syncthing has better warnings now. These folders will be exposed by OAndBackupX so I can safely ignore this until I sort out the ignore file for syncthing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Oh no, syncthing can no longer access &lt;code&gt;&#x2F;storage&#x2F;emulated&#x2F;0&#x2F;Android&#x2F;data&lt;&#x2F;code&gt; - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.syncthing.net&#x2F;t&#x2F;can-i-sync-send-only-data-from-android-data-in-android-11&#x2F;17898&quot;&gt;https:&#x2F;&#x2F;forum.syncthing.net&#x2F;t&#x2F;can-i-sync-send-only-data-from-android-data-in-android-11&#x2F;17898&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Even more reason to have root and run a real and independent backup tool.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;syncthing-ignore-patterns&quot;&gt;Syncthing ignore patterns&lt;&#x2F;h4&gt;
&lt;p&gt;Set up ignores for caches and things that won&#x27;t sync. Files for this are on github at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;tree&#x2F;master&#x2F;phone&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;tree&#x2F;master&#x2F;phone&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Create file &lt;code&gt;phone.stignore&lt;&#x2F;code&gt; in the root of the sync&#x27;d sdcard folder. This one you can edit on the laptop as you find more things you don&#x27;t want sync&#x27;d.&lt;&#x2F;li&gt;
&lt;li&gt;Create file &lt;code&gt;phonetemplate.stignore&lt;&#x2F;code&gt; in the root folder and put only this line in it &lt;code&gt;#include phone.stignore&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;On the phone when they have sync&#x27;d copy the &lt;code&gt;phonetemplate.stignore&lt;&#x2F;code&gt; to a file named just &lt;code&gt;.stignore&lt;&#x2F;code&gt; in the root folder.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The reason for this dance is that syncthing won&#x27;t sync the &lt;code&gt;.stignore&lt;&#x2F;code&gt; so to be able to edit the ignores on a different device you have to set up a link.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;andotp&quot;&gt;AndOTP&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Set up password&lt;&#x2F;li&gt;
&lt;li&gt;Turn off global timeout bar (distracting &amp;amp; stressful)&lt;&#x2F;li&gt;
&lt;li&gt;Icons: small&lt;&#x2F;li&gt;
&lt;li&gt;Layout: compact&lt;&#x2F;li&gt;
&lt;li&gt;Copy backup from old phone with syncthing and restore it&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;antennapod&quot;&gt;AntennaPod&lt;&#x2F;h3&gt;
&lt;p&gt;Now I get to the crux of why I was so fucked off with Android.&lt;&#x2F;p&gt;
&lt;p&gt;I want to copy the &lt;em&gt;exact&lt;&#x2F;em&gt; state of antennapod to the new phone; but my old phone de-rooted itself and broke the backups; and you can&#x27;t back up ~&#x2F;data where everything lives without root because it&#x27;s all locked down with per-app-user permissions, which is great for isolating apps from each other ... and you. The only option for those folders is in app sync (e.g.. sign in to trello&#x2F;firefox&#x2F;slack etc) so local state is throwaway, or backup to google drive .... to some magical fucking invisible folder so you can&#x27;t even download the backups it made. This shit makes me so mad.&lt;&#x2F;p&gt;
&lt;p&gt;We already have working systems for backups and security and these fuckers have broken them and replaced them with their own vendor-locked-in proprietary black-box shite that doesn&#x27;t even work all the time.&lt;&#x2F;p&gt;
&lt;p&gt;Because I&#x27;d lost root and usable backups it took me a while to work out how to transfer my latest beloved podcast player state to a new phone. I knew that you could import&#x2F;export an OPML list of suscriptions but I really wanted to keep the play state of every episode so I caould easily scan the back-catalogues for episodes I&#x27;d never listened to dotted amongst the many thousands of episodes I have listned to. Well darm it there is a full export feature I didn&#x27;t know about. It exports to the virtual sdcard storagea which is kinda like a home directory that you can actually access as a user. I already have the sdcard storage syncing to my other machines with syncthing so getting it from there onwards is a trivial copy-paste on the laptop.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what a quick &lt;del&gt;google&lt;&#x2F;del&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duckduckgo.com&#x2F;&quot;&gt;ddg&lt;&#x2F;a&gt; showed up:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AntennaPod&#x2F;AntennaPod&#x2F;issues&#x2F;5391&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;AntennaPod&#x2F;AntennaPod&#x2F;issues&#x2F;5391&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AntennaPod&#x2F;AntennaPod&#x2F;issues&#x2F;5031&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;AntennaPod&#x2F;AntennaPod&#x2F;issues&#x2F;5031&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AntennaPod&#x2F;AntennaPod&#x2F;issues&#x2F;377&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;AntennaPod&#x2F;AntennaPod&#x2F;issues&#x2F;377&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Old phone:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;hamburger menu top left&lt;&#x2F;li&gt;
&lt;li&gt;settings (cog at bottom) &amp;gt; storage &amp;gt; import&#x2F;export &amp;gt; database export&lt;&#x2F;li&gt;
&lt;li&gt;ensure syncthing is running and connected&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Laptop:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Copy file on laptop to new phone&#x27;s sync folder&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;New phone:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;make sure symcthing is running, connected and up to date to pull new file in&lt;&#x2F;li&gt;
&lt;li&gt;hamburger menu top left&lt;&#x2F;li&gt;
&lt;li&gt;settings (cog at bottom) &amp;gt; storage &amp;gt; import&#x2F;export &amp;gt; database import &amp;gt; Confirm&lt;&#x2F;li&gt;
&lt;li&gt;select file&lt;&#x2F;li&gt;
&lt;li&gt;press ok to restart Antennapod&lt;&#x2F;li&gt;
&lt;li&gt;Woo! Queue entirely intact!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Downloads have to be re-done for the queue but the UI makes that dead easy, just hit play and it switches to a download button so you can whip through them quick.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bulb-energy&quot;&gt;Bulb energy&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;App downloaded&lt;&#x2F;li&gt;
&lt;li&gt;Sign in by magic email link failed&lt;&#x2F;li&gt;
&lt;li&gt;Sign in with password worked&lt;&#x2F;li&gt;
&lt;li&gt;Statement download failed with &quot;no apps can perform this action&quot; but can always use website to get them. ... ah, no pdf reading apps installed, installing a random pdf app fixed that. Not a very clear error message that one!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;keepassdx&quot;&gt;KeePassDX&lt;&#x2F;h3&gt;
&lt;p&gt;Enable fingerprint unlock &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Kunzisoft&#x2F;KeePassDX&#x2F;wiki&#x2F;Advanced-Unlocking#b-link-database-credential-to-advanced-unlock-recognition=&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Kunzisoft&#x2F;KeePassDX&#x2F;wiki&#x2F;Advanced-Unlocking#b-link-database-credential-to-advanced-unlock-recognition=&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;neobackup&quot;&gt;NeoBackup&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Backup folder &amp;gt; neo-backup folder on emulated sdcard home &amp;gt; use this folder&lt;&#x2F;li&gt;
&lt;li&gt;Allow access prompt &amp;gt; allow&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&quot;i&quot; button top right &amp;gt; interesting note about types of android data and inability to restore apps using hardware key stores such as signal&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;work out what apps to back up -- all of them, why guess what I&#x27;ll need with so much storage available&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;actual backups - done&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;schedule backups - done, works great&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;maybe automate clearing off phone onto laptop&#x2F;server&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Set backup password&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Set scheduled backup:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;7 days&lt;&#x2F;li&gt;
&lt;li&gt;5am&lt;&#x2F;li&gt;
&lt;li&gt;system apps + user apps&lt;&#x2F;li&gt;
&lt;li&gt;apk + obb + data + device protected data&lt;&#x2F;li&gt;
&lt;li&gt;all apps&lt;&#x2F;li&gt;
&lt;li&gt;enabled&lt;&#x2F;li&gt;
&lt;li&gt;Start now&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;firefox&quot;&gt;Firefox&lt;&#x2F;h3&gt;
&lt;p&gt;3dots &amp;gt; settings &amp;gt; Search &amp;gt; duckduckgo&lt;&#x2F;p&gt;
&lt;p&gt;firefox was active for 6 hours which makes me think it isn&#x27;t backgrounding properly, perhaps because of media or js on websites.&lt;&#x2F;p&gt;
&lt;p&gt;Firefox icon &amp;gt; long press &amp;gt; App info (i) &amp;gt; Advanced &amp;gt; Battery &amp;gt; Background restriction &amp;gt; Restrict&lt;&#x2F;p&gt;
&lt;h3 id=&quot;signal&quot;&gt;Signal&lt;&#x2F;h3&gt;
&lt;p&gt;Use transfer account to new phone feature
Enable chat backups to virtual SD: dots &amp;gt; settings &amp;gt; chat. &amp;gt; Chat backups. Set folder and create backup.&lt;&#x2F;p&gt;
&lt;p&gt;Signal popup saying detected issue with play services and establishing own connection. Now have permanent notification.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gpslogger&quot;&gt;GPSLogger&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;en&#x2F;packages&#x2F;com.mendhak.gpslogger&#x2F;&quot;&gt;https:&#x2F;&#x2F;f-droid.org&#x2F;en&#x2F;packages&#x2F;com.mendhak.gpslogger&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;hamburger
&lt;ul&gt;
&lt;li&gt;logging details
&lt;ul&gt;
&lt;li&gt;save to folder &amp;gt; give permissions &amp;gt; new folder (+) &amp;gt; &lt;code&gt;~&#x2F;gpx&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;New file creation &amp;gt; every time I start&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;performance
&lt;ul&gt;
&lt;li&gt;Logging interval &amp;gt; 5 secs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So that syncthing can see it. Defaults to inaccessible data folder. Fffffff&lt;&#x2F;p&gt;
&lt;p&gt;Also set to create new track every time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-thought-on-moving-apps-and-data-between-phones&quot;&gt;A thought on moving apps and data between phones&lt;&#x2F;h2&gt;
&lt;p&gt;During the 1000th discussion of phones with my long-sufferring better-half I happened to utter a line that I think realy captures why this whole nonsense is (probably) worth the effort:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Living in the iOS ecosystem with their magical one-tap transfer from old phones to new phones that leave the new phone exactly in the same state as your old phone ... until you realize one day you want to leave the ecosystem, and you have to leave all your data behind in their walled garden.&quot; ~ Me&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;There are several ways of moving data between phones, which provide varying levels of protection against data loss disasters. Disasters that could be local (phone down loo), localized (all devices stolen from house), cloud based (cloud account hacked and wiped), a combination (cloud hacked and devices remote-wiped).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;copying-files-directly&quot;&gt;Copying files directly&lt;&#x2F;h3&gt;
&lt;p&gt;Something like syncthing.&lt;&#x2F;p&gt;
&lt;p&gt;Only works for data on virtual sdcard such as photos &amp;amp; downloads.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;local-backup-restore&quot;&gt;Local backup&#x2F;restore&lt;&#x2F;h3&gt;
&lt;p&gt;With OAndBackup, NeoBackup, TitaniumBackup etc.&lt;&#x2F;p&gt;
&lt;p&gt;Needs root.&lt;&#x2F;p&gt;
&lt;p&gt;Can get app&#x27;s private data out to storage you control.&lt;&#x2F;p&gt;
&lt;p&gt;Can also backup set of installed apps (&lt;code&gt;.apk&lt;&#x2F;code&gt;s) which it turns out is actually quite a time saver compared to clicking install in the app store 100+ times.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vendor-provided-cloud-backup&quot;&gt;Vendor-provided cloud backup&lt;&#x2F;h3&gt;
&lt;p&gt;Completely walled-garden solution. No way to get your data off their cloud without restoring to another device they support (i.e. another Android&#x2F;iOS device).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3rd-party-cloud-backup&quot;&gt;3rd party cloud backup&lt;&#x2F;h3&gt;
&lt;p&gt;Something like dropbox.&lt;&#x2F;p&gt;
&lt;p&gt;It seems that the duopoly has deemed this unacceptable so have hobbled these apps fom working properly or at all. Dropbox on iOS has been reduced to a glorified photo backup which can&#x27;t even run in the background.&lt;&#x2F;p&gt;
&lt;p&gt;Personally I think the fact that the duopoly is denying competition is anti-competitive practice the likes of which saw Microsoft get record fines from the EU back in the day. Hopefully the same will happen to Apple &amp;amp; Google to crack this open a bit, but until then we&#x27;ll have to just shovel digital shit like this blog post to get out from under them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;file-transfer&quot;&gt;File transfer&lt;&#x2F;h2&gt;
&lt;p&gt;Easy thanks to syncthing, just move the folders &amp;amp; files on the laptop from sync sdcard folder of the old phone to the one for the new phone. Win.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trial-titaniumbackup-restore-success&quot;&gt;Trial TitaniumBackup restore - success&lt;&#x2F;h2&gt;
&lt;p&gt;Before my old phone de-rooted itself thanks to a F****g OS update (grrrrr) I did have titanium set up, so I have somem rather stale backups from before then. Mostly as an experiment I&#x27;ve installed Titanium on the new phone to see if the restore works. This is the first time I&#x27;ve had two capable and still working phones at the same time to be able to experiment like this.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Installed TitaniumBackup via Aurora.&lt;&#x2F;li&gt;
&lt;li&gt;Installed Titanium&#x27;s &quot;key&quot; app via Aurora.&lt;&#x2F;li&gt;
&lt;li&gt;Titanium complained that Play store wasn&#x27;t responding so couldn&#x27;t check licence key. Fucksake. More lockin.&lt;&#x2F;li&gt;
&lt;li&gt;Removed key app again.&lt;&#x2F;li&gt;
&lt;li&gt;Copied one of the old backups across (google authenticator). (An app I had not yet installed on the new phone)&lt;&#x2F;li&gt;
&lt;li&gt;Fired up titanium, hit restore for that app.&lt;&#x2F;li&gt;
&lt;li&gt;Boom! There&#x27;s the app installed, fired it up, worked no problems and now have an (outdated) list of OTPs that I don&#x27;t use any more. Hollow victory achieved.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;clock&quot;&gt;Clock&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Settings
&lt;ul&gt;
&lt;li&gt;Time in seconds &amp;gt; on&lt;&#x2F;li&gt;
&lt;li&gt;Alarms
&lt;ul&gt;
&lt;li&gt;silence after &amp;gt; 5 mins&lt;&#x2F;li&gt;
&lt;li&gt;Snooze length &amp;gt; 15 minutes - I find that if I&#x27;m really too tired to move 15 mins makes a good power nap but isn&#x27;t long enough to be disastrous&lt;&#x2F;li&gt;
&lt;li&gt;gradually increase&lt;&#x2F;li&gt;
&lt;li&gt;vol button to snooze&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;config-2&quot;&gt;Config&lt;&#x2F;h2&gt;
&lt;p&gt;A complete list&lt;&#x2F;p&gt;
&lt;p&gt;Settings:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Network and Internet
&lt;ul&gt;
&lt;li&gt;Hotspot and Tethering
&lt;ul&gt;
&lt;li&gt;Wi-Fi Hotspot
&lt;ul&gt;
&lt;li&gt;On&lt;&#x2F;li&gt;
&lt;li&gt;AP Band
&lt;ul&gt;
&lt;li&gt;5 GHz band preferred&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Bluetooth tethering &amp;gt; On (to give the laptop internet out and about)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Connected Devices
&lt;ul&gt;
&lt;li&gt;Connection preferences
&lt;ul&gt;
&lt;li&gt;Bluetooth
&lt;ul&gt;
&lt;li&gt;Device name: foo&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Wifi
&lt;ul&gt;
&lt;li&gt;Wifi preferences
&lt;ul&gt;
&lt;li&gt;Notify for public networks &amp;gt; off&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Apps and Notifications
&lt;ul&gt;
&lt;li&gt;Default apps
&lt;ul&gt;
&lt;li&gt;SMS app &amp;gt; Signal (actually a great integrated SMS app)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Notifications
&lt;ul&gt;
&lt;li&gt;Advanced
&lt;ul&gt;
&lt;li&gt;Do Not Disturb
&lt;ul&gt;
&lt;li&gt;People
&lt;ul&gt;
&lt;li&gt;Calls &amp;gt; &quot;Contacts and repeat callers&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Battery
&lt;ul&gt;
&lt;li&gt;Battery saver and performance
&lt;ul&gt;
&lt;li&gt;Automatic power saver - 15% (off by default oddly)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Display
&lt;ul&gt;
&lt;li&gt;Dark theme
&lt;ul&gt;
&lt;li&gt;on&lt;&#x2F;li&gt;
&lt;li&gt;no schedule - (let&#x27;s give this a try, we&#x27;ll see what it&#x27;s like in broad daylight)&lt;&#x2F;li&gt;
&lt;li&gt;pure black - on (better for battery and I think it looks cooler)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Night Light
&lt;ul&gt;
&lt;li&gt;Schedule&lt;&#x2F;li&gt;
&lt;li&gt;sunset till sunrise - this is an experiment, we&#x27;ll see if it is sensible at it&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Advanced (because this is extreem l33t haxxor stuff, beware n00bs)
&lt;ul&gt;
&lt;li&gt;Screen timeout - 5 mins (scary stuff I know, you were warned by the &lt;strong&gt;advanced&lt;&#x2F;strong&gt; thing, I hope you know what you&#x27;re doing. The nanny phone-state will keep you safe, don&#x27;t you worry your pretty little head about this section. Twunts.)&lt;&#x2F;li&gt;
&lt;li&gt;Styles and wallpapers - yes you read that right folks, wallpapers are an &quot;Advanced&quot; feature. What is wrong with this people?&lt;&#x2F;li&gt;
&lt;li&gt;push a couple of images across to ~&#x2F;Pictures with syncthing and set them as home &amp;amp; lock screen&lt;&#x2F;li&gt;
&lt;li&gt;Lock screen&lt;&#x2F;li&gt;
&lt;li&gt;Add text on lock screen
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Owner Tim Abell &amp;lt;tim@timwise.co.uk&amp;gt;&lt;&#x2F;code&gt; (the idea is that people are generally good and this might be the best way to reach me if I&#x27;ve lost it)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Tap to sleep - off (I only ever do this by mistake)&lt;&#x2F;li&gt;
&lt;li&gt;Font size &amp;gt; Largest (I&#x27;m gettingn quite long-sighted)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Sound&lt;&#x2F;li&gt;
&lt;li&gt;Vibrate for calls - Always (also has a vibrate then ring which is a nice option)&lt;&#x2F;li&gt;
&lt;li&gt;Advanced (why??????)
&lt;ul&gt;
&lt;li&gt;Phone ringtone - thriller three (there&#x27;s a great selection &amp;amp; variety available, impressed with Lineage here. Also liked Solarium, Sheep (yes actual sheep), Rigel)&lt;&#x2F;li&gt;
&lt;li&gt;Default notification sound - Hojus (also liked Beryllium and Titan for minimal stress-inducing feel. Again a great selection available with some really fun sounds).&lt;&#x2F;li&gt;
&lt;li&gt;Default alarm sound - Piezo Alarm (for the retro kicks. Again more winners in here, well worth exploring)&lt;&#x2F;li&gt;
&lt;li&gt;Dial pad tones - off&lt;&#x2F;li&gt;
&lt;li&gt;Screen locking sound - off&lt;&#x2F;li&gt;
&lt;li&gt;Touch sounds - off&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Privacy&lt;&#x2F;li&gt;
&lt;li&gt;Show passwords, display characters briefly as you type - off (I just find this annoying&#x2F;distracting)&lt;&#x2F;li&gt;
&lt;li&gt;Notifications on lock screen
&lt;ul&gt;
&lt;li&gt;Don&#x27;t show notifications at all - this is more for a clear mind rather than privacy, though that&#x27;s a bonus. I hate looking at my (locked) phone for the time and getting drawn into the notifications. Happened toooooo many times.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Trust
&lt;ul&gt;
&lt;li&gt;SMS message limit - always confirm (default of 30 seems like a lot of spam to me), might go to 5 if this is a pain&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Security&lt;&#x2F;li&gt;
&lt;li&gt;Screen lock - pin&lt;&#x2F;li&gt;
&lt;li&gt;Fingerprint&lt;&#x2F;li&gt;
&lt;li&gt;System
&lt;ul&gt;
&lt;li&gt;Buttons
&lt;ul&gt;
&lt;li&gt;Additional buttons
&lt;ul&gt;
&lt;li&gt;Slider top - total silence&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Status bar
&lt;ul&gt;
&lt;li&gt;Network traffic monitor&lt;&#x2F;li&gt;
&lt;li&gt;Display mode &amp;gt; upload and download&lt;&#x2F;li&gt;
&lt;li&gt;Battery status style - Circle (much higher fidelity information)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Advanced
&lt;ul&gt;
&lt;li&gt;Gestures&lt;&#x2F;li&gt;
&lt;li&gt;Power menu
&lt;ul&gt;
&lt;li&gt;Advanced restart - on&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Developer options
&lt;ul&gt;
&lt;li&gt;Automatic system updates &amp;gt; off (&quot;Apply updates when device restarts)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;About phone&lt;&#x2F;li&gt;
&lt;li&gt;Emergency information (wtf is this in about phone for? I had to ddg to find it)
&lt;ul&gt;
&lt;li&gt;Add information&lt;&#x2F;li&gt;
&lt;li&gt;set all the things&lt;&#x2F;li&gt;
&lt;li&gt;Add contact&lt;&#x2F;li&gt;
&lt;li&gt;doesn&#x27;t work, just shows empty list to choose from. dang. TODO&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;legacy-phone-connectivity&quot;&gt;Legacy phone connectivity&lt;&#x2F;h3&gt;
&lt;p&gt;The old phone has Wifi at home but without a sim has no internet out and about. Tether to new phone to give it access to internet elsewhere as needed.&lt;&#x2F;p&gt;
&lt;p&gt;Connected to WiFi hotspot but although it accepted the details it fails to actually connect.&lt;&#x2F;p&gt;
&lt;p&gt;Pair to other phone with bluetooth (either end is fine). On old phone open bluetooth settings, go to device &amp;gt; configure (cog) &amp;gt; Internet access &amp;gt; On.&lt;&#x2F;p&gt;
&lt;p&gt;Success, old phone has internet via bluetooth to new phone just like laptop. Win.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;todo-1&quot;&gt;Todo&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;firmware update: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;fw_update&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;fw_update&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Backup&#x2F;restore with titanium&lt;&#x2F;li&gt;
&lt;li&gt;better camera support? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;google-camera-port-hub&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.xda-developers.com&#x2F;google-camera-port-hub&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;see if android pay etc will work with magisk magic mask pretending we haven&#x27;t unlocked anything&lt;&#x2F;li&gt;
&lt;li&gt;find an alternative to titanium backup &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;farewell-to-titanium-backup-looking-for-alternative.3932814&#x2F;&quot;&gt;https:&#x2F;&#x2F;forum.xda-developers.com&#x2F;t&#x2F;farewell-to-titanium-backup-looking-for-alternative.3932814&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;contribute to lineage to link to golang extractor, maybe with step by step instructions&lt;&#x2F;li&gt;
&lt;li&gt;Make signal default sms app&lt;&#x2F;li&gt;
&lt;li&gt;Camera from lock screen&lt;&#x2F;li&gt;
&lt;li&gt;transfer paid version of rain alarm, seems to be missing three-dot-menu on new version&lt;&#x2F;li&gt;
&lt;li&gt;Xmeye cctv&lt;&#x2F;li&gt;
&lt;li&gt;Backup alarms&lt;&#x2F;li&gt;
&lt;li&gt;Signal SMS warnings -&amp;gt; Settings-privacy-Trust-SMS Sending Limit &amp;gt; 5&lt;&#x2F;li&gt;
&lt;li&gt;No access to work google cal&lt;&#x2F;li&gt;
&lt;li&gt;Ignore public wifi&lt;&#x2F;li&gt;
&lt;li&gt;Maps.me voice. Needs language pack. Wut.&lt;&#x2F;li&gt;
&lt;li&gt;Remember Bluetooth tethering setting. Needs code change.&lt;&#x2F;li&gt;
&lt;li&gt;Phone default to Bluetooth&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;problems-bugs&quot;&gt;Problems &amp;amp; bugs&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Phone app
&lt;ul&gt;
&lt;li&gt;Fails to unblank when phone rings half the time. Workaround to use power button to sleep&#x2F;wake a couple of times to wake it up. Painful but bearable.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Rainalarm problems:
&lt;ul&gt;
&lt;li&gt;no menu so can&#x27;t enable paid copy&lt;&#x2F;li&gt;
&lt;li&gt;map loads but no rain shown&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;os-updates&quot;&gt;OS Updates&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;update&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;update&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Watch out for de-rooting, make sure backups are up to date first.&lt;&#x2F;p&gt;
&lt;p&gt;Got the first Over The Air (OTA) (...well, over wifi anyway) update from LineageOS. Download. Install. Reboot. Magisk no longer installed. Well that&#x27;s a fucking pain. NeoBackup fails to start. Backups now broken. Fuck you android.&lt;&#x2F;p&gt;
&lt;p&gt;todo: see if I can restore root with out a full wipe and reinstall this time. twunts. what a pile of yaks.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;community.oneplus.com&#x2F;thread?id=914099&quot;&gt;OnePlus Community forum: Keep Root with Magisk with OTA updates&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;LineageOS&#x2F;comments&#x2F;hynl52&#x2F;any_way_to_keep_magisk_and_installed_modules_when&#x2F;&quot;&gt;piles of fucking yaks courtesy of reddit&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;200410&#x2F;how-do-i-update-an-ota-while-retaining-twrp-and-magisk-only-with-my-phone&quot;&gt;https:&#x2F;&#x2F;android.stackexchange.com&#x2F;questions&#x2F;200410&#x2F;how-do-i-update-an-ota-while-retaining-twrp-and-magisk-only-with-my-phone&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;topjohnwu.github.io&#x2F;Magisk&#x2F;ota.html&quot;&gt;https:&#x2F;&#x2F;topjohnwu.github.io&#x2F;Magisk&#x2F;ota.html&lt;&#x2F;a&gt; -&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;When an OTA is available, first go to (Magisk app → Uninstall → Restore Images). Do not reboot or you will have Magisk uninstalled.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Bit fucking late now.&lt;&#x2F;p&gt;
&lt;p&gt;So basically you have to know all this &lt;em&gt;before&lt;&#x2F;em&gt; you let android install an update and fuck up your setup (again). Pit of failure.&lt;&#x2F;p&gt;
&lt;p&gt;Guess I&#x27;ll have to re-do the patch thing I did in the first place.&lt;&#x2F;p&gt;
&lt;p&gt;Export Antennapod state, backup andOTP and make sure syncthing has pushed the files before attempting anything.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;re-root-attempt-success&quot;&gt;Re-root attempt - success!&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s try repeating the magisk setup from the original install but with the updated image.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Check current version installed
&lt;ul&gt;
&lt;li&gt;on phone: settings &amp;gt; about &amp;gt; android version &amp;gt;  &amp;gt; lineageos version: lineage-18.1-20220518-microG-lemonadep&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Download matching image to laptop from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;download.lineage.microg.org&#x2F;lemonadep&#x2F;&quot;&gt;https:&#x2F;&#x2F;download.lineage.microg.org&#x2F;lemonadep&#x2F;&lt;&#x2F;a&gt; (if it&#x27;s still available, which it is. If it wasn&#x27;t then might have to run more updates or grab image from phone somehow)&lt;&#x2F;li&gt;
&lt;li&gt;Run the payload extaction, patch on phone &amp;amp; reflash as in original install:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt; ..&#x2F;..&#x2F;payload-dumper-go&#x2F;payload-dumper-go_1.2.0_linux_amd64&#x2F;payload-dumper-go ..&#x2F;lineage-18.1-20220518-microG-lemonadep.zip&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;[plug phone in to laptop with usb]&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;adb push extracted_20220704_232617&#x2F;boot.img &#x2F;sdcard&#x2F;Download&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;patch the file in magisk on the phone (install &amp;gt; patch &amp;gt; select file etc.)&lt;&#x2F;li&gt;
&lt;li&gt;get the patched file back on to laptop: &lt;code&gt;patched=``adb shell ls &#x2F;sdcard&#x2F;Download&#x2F;magisk_patched*`` &amp;amp;&amp;amp; echo $patched &amp;amp;&amp;amp; adb pull $patched&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;advanced reboot on phone &amp;gt; fastboot&lt;&#x2F;li&gt;
&lt;li&gt;flash the boot image:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@max:~&#x2F;Downloads&#x2F;oneplus9pro&#x2F;lineage-for-microG&#x2F;payload2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ fastboot flash boot magisk_patched-24300_nspcI.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;target reported max download size of 268435456 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sending &amp;#39;boot_b&amp;#39; (196608 KB)...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OKAY [  5.675s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;writing &amp;#39;boot_b&amp;#39;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OKAY [  0.644s]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;finished. total time: 6.320s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;reboot phone (&quot;reboot system now&quot; &amp;gt; power button)&lt;&#x2F;li&gt;
&lt;li&gt;open up magisk app .... drumroll ....&lt;&#x2F;li&gt;
&lt;li&gt;success!! &quot;Installed 24.3 (24300)&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;... run a backup with neobackup to see if it works... oh never mind it just popped a notification that neobackup has been granted superuser so I guess it can run its backups now and the schedule has kicked it off after a reboot.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ota-over-the-air-update-without-losing-root-fail&quot;&gt;OTA (Over The Air) update without losing root - fail&lt;&#x2F;h3&gt;
&lt;p&gt;Having regained root by patching and flashing boot.img again (above) I&#x27;m going to try the OTA on-phone patching as per &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;topjohnwu.github.io&#x2F;Magisk&#x2F;ota.html&quot;&gt;https:&#x2F;&#x2F;topjohnwu.github.io&#x2F;Magisk&#x2F;ota.html&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Settings &amp;gt; System &amp;gt; Advanced &amp;gt; Updater&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Press refresh symbol in top right corner.&lt;&#x2F;p&gt;
&lt;p&gt;Two images available:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;LineageOS 19.1, 11 June 2022, 1.3GB &amp;gt; INFO &amp;gt; &quot;Update blocked This update cannot be installed using the updater app. Please read &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;upgrade&quot;&gt;https:&#x2F;&#x2F;wiki.lineageos.org&#x2F;devices&#x2F;lemonadep&#x2F;upgrade&lt;&#x2F;a&gt; for more information.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;LineageOS 18.1, 18 May 2022, 1.1GB &amp;gt; INSTALL &amp;gt; ...&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;So let&#x27;s try the point update following &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;topjohnwu.github.io&#x2F;Magisk&#x2F;ota.html&quot;&gt;the magisk ota instructions&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Magisk app &amp;gt; Unistall.... um, where&#x27;s that then. Perhaps missing because it wasn&#x27;t instaled this way.
&lt;ul&gt;
&lt;li&gt;&quot;This will restore partitions modified by Magisk back to stock from backups made at install in order to pass pre-OTA block verifications.&quot; - yeah that figures, I didn&#x27;t do that so there&#x27;s no backups to restore.&lt;&#x2F;li&gt;
&lt;li&gt;Guess we&#x27;ll skip this and hope for the best&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Settings &amp;gt; System &amp;gt; Advanced &amp;gt; Updater &amp;gt; 18.1 18 May 2022 &amp;gt; INSTALL &amp;gt; OK&lt;&#x2F;li&gt;
&lt;li&gt;... ~ 10 mins elapse ...&lt;&#x2F;li&gt;
&lt;li&gt;Updater shows &quot;reboot&quot; button. &lt;em&gt;DON&#x27;T PRESS IT!!&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Magisk app &amp;gt; install &amp;gt; install to inactive slot (after OTA) &amp;gt;
&lt;ul&gt;
&lt;li&gt;&quot;Attention. Your device will be FORCED to boot to the current inactive slot after a reboot! Only use this option after the OTA is done. Continue?&quot; &amp;gt; OK&lt;&#x2F;li&gt;
&lt;li&gt;Target slot _a ...&lt;&#x2F;li&gt;
&lt;li&gt;failed! dammit.&lt;&#x2F;li&gt;
&lt;li&gt;press little save button top right to save log&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Failure log: &lt;code&gt;magisk_install_log_2022-07-05T21_12_57.log&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Target slot: _a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Target image: &#x2F;dev&#x2F;block&#x2F;sde16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Device platform: arm64-v8a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Installing: 24.3 (24300)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Unpacking boot image&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Parsing boot image: [&#x2F;dev&#x2F;block&#x2F;sde16]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;HEADER_VER      [3]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;KERNEL_SZ       [40823296]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RAMDISK_SZ      [10201092]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OS_VERSION      [11.0.0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OS_PATCH_LEVEL  [2022-05]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PAGESIZE        [4096]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CMDLINE         []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;KERNEL_FMT      [raw]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RAMDISK_FMT     [gzip]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VBMETA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Checking ramdisk status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Loading cpio: [ramdisk.cpio]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Stock boot image detected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Patching ramdisk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Loading cpio: [ramdisk.cpio]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Add entry [init] (0750)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Create directory [overlay.d] (0750)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Create directory [overlay.d&#x2F;sbin] (0750)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Add entry [overlay.d&#x2F;sbin&#x2F;magisk32.xz] (0644)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Add entry [overlay.d&#x2F;sbin&#x2F;magisk64.xz] (0644)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Patch with flag KEEPVERITY=[true] KEEPFORCEENCRYPT=[true]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Loading cpio: [ramdisk.cpio.orig]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Backup mismatch entry: [init] -&amp;gt; [.backup&#x2F;init]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Record new entry: [overlay.d] -&amp;gt; [.backup&#x2F;.rmlist]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Record new entry: [overlay.d&#x2F;sbin] -&amp;gt; [.backup&#x2F;.rmlist]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Record new entry: [overlay.d&#x2F;sbin&#x2F;magisk32.xz] -&amp;gt; [.backup&#x2F;.rmlist]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Record new entry: [overlay.d&#x2F;sbin&#x2F;magisk64.xz] -&amp;gt; [.backup&#x2F;.rmlist]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Create directory [.backup] (0000)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Add entry [.backup&#x2F;.magisk] (0000)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Dump cpio: [ramdisk.cpio]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Repacking boot image&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Parsing boot image: [&#x2F;dev&#x2F;block&#x2F;sde16]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;HEADER_VER      [3]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;KERNEL_SZ       [40823296]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RAMDISK_SZ      [10201092]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OS_VERSION      [11.0.0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OS_PATCH_LEVEL  [2022-05]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PAGESIZE        [4096]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CMDLINE         []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;KERNEL_FMT      [raw]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RAMDISK_FMT     [gzip]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VBMETA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Repack to boot image: [new-boot.img]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;HEADER_VER      [3]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;KERNEL_SZ       [40823296]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RAMDISK_SZ      [10715780]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OS_VERSION      [11.0.0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OS_PATCH_LEVEL  [2022-05]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PAGESIZE        [4096]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CMDLINE         []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Flashing new boot image&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- Sepolicy rules dir is &#x2F;dev&#x2F;hWU&#x2F;.magisk&#x2F;mirror&#x2F;metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;! Installation failed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;! Unable to download bootctl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Guess I&#x27;ll try the patch of boot again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion-inconclusive&quot;&gt;Conclusion: inconclusive&lt;&#x2F;h2&gt;
&lt;p&gt;The main thing I&#x27;ve learned from this is the long-standing duopoly of iOS+Android has caused deep and hard to reverse problems in the phone software ecosystem. It&#x27;s a crying shame really because there is so much opportunity for innovation now that phone hardware is basically done, but instead we get stagnation, pointless features, anti-features and down-right user-hostile behaviour from both we-know-best camps. It really reminds me of the dark years of the browser and operating system wars. Particularly when internet explorer became dominant and website (i.e. app) developers targeted proprietary IE APIs, locking everyone in and nearly killing the competition. The same for windows in its prime (when Balmer shouted developers-developers-developers he knew the apps created platform-vendor lock-in that he so desired).&lt;&#x2F;p&gt;
&lt;p&gt;There are some promising signs: Ubuntu so nearly made a phone, and then didn&#x27;t hit their funding target (the ubuntu phone operating system lives on in obscurity), The Librem looks like it might be a sustainable Linux based phone &amp;amp; business (Android is &lt;em&gt;not&lt;&#x2F;em&gt; Linux remember).&lt;&#x2F;p&gt;
&lt;p&gt;For me I think I&#x27;ll do the closest thing I can to dual-boot and VMs which is to have a second burner phone to run prioprietary crap, but have a primary phone that&#x27;s as open as I can make it, just like I did with Linux and Windows around 2005-2010.&lt;&#x2F;p&gt;
&lt;p&gt;Every person that takes this route is a vote for change. User numbers matter, especially when it comes to app vendors; they won&#x27;t invest in dead platforms, but they can&#x27;t and don&#x27;t ignore growing market share, and if that&#x27;s free and open it gets supported. Just look at Microsoft rewriting their &lt;em&gt;entire&lt;&#x2F;em&gt; dotnet ecosystem from scratch to be cross platform.&lt;&#x2F;p&gt;
&lt;p&gt;Open source moves slowly, but like an iceberg it&#x27;s hard to stop when it&#x27;s claimed the land.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;end-for-now&quot;&gt;End... for now&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s as far as I&#x27;ve got so far. I&#x27;ll be editing this post as I progress with the install so do come and look again. Also suggestions and questions welcome.&lt;&#x2F;p&gt;
&lt;p&gt;I really do hope one day I can de-google my phone just like I de-microsofted my laptop, but today is not that day for me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;358166&#x2F;using-android-without-google-a-kind-of-guide&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;358166&#x2F;using-android-without-google-a-kind-of-guide&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Being a development team lead</title>
        <published>2021-12-10T00:00:00+00:00</published>
        <updated>2021-12-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/12/10/being-a-development-team-lead/"/>
        <id>https://0x5.uk/2021/12/10/being-a-development-team-lead/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/12/10/being-a-development-team-lead/">&lt;p&gt;Here&#x27;s my take on what it means to be a dev-lead &#x2F; tech-lead &#x2F; lead developer; and why it&#x27;s time I stepped up.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m going to explain what I think makes for a really good high-functioning dev team, and how to get there along with links to essential reading on the subject.&lt;&#x2F;p&gt;
&lt;p&gt;As always contributions and thoughts welcome, drop me a line. If you want me to help with your team just shout. I love to just chat with people about their challenges in digital delivery, whether or not I end up becoming part of the project.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m also going to say why I think it&#x27;s time I shifted &lt;em&gt;my&lt;&#x2F;em&gt; contracting focus from individual contributor to being a lead dev for teams.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-be-an-excellent-lead-dev&quot;&gt;How to be an excellent lead dev&lt;&#x2F;h2&gt;
&lt;p&gt;Having worked under many team leaders of all types I have a pretty good idea of what&#x27;s pleasant and effective. And I&#x27;m glad to say that being a nice human being to be around is a big part of being a great leader. Dictatorial, unpleasant and command-and-control leadership are just not the right tool for running complex digital delivery projects&lt;&#x2F;p&gt;
&lt;h3 id=&quot;servant-leader&quot;&gt;Servant-leader&lt;&#x2F;h3&gt;
&lt;p&gt;The best leaders I&#x27;ve come across are almost deceptively non-leader-like. This is because our culture in the west (hello press, television and film) portrays &quot;leaders&quot; as hard-ass bullies who get the best out of an organisation by ordering people around, knowing all the answers like some kind of god and generally being unpleasant. The reality is that the best leaders don&#x27;t lead by intimidation, they lead by example, lead by being humble, lead by coaching (see below) and know that relationships and trust are what really matter for teams that can ship and respond to problems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;culture-of-trust&quot;&gt;Culture of trust&lt;&#x2F;h3&gt;
&lt;p&gt;Everyone in the team is doing the best they can with the knowledge and circumstances they have. We can all help each other get better with trust and a good dose of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Nonviolent-Communication-Marshall-Rosenberg&#x2F;dp&#x2F;1591791707&quot;&gt;nonviolent communication&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openness-with-all&quot;&gt;Openness with all&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gov.uk&#x2F;guidance&#x2F;government-design-principles#make-things-open-it-makes-things-better&quot;&gt;Make things open: it makes things better&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve always thought it best that anyone in the organisation who is interested can see every last detail of what we&#x27;re working on, right down to the code. This does of course require a culture of trust, but if that&#x27;s missing there are deeper problems to be solved.&lt;&#x2F;p&gt;
&lt;p&gt;There are of course some things that need to be protected such as production keys and the personal data of users.&lt;&#x2F;p&gt;
&lt;p&gt;As an example I ran an end-of-sprint demo for a client with all the major stakeholders present for an important project. The demo consisted of a &quot;red screen of death&quot;, which showed that we had been unable to get a particular piece of technology with which the team was unfamiliar to work even after a whole sprint on it. Once the shock of the blunt honesty subsided the senior stakeholders were able to see that something needed to be done to ensure success and helped us recruit an external consultant with expertise in that particular technology. From there on things went much more smoothly. If we hadn&#x27;t demoed our &quot;failure&quot; then there was a real risk that the senior stakeholders would have mistakenly thinking everything was fine and now action was needed, which would likely have resulted in a complete failure of the project to deliver. Some people seem to like to always paint a positive picture to their seniors (the RAG reports that are always yellow until it&#x27;s too late to fix anything and they finally all go red, as they people go and get new jobs elsewhere...).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setting-the-standards&quot;&gt;Setting the standards&lt;&#x2F;h3&gt;
&lt;p&gt;Nobody wants bugs, unmaintainable spaghetti code, regressions due to missing test coverage. But how do you achieve this in a collaborative positive way? Just demanding it be so is ineffective and builds resentment.&lt;&#x2F;p&gt;
&lt;p&gt;No team is perfect. No software is perfect. There is only &quot;better&quot;, &quot;worse&quot; and different tradeoffs between different pressures on system design and human behaviour. So we should strive for the best, bring the team with us, and accept that we are all flawed human beings with an inability to simultaneously keep in our heads every constraint and piece of the system. In fact software is largely written and architected the way it is &lt;em&gt;because&lt;&#x2F;em&gt; even the best human brains have limited capacity for knowledge of a system. Managing complexity and coping gracefully with humans being human is an important part of the puzzle.&lt;&#x2F;p&gt;
&lt;p&gt;I see the push towards today and tomorrow&#x27;s &quot;best practice&quot; more as giving permission to the team to strive for it than enforcing. Most developers I know want to be and do the absolute best they can. When team output doesn&#x27;t meet some criteria (such as test coverage) these are some possible reasons that I&#x27;d look at. I&#x27;d use the ordering below so that we can assume good faith until proven wrong. I definitely wouldn&#x27;t start with confrontation or accusation. Assuming the best does not mean giving up powers of last resort should all other options be exhausted, but that would be the last option. Filtering for great people on the way in is much better than undoing poor selection once the team is up and running.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;What pressures are being placed on a contributor to behave a particular way, where is that coming from? E.g. is a delivery manager pushing for raw speed and that being interpreted as a need to skip test coverage and just ship bare production code. In that case perhaps some conversations about the tradeoffs being invisibly made are all that it would take, and some defense of the fundamentals that drive the need for &quot;best practice&quot; in the first place (e.g. regression-proofing to allow continuous delivery, and confidence in refactoring to support agility and ongoing quality, see also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Extreme_programming&quot;&gt;XP&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Is there a lack of knowledge as to why this good practice is beneficial to the project? If so some mentoring and coaching might be in order. Maybe as part of some pair programming exercises.&lt;&#x2F;li&gt;
&lt;li&gt;Provide formal training (perhaps Pluralsight courses) to fill in the knowledge gaps. Particularly for permanent employees. For contractors perhaps a suggestion of courses they could take to level-up.&lt;&#x2F;li&gt;
&lt;li&gt;Communicating to those involved in line management &#x2F; supplier management the concerns with not meeting the standards the rest of the team are able to achieve. Discussing additional ways of providing support to enable the individual to level-up.&lt;&#x2F;li&gt;
&lt;li&gt;Finally and this is not a preferred option due to the disruption it causes make the call to formally put someone on a formal improvement plan or move them on.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;the-coaching-ladder&quot;&gt;The coaching ladder&lt;&#x2F;h4&gt;
&lt;p&gt;Inspired by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.developingleadership.co&#x2F;episode&#x2F;episode-19-transitioning-from-a-holacracy-to-a-strong-engineering-leadership-culture-with-katie-wilde-from-ambassador-labs#&quot;&gt;Developing Leadership podcast episode 19 about a strong engineering leadership culture&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Different people, cultures and neurological wiring need different ways of setting out expectations. A two-pronged approach of gentle coaching + clear expectation &amp;amp; consequence setting seems to cover all bases.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Listening mode - make sure people are heard in groups and one-on-one&lt;&#x2F;li&gt;
&lt;li&gt;Gently coach expectations - &quot;have you thought about doing x?&quot; &#x2F; &quot;I observe that your PR descriptions average 10 words&quot; &#x2F; &quot;here&#x27;s how writing clear PR descriptions helps your valuable ideas be recognised by the team&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Set out consequences of not meeting expectations - &quot;We require excellent communication in pull requests to the standard of [example]&quot; &#x2F; &quot;this standard is a requirement of continuing to be a senior engineer here&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;one-minute-manager&quot;&gt;One-minute manager&lt;&#x2F;h4&gt;
&lt;p&gt;Where course correction is needed (when operating more as a line-manager) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;New-One-Minute-Manager&#x2F;dp&#x2F;0008128049&quot;&gt;The (new) One Minute Manager&lt;&#x2F;a&gt; offers some great advice on keeping it simple and clear for all involved. This suggests that one-to-one interactions take the form of:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;One-minute on goals&lt;&#x2F;li&gt;
&lt;li&gt;One-minute on praise&lt;&#x2F;li&gt;
&lt;li&gt;One-minute on redirection&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If doing only three minutes of this means they can be done more often and more reliably with the whole team this is a win, as often the opportunity for this kind of discussion is lacking due to the pressure to ship. It&#x27;s important to note that this doesn&#x27;t mean the relationship has reverted to command and control, only that clear expectations are important for everyone&#x27;s success and happiness.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;current-best-practice-and-lofty-goals&quot;&gt;Current &quot;Best Practice&quot; and Lofty Goals&lt;&#x2F;h3&gt;
&lt;p&gt;Things we should strive towards doing&#x2F;having.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Great test coverage
&lt;ul&gt;
&lt;li&gt;100% unit test coverage (in meaning not just in line count)
&lt;ul&gt;
&lt;li&gt;Why? Because this enables refactoring with confidence, reduces the chance of regressions and encourages good design (e.g. decoupling, SOLID etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Use TDD (Test-Driven Development)... if it&#x27;s the right tool for the job. TDD is a useful technique to be sure. It&#x27;s harder to use when you can&#x27;t picture the shape of what you are going to create in your head in advance which I think is probably its biggest weakness. The ultimate objective is that it should be impossible to change the intended behaviour of a production code without a test failing. TDD helps with this but isn&#x27;t the only way. Another way is to alter the behaviour temporarily (locally) after the code is written and make sure the tests do actually fail. So long as the output coverage is good then I don&#x27;t personally think that being religious about TDD is especially helpful. I think it&#x27;s a technique that all developers should learn and practice, whether or not they use it for every piece of code they write.&lt;&#x2F;li&gt;
&lt;li&gt;Smoke tests
&lt;ul&gt;
&lt;li&gt;Some kind of end-to-end &quot;did we break anything critical&quot; that runs on real infrastructure. This usually requires dedicated effort to create beyond the tests created during individual feature work. I recommend putting this in the backlog and ensuring it is scheduled as it&#x27;s too big for a hero-developer to &quot;just do&quot; unless you&#x27;ve completely lost control.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.browserstack.com&#x2F;guide&#x2F;visual-regression-testing&quot;&gt;Visual regression testing&lt;&#x2F;a&gt; - in anything with a UI this can catch regressions and unintentional changes that would be hard to catch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.agilealliance.org&#x2F;glossary&#x2F;bdd&#x2F;&quot;&gt;&quot;BDD&quot; (Behaviour Driven Development) aka specification by example&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A tool for a job. Use it where it&#x27;s useful such as allowing business analysts to create and validate example scenarios for complex calculations or flows. Beware of the overhead of example wiring code.&lt;&#x2F;li&gt;
&lt;li&gt;Often confused with UI tests due to coincidental timing of creation with browser-automation. BDD is not the same as UI testing, mkay?&lt;&#x2F;li&gt;
&lt;li&gt;The point of BDD is more that it&#x27;s a user&#x2F;business need focussed description of what the software is supposed to do that&#x27;s then made executable through a translation layer. Do not forget this.&lt;&#x2F;li&gt;
&lt;li&gt;You can get a lot of the benefit of BDD by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.futurelearn.com&#x2F;info&#x2F;blog&#x2F;how-we-write-readable-feature-tests-with-rspec&quot;&gt;just writing test method names in the BDD style&lt;&#x2F;a&gt;, such as &lt;code&gt;def the_order_total_should_be(total_price)&lt;&#x2F;code&gt; and then chaining them together in a top level &quot;scenario&quot; method just like you would with gherkin but without all the example parsing overhead.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Continuous delivery (and confidence to ship any time without even looking)
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sdtimes.com&#x2F;devops&#x2F;going-lights-out-with-devops&#x2F;&quot;&gt;Lights-Out delivery&lt;&#x2F;a&gt; - i.e. never having to manually interact with production servers. Related to configuration-as-code etc.&lt;&#x2F;li&gt;
&lt;li&gt;Use feature flags (related to the true meaning of the oft misused phrase &quot;continuous integration&quot;) to avoid long-lived feature branches for things you can&#x27;t release to the users yet.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Use the best type of project management (yes I used the dirty words!) for &lt;em&gt;your&lt;&#x2F;em&gt; project.
&lt;ul&gt;
&lt;li&gt;Agility:
&lt;ul&gt;
&lt;li&gt;Methodologies are fine, but the point is to be able to be responsive to changing knowledge and business requirements. Never forget that.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.extremeprogramming.org&#x2F;&quot;&gt;eXtreme Programming&lt;&#x2F;a&gt; - an important piece of the landscape, with a focus on technical approaches that allow agility (always shippable, fully tested, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.scrum.org&#x2F;resources&#x2F;what-is-scrum&#x2F;&quot;&gt;Scrum&lt;&#x2F;a&gt; - a good basis for all projects, especially greenfield development&lt;&#x2F;li&gt;
&lt;li&gt;Kanban - better for maintenance mode projects
&lt;ul&gt;
&lt;li&gt;It&#x27;s very important to understand &quot;Work In Progress (WIP) limits&quot; regardless of whether you use kanban or not. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;W92wG-HW8gg&quot;&gt;This video explains wip limits&lt;&#x2F;a&gt; in a way that is easily understandable. The mathematically truth of wip limits will always be counter-intuitive to my monkey-brain I think. In short, throughput matters more than utilisation of each person&#x2F;resource.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Lean&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;flowacademy.io&#x2F;what-is-flow&#x2F;&quot;&gt;Flow&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.scaledagileframework.com&#x2F;&quot;&gt;Scaled Agile (SAFe)&lt;&#x2F;a&gt; for multi-team agile&lt;&#x2F;li&gt;
&lt;li&gt;ShapeUp from basecamp is inspirational. It&#x27;s a refreshing change from scrum. I wrote &lt;a href=&quot;&#x2F;2019&#x2F;11&#x2F;26&#x2F;time-to-shape-up-your-scrum-process-the-new-thing-from-basecamp&#x2F;&quot;&gt;a summary of ShapeUp&lt;&#x2F;a&gt; which, in my humble opinion, is worth a read.&lt;&#x2F;li&gt;
&lt;li&gt;Waterfall is bad. Period. Gantt charts are to be treated with suspicion, along with anyone and anything else that promises complete predictability of software development.&lt;&#x2F;li&gt;
&lt;li&gt;Self-directed teams that own their results and can use appropriate methods for their particular challenges are far more effective than standardization.&lt;&#x2F;li&gt;
&lt;li&gt;Personally I like some kind of blend of scrum and kanban, and definitely no story pointing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Lightweight agile governance:
&lt;ul&gt;
&lt;li&gt;Stakeholders showing up to sprint demos (show-n-tell) is much more time-efficient and more powerful than written reports.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Ability to rebuild entire estate from source-control:
&lt;ul&gt;
&lt;li&gt;Binaries&lt;&#x2F;li&gt;
&lt;li&gt;Infrastructure (configuration-as-code)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;DevOps in practice not just in name (the development team &lt;strong&gt;owning&lt;&#x2F;strong&gt; production)
&lt;ul&gt;
&lt;li&gt;This implies a diversity of skills within the &quot;development&quot; team.&lt;&#x2F;li&gt;
&lt;li&gt;Assistance from people with expertise outside the team is of course welcome, but the important thing is the team continues to own their own outcomes.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Some (but not complete) harmonization of technology choices:
&lt;ul&gt;
&lt;li&gt;Largely consistent technology makes hiring and moving around projects easier&lt;&#x2F;li&gt;
&lt;li&gt;Completely consistent technology prevents using the best tool for the job&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Following &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;12factor.net&#x2F;&quot;&gt;12 factor principles&lt;&#x2F;a&gt;.
&lt;ul&gt;
&lt;li&gt;Pushing beyond the original 12 factor principles - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;smallbatches.fm&#x2F;7&#x2F;&quot;&gt;Small Batches podcast episode 7&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Continuous improvement (of the team, the processes and the system being built)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Pair&#x2F;mob programming.
&lt;ul&gt;
&lt;li&gt;Collaborating on just about everything ensures no-one is a single point of knowledge for any one thing.&lt;&#x2F;li&gt;
&lt;li&gt;The sharing of knowledge, skills and techniques improves everyone&#x27;s skills as we go.&lt;&#x2F;li&gt;
&lt;li&gt;Many problems and bugs are caught even before &lt;code&gt;git add&lt;&#x2F;code&gt; has been run. The later a problem is found the more it costs to rectify it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;estimates&quot;&gt;Estimates&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;Story points, t-shirt sizes, predictions, time-based estimates and no-estimates.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a topic that always causes heated debate with lots of dogma on all sides. Experiences of day-long point-guessing sessions leave developers who just want to ship nervous of anyone who mentions the word estimate or point. Project owners&#x2F;managers get nervous when they have no idea how much they are about to spend. Deadlines can be real or made up. Cost&#x2F;benefit decisions have to be made. So what should we do?&lt;&#x2F;p&gt;
&lt;p&gt;I say it depends. And more usefully, &lt;strong&gt;only create estimates if you can prove you need them&lt;&#x2F;strong&gt;, and then use the most lightweight way you can come up with of getting just enough information to make a call and go back to cutting code.&lt;&#x2F;p&gt;
&lt;p&gt;Creating estimates has a cost, make sure you know you need it otherwise don&#x27;t pay the price. Kanban calls this &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kanbanize.com&#x2F;lean-management&#x2F;value-waste&#x2F;7-wastes-of-lean&quot;&gt;waste&lt;&#x2F;a&gt;&quot; (i.e. anything that doesn&#x27;t end up in the final product, which definitely includes estimation work).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ronjeffries.com&#x2F;articles&#x2F;019-01ff&#x2F;story-points&#x2F;Index.html&quot;&gt;Avoid story points&lt;&#x2F;a&gt; - they were basically invented as a way to prevent people mistaking &lt;strong&gt;estimates&lt;&#x2F;strong&gt; for &lt;strong&gt;commitments&lt;&#x2F;strong&gt; but have taken on a horrifying life of their own. I have &lt;em&gt;never&lt;&#x2F;em&gt; seen them be particularly useful in any of the many projects I&#x27;ve been on, and I have regularly seen them be a big cause of pain, wasted time and discontentment.&lt;&#x2F;p&gt;
&lt;p&gt;Genuine reasons for needing some kind of estimate:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Big-feature prioritization - use t-shirt sizes (small, medium, large, elephant)&lt;&#x2F;li&gt;
&lt;li&gt;Can&#x27;t miss deadline (I arrived on a project when the release date of a non-existent thing had already been announced by the managing director to all the customers). Do as few of the following as you can: (listed in increasing order of cost and decreasing order of preference.)
&lt;ul&gt;
&lt;li&gt;A &quot;finger in the air&quot; hunch for viability of the project from an experienced engineer&lt;&#x2F;li&gt;
&lt;li&gt;Consider just doing the minimum viable product (MVP) first and then adding nice to haves once that&#x27;s done (iterate). Focus on always-shippable.&lt;&#x2F;li&gt;
&lt;li&gt;If you are concerned even the smallest viable thing might not be doable then you might have to create some architecture designs and prototypes up-front to reduce risk of discovering complications later.&lt;&#x2F;li&gt;
&lt;li&gt;If time is tight and even the MVP is looking uncertain then you might have to create actual estimates for more detailed tasks to give you a better idea of the options ahead of you. I have actually done this on a fixed-deadline project. It&#x27;s time consuming and dangerously waterfall but it might be your only choice. The more granular the task list the more accurate the estimate (it helps compensate for human bias), but on the flip side the more detail you create without building the more likely you are to be wrong about the design and tasks and for it all to be a waste.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Planning releases - do you &lt;em&gt;really&lt;&#x2F;em&gt; need to do this give the cost? Consider using feature-flags instead to hold back features if you need to time their release.&lt;&#x2F;p&gt;
&lt;p&gt;If you need to forecast based on points &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;christopher-bimson.github.io&#x2F;blog&#x2F;2017&#x2F;04&#x2F;19&#x2F;forecaster&quot;&gt;use monte-carlo story-point forecasting as implemented by Chris Bimson&lt;&#x2F;a&gt;. While I like this approach I&#x27;d challenge the need for the forecasts in the first place before committing to the significant extra overhead of calculating and tracking points and then turning that into forecast.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;staying-sharp&quot;&gt;Staying sharp&lt;&#x2F;h3&gt;
&lt;p&gt;Even though I accidentally led a couple of teams early in my contracting career I didn&#x27;t at that point fancy moving &quot;up&quot; the ladder. I had seen people become &quot;dev team managers&quot; and rapidly lose all their technical skills through a combination of atrophy and the never-ending churn in state-of-the-art technology and practice. I certainly didn&#x27;t want to end up us a mediocre manager with mediocre and outdated tech skills. So I put my head down and kept on coding as an &quot;individual contributor&quot; (sometimes referred to as an I.C.). Since then I&#x27;ve learned and seen some tricks that I think can allow people to stay sharp no matter how high they climb.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-pendulum&quot;&gt;The pendulum&lt;&#x2F;h4&gt;
&lt;p&gt;By alternating roles you take on between individual contributor (coder) and team lead roles you can keep the experience of coal-face high-pace shipping fresh whilst also giving more value by helping whole teams succeed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;charity.wtf&#x2F;2017&#x2F;05&#x2F;11&#x2F;the-engineer-manager-pendulum&#x2F;&quot;&gt;https:&#x2F;&#x2F;charity.wtf&#x2F;2017&#x2F;05&#x2F;11&#x2F;the-engineer-manager-pendulum&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-non-critical-path-task&quot;&gt;The non-critical-path task&lt;&#x2F;h4&gt;
&lt;p&gt;I tried picking up a story from the sprint when I was leading a team once. It didn&#x27;t go well but I didn&#x27;t know any better. Because my primary goal was team enablement and my time was interrupt-driven I&#x27;d end up with the team waiting for my piece to get done. Not a great help to the team&#x27;s delivery speed. I also found with the team being full time on code and me less than full time I was always just that little bit behind on current thinking in the heart of the codebase, and you don&#x27;t have to be much out of step to be much less productive or cause more problems than you solve.&lt;&#x2F;p&gt;
&lt;p&gt;Since then I&#x27;ve seen two great approaches implemented by others:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Take on a non-critical but useful coding piece that won&#x27;t block the team. I watched an amazing product owner (who can also code) built an entire support console microservice while us devs built the main production app. This gave huge benefit of allowing the support folks and BAs to self-serve on things we didn&#x27;t have time to build to production grade. It kept him close to the actual product. It also kept his Ruby on Rails skills current and sharp. Ace. I shall be copying this trick!&lt;&#x2F;li&gt;
&lt;li&gt;Work on enablement pieces. Make sure CI pipelines are flowing well. Do version upgrades. Tackle bugs that haven&#x27;t made the team&#x27;s sprint. I&#x27;ve seen a team lead do this effectively and would recommend.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;interviewing-filtering&quot;&gt;Interviewing &#x2F; filtering&lt;&#x2F;h3&gt;
&lt;p&gt;Not everyone gets this luxury but being allowed to control who works in your team will do more for your ability to succeed than anything else.&lt;&#x2F;p&gt;
&lt;p&gt;For a phone screen I wrote up my process here: &lt;a href=&quot;&#x2F;2021&#x2F;12&#x2F;10&#x2F;technical-phone-screen-interview-questions&#x2F;&quot;&gt;Technical phone screen interview questions&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Beyond a quick phone&#x2F;video screen my favourite approach is a pair-programming exercise as this is such a rich source of information and matches how we actually get things done.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;coaching-mentoring&quot;&gt;Coaching &amp;amp; mentoring&lt;&#x2F;h3&gt;
&lt;p&gt;I can&#x27;t say it better than &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Coaching-Habit-Less-Change-Forever&#x2F;dp&#x2F;B01HH7IZCI&quot;&gt;The Coaching Habit by Michael Bungay Stanier&lt;&#x2F;a&gt;. The follow-up book &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;How-Tame-Your-Advice-Monster&#x2F;dp&#x2F;1989025757&quot;&gt;The Advice Trap&lt;&#x2F;a&gt; is also excellent.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve often been guilty of unloading all my &quot;knowledge&quot; on others before they&#x27;ve even asked. Now I see the error of my ways and instead as per the book look to nudge and help at people&#x27;s own pace. Being there to assist and give confidence as needed; leading people to the best answer through questions instead of answers (and being happy to be surprised that it&#x27;s a better answer than I had in mind).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;decision-making&quot;&gt;Decision making&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s good to have single points of responsibility such as a tech lead or project owner, however that doesn&#x27;t mean that it&#x27;s top down control.&lt;&#x2F;p&gt;
&lt;p&gt;As for how to make the best decisions in chaos and complexity, or when thinking seems to have narrowed to group-think this is an excellent guide: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Decisive-Make-Better-Choices-Life&#x2F;dp&#x2F;0307956393&quot;&gt;Decisive: How to Make Better Choices in Life and Work by Chip &amp;amp; Dan Heath&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;things-to-read-watch-listen-too&quot;&gt;Things to read &#x2F; watch &#x2F; listen too&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Blog posts
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;paulgraham.com&#x2F;makersschedule.html&quot;&gt;Maker&#x27;s Schedule, Manager&#x27;s Schedule by Paul Graham&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;noidea.dog&#x2F;glue&quot;&gt;Being Glue post&#x2F;talk by Tanya Reilly&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2000&#x2F;03&#x2F;23&#x2F;command-and-conquer-and-the-herd-of-coconuts&#x2F;&quot;&gt;Command and Conquer and the Herd of Coconuts by Joel Spolsky&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;danluu.com&#x2F;wat&#x2F;&quot;&gt;Normalization of deviance by Dan Luu&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Tech leadership books
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Notes-Software-Team-Leader-Organizing&#x2F;dp&#x2F;829993320X&quot;&gt;Notes to a Software Team Leader: Growing Self Organizing Teams by Roy Osherove&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;General leadership &amp;amp; communication books
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Advice-Trap-Humble-Curious-Forever-ebook&#x2F;dp&#x2F;B083YZTW4B&quot;&gt;The Advice Trap: Be Humble, Stay Curious &amp;amp; Change the Way You Lead Forever by Michael Bungay Stanier&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.audible.co.uk&#x2F;pd&#x2F;The-Five-Dysfunctions-of-a-Team-Audiobook&#x2F;B004EXKC5M&quot;&gt;5 Dysfunctions of a Team&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.audible.co.uk&#x2F;pd&#x2F;The-First-90-Days-Updated-and-Expanded-Audiobook&#x2F;B00CDW0EX6&quot;&gt;The First 90 Days&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Personal development (you&#x27;ll need this for you and your team!)
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Daring-Greatly-Courage-Vulnerable-Transforms-ebook&#x2F;dp&#x2F;B00APRW2WC&quot;&gt;Daring Greatly by Brené Brown&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Nonviolent-Communication-Create-Relationships-Harmony&#x2F;dp&#x2F;B00TIWFAV0&#x2F;&quot;&gt;Nonviolent Communication; Marshall Rosenberg&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Bonds-That-Make-Free-Relationships&#x2F;dp&#x2F;B07N149VZK&#x2F;&quot;&gt;Bonds That Make Us Free; C. Terry Warner&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;48-Laws-of-Power&#x2F;dp&#x2F;B00WYRC0L4&#x2F;&quot;&gt;48 Laws of Power; Robert Greene&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Lean &#x2F; Flow &#x2F; Kanban agile etc
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Goal-Process-Ongoing-Improvement-ebook&#x2F;dp&#x2F;B002LHRM2O&quot;&gt;The Goal: A Process of Ongoing Improvement Kindle Edition
by Eliyahu M. Goldratt&lt;&#x2F;a&gt; (Audible version has sound effects and everything!)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=W92wG-HW8gg&quot;&gt;WIP: why limiting work in progress makes sense (Kanban) (YouTube)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(Personally I like Audible books, I think it sinks in better being told the stories by another human voice)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;who-to-learn-from&quot;&gt;Who to learn from&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;The legend of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;&quot;&gt;Joel Spolsky&lt;&#x2F;a&gt; - I&#x27;ve been reading his articles since I first started coding. Remember &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2000&#x2F;08&#x2F;09&#x2F;the-joel-test-12-steps-to-better-code&#x2F;&quot;&gt;the joel test&lt;&#x2F;a&gt;&quot;?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;other-ways-of-moving-up&quot;&gt;Other ways of moving &quot;up&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;These days thankfully moving into management isn&#x27;t the only way to get a pay raise in many organisations. Places have recognised that getting ever deeper into technology is in itself valuable, spawning titles such as &quot;principle engineer&quot; that carry the weight and renumeration to match the value and experience of a coder who has seen many things and developed many other skills beyond pure coding.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s also the &quot;architect&quot; route where you can be an expert in deciding what to use and how to put it together from the seemingly infinite choice of technical solutions, patterns, services and infrastructure that will solve pretty much any given problem. There&#x27;s good money to be made being an architect, if nothing else than because your power to royally screw everything up for everyone that comes after you is probably about as high as it gets in this role! (Yes I&#x27;ve been on the receiving end of good and bad &quot;architecture&quot;).&lt;&#x2F;p&gt;
&lt;p&gt;The road to CTO. You can join a small startup and ride the explosive growth, ending up with many engineers and services under your control. Or you can work your way up relentlessly in one or more large organisations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;me-a-leader&quot;&gt;Me, a leader?&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-me-why-now-why-this&quot;&gt;Why me, why now, why this?&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;d like to build a product, but I can&#x27;t just stop contracting and hope for the best. As such I&#x27;ve spent some time considering which direction I should take my contractor life.&lt;&#x2F;p&gt;
&lt;p&gt;When considering changes of career direction I highly recommend &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Working-Identity-Unconventional-Strategies-Reinventing-ebook&#x2F;dp&#x2F;B004OEIQ7C&quot;&gt;the book &quot;Working Identity&quot; by Herminia Ibarra&lt;&#x2F;a&gt; which lays out a framework for thinking about the journey of the change, combined with lots of research and stories of others who&#x27;ve faced the chasm (often but not exclusively in the traditional mid-life point).&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s some ideas that popped up (&quot;identities to try on&quot; in the terminology of the book):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Systems-integration agency&#x2F;consultancy&lt;&#x2F;strong&gt; - I had a go at this but seems to be too big a jump for me right now, on the plus side it&#x27;s kicked off another period of learning and self-development for me and is the reason I hired a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;businesscoachdirectory.com&#x2F;coaches&#x2F;&quot;&gt;business coach&lt;&#x2F;a&gt; which I am eternally grateful for.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Become a &quot;frontend&quot; engineer&lt;&#x2F;strong&gt; - Traditionally I&#x27;ve been a &quot;full stack&quot; or &quot;backend&quot; engineer which fits my engineering strengths of dealing with complexity in code (for example &lt;a href=&quot;&#x2F;2020&#x2F;07&#x2F;09&#x2F;approaches-to-refactoring-and-technical-debt&#x2F;&quot;&gt;tech debt as discussed here&lt;&#x2F;a&gt;). Way back there wasn&#x27;t much complexity beyond a bit of jQuery in most frontend things, in fact I didn&#x27;t come across the frontend&#x2F;backend specialization for many years. For a long time the designers-who-can-html dominated frontend land. But these days with ES6, Typescript, npm, angular, react, etc. etc. there is now endless complexity on the frontend for someone like me to get my teeth into. With that in mind (and with a view to improving my ability to ship side-projects) I&#x27;ve been updating my languishing frontend skills. (There&#x27;s not much frontend in my recent work for UK Gov as that&#x27;s pretty much templated out with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;design-system.service.gov.uk&#x2F;&quot;&gt;gov.uk design system&lt;&#x2F;a&gt;, and accessibility concerns means that fancy responsive SPAs don&#x27;t tend to pass muster). Having put the idea out there with recruiters etc. but not getting much interest I think it&#x27;s probably a jump too far in one go, but either way I&#x27;ll spend some spare time skilling up.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Lead developer&lt;&#x2F;strong&gt; - I don&#x27;t really know why I didn&#x27;t think of this sooner, it&#x27;s actually a good fit for where I&#x27;ve been and where my life is at now. This is my current identity to try on, wish me luck! The rest of this post is about this.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here&#x27;s why I like the team lead idea right now:&lt;&#x2F;p&gt;
&lt;p&gt;I think can provide more value as a contract team-lead for dotnet delivery teams. I can still crank code, and still enjoy coding, but helping a whole team succeed is a worthy thing.&lt;&#x2F;p&gt;
&lt;p&gt;The higher rates would make up for it being a less commonly available role (there&#x27;s always at least two individual contributors for every team lead, and leads are less commonly contractors). And I could always fill in with coder work in any gaps.&lt;&#x2F;p&gt;
&lt;p&gt;Thinking back to my history and current position, I&#x27;ve enjoyed the lead roles I&#x27;ve done, I love enabling those around me, and I&#x27;ve learned some tricks for being able to stay close to the tech without getting in the way (see &quot;staying sharp&quot; above). I can still crank code, but it seems a shame to learn everything I have beyond the code and then not put it into practice.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;experience-leading&quot;&gt;Experience leading&lt;&#x2F;h3&gt;
&lt;p&gt;One of my earliest contracts was a project where I was brought in as a solo dev with a view to delivering an asp.net project. The first task was to collect the requirements from a sales person (not an end user or user researcher sadly but that&#x27;s how it was). So armed with my new love of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;balsamiq.com&#x2F;&quot;&gt;balsamiq mockups&lt;&#x2F;a&gt; I set about turning the explained needs into a set of wireframes, using them as a tool for a tool for discussion and iterating them as I better understood the problem at hand. I then started work building. After some time the CTO sauntered over and casually asked how likely we were to meet the publicised launch date now that we understood what needed to be built. &quot;Zero&quot; I said, as this was quite a sizeable thing on a not particularly long timeline. A lovely chap to work with he didn&#x27;t pass further comment and disappeared again.&lt;&#x2F;p&gt;
&lt;p&gt;Not much later I found myself with a team to work on the project consisting of a mix of permanent development staff who&#x27;d been reassigned to the project. Because I was there first and I was in touch with the people relaying user&#x27;s needs I was naturally the hub for the team. Additionally I was one of the few who&#x27;d practiced agile methods in previous roles. The result was I felt it was far more important that I enabled the rest of my team to be as productive as possible by eliminating things that were blocking them as my top priority. So there I was, being a team lead for a dev team building a new product, making sure everyone was able to get on, talking to stakeholders and running our sprint demos to ensure everyone inside and outside the project team understood how it was going and could play their part. Pleasingly we shipped a usable system in time for the deadline.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;experience-mentoring&quot;&gt;Experience mentoring&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve always helped everyone I can be the best they can, freely sharing knowledge with anyone who&#x27;s interested. Not just developers either, in my view the more non-technical roles know about the thing we&#x27;re all working on the more effective they can be.&lt;&#x2F;p&gt;
&lt;p&gt;I officially mentored DfE Digital&#x27;s first civil-servant developer which was a real pleasure. You can hear a bit more about that on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pod.timwise.co.uk&#x2F;10&quot;&gt;my podcast episode &quot;A retrospective of mentoring, with David Gisbey&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Well that was a lot more than I expected when I sat down to write, guess there&#x27;s a lot floating around my head after 21 years thinking, doing and learning.&lt;&#x2F;p&gt;
&lt;p&gt;Wish me luck, and I hope this helps you in some way.&lt;&#x2F;p&gt;
&lt;p&gt;If you want my help with a team just get in touch, I&#x27;m always happy to chat.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Technical phone screen interview questions</title>
        <published>2021-12-10T00:00:00+00:00</published>
        <updated>2021-12-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/12/10/technical-phone-screen-interview-questions/"/>
        <id>https://0x5.uk/2021/12/10/technical-phone-screen-interview-questions/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/12/10/technical-phone-screen-interview-questions/">&lt;p&gt;I was tasked with giving an initial assessment of technical competence &#x2F; fit in a 30 minute phone call.&lt;&#x2F;p&gt;
&lt;p&gt;This tech screen is based on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sites.google.com&#x2F;site&#x2F;steveyegge2&#x2F;five-essential-phone-screen-questions&quot;&gt;Steve Yegge’s &quot;The Five Essential Phone-Screen Questions&quot;&lt;&#x2F;a&gt;
My lightweight version goes something like this:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-coding&quot;&gt;1) Coding&lt;&#x2F;h2&gt;
&lt;p&gt;Ask them to describe the code for a console app that prints the ten-times table in a grid. This is intended to get them to describe a nested for loop, or maybe some fancier construct. It doesn’t matter if they nail it, you can tell if they understand how to code from how they talk about it. Bonus for whether they can understand a verbal description (possibly imperfectly described), and throw together a solution in their head.&lt;&#x2F;p&gt;
&lt;p&gt;This isn’t a substitute for an in-person pairing session, but it gives a quick indication whether they have a clue how to code.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s supposed to be something like this, which is remarkably hard to explain on the phone from my side (no points deducted for my inability to be clear!):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1	2	3	4	5	6	7	8	9	10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2	4	6	8	10	12	14	16	18	20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3	6	9	12	15	18	21	24	27	30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4	8	12	16	20	24	28	32	36	40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5	10	15	20	25	30	35	40	45	50&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6	12	18	24	30	36	42	48	54	60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7	14	21	28	35	42	49	56	63	70&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8	16	24	32	40	48	56	64	72	80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9	18	27	36	45	54	63	72	81	90&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10	20	30	40	50	60	70	80	90	100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;6aaf930fa97854584192faa9ca81e290&quot;&gt;gist&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-oo-design-and-other-structures&quot;&gt;2) OO design (and other structures)&lt;&#x2F;h2&gt;
&lt;p&gt;Ask them to describe how they can arrange their code, giving a hint that I’m after object oriented things. I’m looking for a confident off-hand description of inheritance, interfaces etc.&lt;&#x2F;p&gt;
&lt;p&gt;If they don’t fluff that, ask if they know non-OO approaches (composition, modules, mixins etc) that are used in languages other than C# to see how broad and deep their knowledge is.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;3-scripting-regex&quot;&gt;3) Scripting &amp;amp; Regex&lt;&#x2F;h2&gt;
&lt;p&gt;Context: It’s not uncommon for microsoft devs to never look outside the microsoft sandbox. This can result in someone spending week(s) writing a program to solve a problem that can be done with one linux command. Times are changing and Microsoft loves linux, but these narrow thinkers are best avoided. This question is almost pointless for ruby devs who live in unix land.&lt;&#x2F;p&gt;
&lt;p&gt;Question: you have a server with thousands of plain-text log files scattered across hundreds of folders and you need to find all the lines with a particular user-id in them to solve a production problem.&lt;&#x2F;p&gt;
&lt;p&gt;Good answer: &lt;code&gt;grep&lt;&#x2F;code&gt; (this means they know of unix tools, maybe probe how wide that is)
Bad answer: I’d start a new project in visual studio and use FileInfo classes…&lt;&#x2F;p&gt;
&lt;p&gt;Follow up question: what if you needed to find an identifier that matched a pattern but wasn’t always the same? (i.e. do they know about regex)&lt;&#x2F;p&gt;
&lt;p&gt;Great answer: I’d use &lt;code&gt;egrep&lt;&#x2F;code&gt; with a regex (or similar tools); goes on to explain a bunch of great tools I hadn’t heard of before&lt;&#x2F;p&gt;
&lt;p&gt;If they have other smart ways (e.g. they know about log aggregation tools like Kibana), guide them back to a limited toolset (“it’s a legacy system, you haven’t got any of that...”)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;4-data-structures&quot;&gt;4) Data Structures&lt;&#x2F;h2&gt;
&lt;p&gt;Do they know the difference between dictionaries and lists, particularly when it comes to speed of lookup.&lt;&#x2F;p&gt;
&lt;p&gt;Related: Do they know about &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bigocheatsheet.com&#x2F;&quot;&gt;algorithmic complexity&lt;&#x2F;a&gt; - this sorts the self-taughts from the computer-science degree crowd, but if you don’t know this stuff it’ll bite you sooner or later.&lt;&#x2F;p&gt;
&lt;p&gt;See if they are aware of the available structures.
See how clearly they can explain why you’d choose one over the other for a particular piece of code.
It doesn’t matter if they can recall the specifics, it just matters that they’d think to go and look up the specifics when they needed to decide.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;5-bits-and-bytes&quot;&gt;5) Bits and bytes&lt;&#x2F;h2&gt;
&lt;p&gt;Do they know why you don’t store money in floating point variables?&lt;&#x2F;p&gt;
&lt;p&gt;Great: use decimal instead because floating point cannot accurately represent decimal fractions and will give you rounding errors that upset the accountants and customers
Okay: always use decimals, but don’t really know why
Bad: I’d use a float for money&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;So that’s it for Steve’s list.&lt;&#x2F;p&gt;
&lt;p&gt;I also like to ask them how they feel about the following:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;6-testing&quot;&gt;6) Testing&lt;&#x2F;h2&gt;
&lt;p&gt;Are they militant about TDD? What do they think about BDD? Are they more pragmatic?&lt;&#x2F;p&gt;
&lt;p&gt;How do they think about why you write tests.&lt;&#x2F;p&gt;
&lt;p&gt;This isn’t likely to be make or break, but might indicate better or worse fit with a team and is good to know.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;7-agile&quot;&gt;7) Agile&lt;&#x2F;h2&gt;
&lt;p&gt;What kind of agile structures have they worked in. What did they think about it.&lt;&#x2F;p&gt;
&lt;p&gt;I’m looking for enthusiasm for the way the best agile teams operate, it doesn’t matter too much if it’s SCRUM or something else. Do they seem like they’d be adaptable? Would they push for better?&lt;&#x2F;p&gt;
&lt;p&gt;Have they worked on GDS style teams? (For gov work)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;assessment&quot;&gt;Assessment&lt;&#x2F;h2&gt;
&lt;p&gt;During the debrief I usually discuss at least some of the following areas, focussing on what seems to be the make or break points:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;skill &#x2F; knowledge level: architect &amp;amp; team lead &amp;gt; senior engineer &amp;gt; narrow senior engineer &amp;gt; competent &amp;gt; hand-holding needed &amp;gt; complete liability&lt;&#x2F;li&gt;
&lt;li&gt;communication style, ability to discuss piece of theoretical code&lt;&#x2F;li&gt;
&lt;li&gt;attitude towards tech (e.g. do they demand testing or are they more “pragmatic”)&lt;&#x2F;li&gt;
&lt;li&gt;attitude towards and organisational structures and approaches (i.e. scrum or GDS team structures)&lt;&#x2F;li&gt;
&lt;li&gt;how they would likely fit in with the intended team&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Some example outcomes of the technical assessment might be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Strong - knew everything, broad knowledge, could clearly do the job&lt;&#x2F;li&gt;
&lt;li&gt;Qualified positive - can probably build something within some boundaries, but you’d want a strong tech lead in charge to keep things on track&lt;&#x2F;li&gt;
&lt;li&gt;Weak - lacking knowledge of important areas of tech, failed to explain a good solution to a simple nested loop problem&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;bias-and-scoring&quot;&gt;Bias and scoring&lt;&#x2F;h2&gt;
&lt;p&gt;To minimize risk of bias sneaking in and giving me a &quot;favourite&quot; based on how similar they are to me rather than how well they did I like to do a written report scoring each area above.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Integrating ShipStation with QuickBooks Desktop</title>
        <published>2021-09-27T00:00:00+00:00</published>
        <updated>2021-09-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/09/27/integrating-shipstation-with-quickbooks-desktop/"/>
        <id>https://0x5.uk/2021/09/27/integrating-shipstation-with-quickbooks-desktop/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/09/27/integrating-shipstation-with-quickbooks-desktop/">&lt;p&gt;A possible customer of my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ecommerceintegrations.co.uk&#x2F;&quot;&gt;new eCommerce Integration
business&lt;&#x2F;a&gt; popped up with an interesting
problem: how to have orders that are entered into &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;quickbooks.intuit.com&#x2F;desktop&#x2F;&quot;&gt;QuickBooks
Desktop&lt;&#x2F;a&gt; automatically create matching
entries in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.shipstation.com&#x2F;&quot;&gt;ShipStation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;How can I get my orders from QuickBooks into ShipStation without my staff manually retyping them?&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;what-is-shipstation&quot;&gt;What is ShipStation?&lt;&#x2F;h2&gt;
&lt;p&gt;It is a one-stop order shipping interface for shipping your physical outbound
orders that can in turn talk to all the actual couriers so you don&#x27;t need to
deal with them individually. It connects to Royal Mail, Hermes, DPD etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;connecting-shipstation-to-quickbooks-desktop&quot;&gt;Connecting ShipStation to QuickBooks Desktop&lt;&#x2F;h2&gt;
&lt;p&gt;There isn&#x27;t a direct way of connecting them together, so that means we need
something to do the work of pulling orders out of QuickBooks and pushing them
into ShipStation.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s two pieces of software that can connect the two systems together:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;connex&quot;&gt;Connex&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.shipstation.com&#x2F;partners&#x2F;connex-quickbooks&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.shipstation.com&#x2F;partners&#x2F;connex-quickbooks&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.syncwithconnex.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.syncwithconnex.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Connex is a bit like Codeless BPA in that it enables a flow of orders, but specific to QuickBooks rather than having many connectors on both sides.&lt;&#x2F;li&gt;
&lt;li&gt;This page lists exactly what pieces of data will be transferred: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.syncwithconnex.com&#x2F;hc&#x2F;getting-started-with-shipstation&quot;&gt;https:&#x2F;&#x2F;help.syncwithconnex.com&#x2F;hc&#x2F;getting-started-with-shipstation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.shipstation.com&#x2F;hc&#x2F;en-us&#x2F;articles&#x2F;360026142191#UUID-b13db029-1f01-b9b8-52f3-71e0c4caa0be&quot;&gt;ShipStation help page on Connex for QuickBooks&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.syncwithconnex.com&#x2F;products-2&#x2F;&quot;&gt;base price for Connex is $199&#x2F;month&lt;&#x2F;a&gt; at time of writing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;codeless-bpa&quot;&gt;Codeless BPA&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.codelessplatforms.com&#x2F;business-process-automation-platform&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.codelessplatforms.com&#x2F;business-process-automation-platform&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Codeless has a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.codelessplatforms.com&#x2F;connectors&#x2F;shipstation-integration&#x2F;&quot;&gt;ShipStation connector&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;BPA Platform starts from £175&#x2F;month billed annually.&lt;&#x2F;li&gt;
&lt;li&gt;We&#x27;d need to do some investigation of the method of integrating QuickBooks Desktop with Codeless BPA.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;connex-versus-codeless&quot;&gt;Connex versus Codeless&lt;&#x2F;h2&gt;
&lt;p&gt;Both Codeless BPA and Connex have similar monthly costs, and both will need
setting up, so choosing which to go with is going to come down to which option
fits your businesses needs better now and in the longer term. Connex will solve
the immediate problem, but Codeless has more connections you can use in the
future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dbsync&quot;&gt;DBSync&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.mydbsync.com&#x2F;workflow&#x2F;shipstation-quickbooks-integration&quot;&gt;https:&#x2F;&#x2F;www.mydbsync.com&#x2F;workflow&#x2F;shipstation-quickbooks-integration&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Cloud and On-Premise offerings.&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Chat for pricing&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;unify-by-webgility&quot;&gt;Unify by Webgility&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;ShipStation integration: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.webgility.com&#x2F;integrations&#x2F;shipstation&quot;&gt;https:&#x2F;&#x2F;www.webgility.com&#x2F;integrations&#x2F;shipstation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;QuickBooks desktop integration: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.webgility.com&#x2F;integrations&#x2F;quickbooks&quot;&gt;https:&#x2F;&#x2F;www.webgility.com&#x2F;integrations&#x2F;quickbooks&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.webgility.com&#x2F;pricing&quot;&gt;From $39&#x2F;month billed annually&lt;&#x2F;a&gt; at time of writing.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.shipstation.com&#x2F;hc&#x2F;en-us&#x2F;articles&#x2F;360025856492-Unify-by-Webgility?queryID=2ab3382fc895786ba9cda0cfbc556a5b&quot;&gt;ShipStation integration help page&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;automate-io&quot;&gt;Automate.io&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;automate.io&#x2F;integration&#x2F;quickbooks&#x2F;shipstation&quot;&gt;https:&#x2F;&#x2F;automate.io&#x2F;integration&#x2F;quickbooks&#x2F;shipstation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;automate.io&#x2F;pricing&quot;&gt;From free to $159&#x2F;month&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;tradegecko-retired&quot;&gt;TradeGecko (retired)&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;This is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tradegecko.com&#x2F;sunset&quot;&gt;being retired&lt;&#x2F;a&gt;, but mentioned for completeness.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;support.tradegecko.com&#x2F;hc&#x2F;en-us&#x2F;articles&#x2F;201825933-ShipStation-Integration-Setup-Guide&quot;&gt;https:&#x2F;&#x2F;support.tradegecko.com&#x2F;hc&#x2F;en-us&#x2F;articles&#x2F;201825933-ShipStation-Integration-Setup-Guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;to-integrate-now-or-to-change-technology&quot;&gt;To integrate now, or to change technology?&lt;&#x2F;h2&gt;
&lt;p&gt;As everything moves to the cloud it&#x27;s worth considering whether to invest
further in your existing desktop-based technology choices, or to take the
opportunity to move to cloud based accounting and ERP systems before looking to
connect them together.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;get-in-touch&quot;&gt;Get in touch&lt;&#x2F;h2&gt;
&lt;p&gt;Did I miss an option? Let me know!&lt;&#x2F;p&gt;
&lt;p&gt;Can I help you or someone you know with something? Reach out!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The death of custom software development</title>
        <published>2021-08-18T00:00:00+00:00</published>
        <updated>2021-08-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/08/18/the-death-of-custom-software-development/"/>
        <id>https://0x5.uk/2021/08/18/the-death-of-custom-software-development/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/08/18/the-death-of-custom-software-development/">&lt;p&gt;I&#x27;ve been around this industry for a long time and have been quietly observing the bigger trends while I fiddle around with the details of software.
Here&#x27;s what I&#x27;ve noticed: writing software by hand is doomed. Expect that it isn&#x27;t, and it&#x27;s a bit more nuanced than that.&lt;&#x2F;p&gt;
&lt;p&gt;I think the industrial revolution and the creation and growth of engineering as a profession is a good way to think about the progression of the software profession in the large.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-long-view-the-birth-of-payroll-software&quot;&gt;The long view - the birth of payroll software&lt;&#x2F;h2&gt;
&lt;p&gt;A few years ago I decided to get a bit stronger (being your typically feeble software engineer at the time) and joined a Nuffield gym and took them up on their personal training options so that I wouldn&#x27;t injure myself picking up the first 1kg weight I found in the gym. The PT I got happened to be a lovely older chap named Bryan, who is a very calm and experienced trainer who really helped me build some useful real-world strength through the medium of increasingly heavy kettle-bells and other such devices, all without injury. Now obviously we got talking as we spent many hours on turning me into a proper human, and it turns out that Bryan used to work for the might HP (the computer company not the sauce) of all things, and was part of the software world for many years before I joined it amidst the dot-com mania. I have heard talk of people writing custom payroll systems in the past, but Bryan actually lived it and it was great hearing the stories. In many ways nothing much has changed; software engineers write custom software to solve some pressing business problem for the big businesses that can afford it, and everyone else gets by with bits of paper or whatever they can pull together. The software engineers complain about the hardware engineers, the hardware engineers complain about the software engineers, the sales people sell things that are expensive to do and the software engineers grumble and try and make good. There are fascinating stories of obscure bugs where you have to drill all the way down to the compiler or hardware to find the true source; the stuff of coder legends. All this was true then and is true now.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;That&#x27;s all very well&quot;, you say, but what&#x27;s that got to do with me? Well I think some of the systems Bryan worked on are illustrative of the geological shifts in software over the years, and are indicative of changes happening to this day and still to come.&lt;&#x2F;p&gt;
&lt;p&gt;In that era, there was no good off-the-shelf payroll software that could solve every business&#x27;s payroll needs, and every business needs to pay its staff. Doing it by hand is laborious and error prone which makes it a good candidate for turning into software. The in-house custom coding crowd got there first and made it work for big businesses that could afford development teams or the equivalent consultancy fees. Then vendors started to show up but there were edges that they couldn&#x27;t handle so there was still room for custom code, and now it would be [almost] madness to start a payroll software company (though you might find a way to disrupt the existing players like Sage, but it&#x27;s not going to be all green fields for the taking like it was back then).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-trend-of-commoditization-and-the-shrinking-need-for-custom-code&quot;&gt;The trend of commoditization and the shrinking need for custom code&lt;&#x2F;h2&gt;
&lt;p&gt;&quot;So what&quot;, you say, &quot;there&#x27;s still vast plains of untouched lands for software development, coding will never die! Coders unite!&quot;&lt;&#x2F;p&gt;
&lt;p&gt;As the really big universal problems are picked off one by one there is indeed still plenty of room, for now at least, for custom code.&lt;&#x2F;p&gt;
&lt;p&gt;(By big universal problems I mean things like: accounting, payroll, Enterprise Resource Planning aka ERP, development tooling, website creation, online payments, social media, buying and selling privately online, car-sharing, short-term property rentals, travel bookings, etc. etc.)&lt;&#x2F;p&gt;
&lt;p&gt;Some organisations will always think they are too special or have too much ego invested in rolling their own (not-invented-here syndrome) to buy an off the shelf options. This is inefficient, but will happen nonetheless if they want to pay for it.&lt;&#x2F;p&gt;
&lt;p&gt;There will always be innovation and disruption, which will require engineering effort. Even in the age-old physical realm of engineering such as building roads, bridges and buildings there continues to be innovation and a need for skilled highway and bridge engineers.&lt;&#x2F;p&gt;
&lt;p&gt;Undeniably, however, there are whole classes of problems that software is capable of solving that have already been solved (some better than others of course), and a market of off the shelf or open source software dominates each particular problem leaving little room for expensive one-off custom builds to solve the same problem again.&lt;&#x2F;p&gt;
&lt;p&gt;As each vendor gets better at solving the problem at hand (or gets disrupted when they fail to), more and more use cases that used to require custom code are served by off-the-shelf software eliminating the need for developer time and replacing it with more-or-less need for installation, setup and configuration expertise.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-end-game-for-software-development&quot;&gt;The end-game for software development&lt;&#x2F;h2&gt;
&lt;p&gt;In the very long run (maybe another 100 years?) I see us getting to a steady state much like exists in traditional physical engineering. There are no vast new uncharted problem spaces waiting to return billions of dollars just for being first to get there. There will still be the occasional disruption but we&#x27;ll look back on the dot-com boom in the late &#x27;90s just like we look back on the industrial revolution and the creation of railroads for the first time. We&#x27;ll still have railroads, and we&#x27;ll still have social media platforms and SaaS businesses; and sometimes one company will die and be replaced by others; but we won&#x27;t be awestruck by silicon valley&#x27;s ability to turn the world on it&#x27;s head any more. It will just be normal.&lt;&#x2F;p&gt;
&lt;p&gt;As for the software developers and their trade; they won&#x27;t go extinct, they&#x27;ll probably have the same job titles more or less. There will be more developers working for the SaaS companies, infrastructure companies and boxed software companies (locally installed software will never die), and less developers working for businesses that aren&#x27;t fundamentally software businesses. The latter will just buy the outputs of the software companies for far less than they would have had to pay a development team or outsourcer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;developer-salaries&quot;&gt;Developer salaries&lt;&#x2F;h2&gt;
&lt;p&gt;Companies that have money will always pay good money for good people, and software businesses serving worldwide business and consumer markets with software that costs nothing to replicate will always have plenty of money.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;shortage&quot; of software developers caused by the collapse in interest in computer science degrees after the dot-com bust combined with ever increasing production of software has already started to be mitigated as the &quot;boot camp&quot; model that has been running for a few years now at scale is starting to result in volumes of quality and sufficiently experienced engineers. This will push prices for the &quot;average&quot; developer down. In fact prices of the average developer haven&#x27;t really moved much in the last 20 years in spite of the effects of inflation eating away at the real value of that income. £50-60k is still a reasonable salary for an experienced engineer in an average job in the UK just like it has been for years, while house prices have rocketed up in that time.&lt;&#x2F;p&gt;
&lt;p&gt;So in the long run apart from people that can make themselves invaluable to the richest companies (which takes more than being able to write Python or C#) will still be well rewarded, but the days of exceptional salaries for anyone that can write a &lt;code&gt;for&lt;&#x2F;code&gt; loop let alone recursion are well behind us now.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-fractures-and-integrations-between-software&quot;&gt;The fractures and integrations between software&lt;&#x2F;h2&gt;
&lt;p&gt;An interesting effect of the ever-growing amount of coverage of off-the-shelf software and SaaS companies in the global problem-space of business is the rising challenges and expectations for making it all work together (often known as &quot;systems integration&quot;).&lt;&#x2F;p&gt;
&lt;p&gt;For sectors where there are many similar businesses (think plumbers, accountants, travel agents), the software vendors will produce solutions that cover everything that the profession needs all in one offering (marketing, finance tracking, invoicing, customer contact etc.). They can do this cost-effectively by selling the same thing repeatedly for near-zero marginal cost.&lt;&#x2F;p&gt;
&lt;p&gt;Bigger more complicated businesses, or more unique businesses are left trying to avoid building everything they need from scratch and instead trying to cobble together a complete solution for their business from all the various SaaS and on-site offerings that are out there.&lt;&#x2F;p&gt;
&lt;p&gt;As businesses put solutions in place for each problem they have to solve, they then start looking at how well these things are working together, and mostly discover that they aren&#x27;t. One SaaS thinks it has the answer to everything but is wrong, another on-site system thinks it owns the data about customers but the cloud-based CRM has got out of sync again and they keep upsetting customers by getting their facts wrong. So sometimes they just paper over the cracks with people based processes and spreadsheets. Sometimes they hire developers to try and glue systems together that really don&#x27;t want to be glued together (through the magic of dubious quality APIs or maybe direct SQL database access).&lt;&#x2F;p&gt;
&lt;p&gt;Some bits of software provide value as a standalone thing (e.g. document or chat tools), but even with those there&#x27;s a drive to integrate (e.g. single sign-on to avoid access for previous employees, auditing and storage for compliance etc). Other bits of software are very painful to leave disconnected (e.g. a storefront in Magento where customers purchase goods and an inventory ordering&#x2F;management (ERP) system in SAP Business One that makes sure there&#x27;s anything to ship).&lt;&#x2F;p&gt;
&lt;p&gt;To solve this latest self-inflicted pain of the software world a whole new class of software has emerged who&#x27;s only job is to join systems together that don&#x27;t know how to connect directly, or to act as an orchestrator of all the flows of data. You might have seen IFTTT (If This Then That) which is the consumer-centric version of this where you can make any number of events in one SaaS trigger actions elsewhere. Another is Business Process Automation (BPA) such as Codeless BPA which connect all sorts of enterprise software together by hook or by crook, while giving a central place to manage the flow of data and massage and monitor it on the way through as needed.&lt;&#x2F;p&gt;
&lt;p&gt;But even &lt;em&gt;that&lt;&#x2F;em&gt; extra layer of connection still doesn&#x27;t always give us the magical point and click connection we were promised decades ago where you can make your whole business work without talking to any nerds. For simpler cases you might get lucky, but as soon as you have to make a web hook work many people just glaze over and reach for the phone. And if something stops working between two bits of software that don&#x27;t really like each other, and your business&#x27;s whole income depends on that data flow, you&#x27;re going to do whatever it takes to make it behave again. So in a slightly different shape we find ourselves yet again in need of a vast army of technical folks who really know what&#x27;s going on and how to work the magic to make the wheels turn again and the ones and zeros flow like a spring down a mountain-side.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;service-buses-and-event-sourcing&quot;&gt;Service buses and event sourcing&lt;&#x2F;h2&gt;
&lt;p&gt;One of my tech friends mentioned this (very technical) approach to solving the pains.  This is a really good point, as you can get better more scalable, more fault tolerant and more responsive systems with these approaches. The move to this approach is however contingent on either the vendors playing ball, or on your systems being sufficiently hand-coded already that you can make these kinds of architectural improvements. YMMV as they say. An interesting aside that&#x27;s worth being aware of and considering. I won&#x27;t go into what they are here as there&#x27;s tons of content out there on this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ai-artificial-intelligence-and-machine-learning-ml&quot;&gt;AI (Artificial Intelligence) and Machine Learning (ML)&lt;&#x2F;h2&gt;
&lt;p&gt;A hot topic of the day is AI and ML. These are growth areas for good reason as they can eliminate whole swathes of formerly labour intensive work, but personally I don&#x27;t see programming in any meaningful sense as being one of them. I might be a bit biased of course. If anything this is likely to spawn yet more need for highly capably technical folks to build and integrate these new systems, regardless of where the boundaries of each system sits.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-new-consultancy&quot;&gt;A new consultancy&lt;&#x2F;h2&gt;
&lt;p&gt;Yes there was a reason I was even thinking about this, let alone writing it down, but this isn&#x27;t really a pitch; I genuinely find this stuff interesting to think and write about.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m building a new systems integration business off the back of my experience in tech, so if that&#x27;s relevant to you drop me an email &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;mailto:tim@timwise.co.uk&lt;&#x2F;a&gt; and let&#x27;s talk. I&#x27;m looking to build my network of people who I&#x2F;we can help, and also my network of people who might want to be involved in the new business.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-penny-for-your-thoughts&quot;&gt;A penny for your thoughts&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;d love to talk to you &lt;em&gt;on an actual phone call&lt;&#x2F;em&gt; if you thought this was interesting or relevant (or wrong or silly!)&lt;&#x2F;p&gt;
&lt;p&gt;Drop me a line on &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;mailto:tim@timwise.co.uk&lt;&#x2F;a&gt; and arrange a call!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;footnotes&quot;&gt;Footnotes&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;many-names-of-non-custom-software&quot;&gt;Many names of non-custom software&lt;&#x2F;h3&gt;
&lt;p&gt;Sometimes you may hear software referred to as COTS, which is short for &quot;Commercial Off The Shelf&quot; software, or &quot;boxed software&quot;. These days you might call that codeless, no-code or low-code. Or maybe &quot;apps&quot;. The point here is that you don&#x27;t have to pay developers to solve a problem (which is expensive, slow and error prone - good for developers paid for their time and skills, not so good for the business paying the bill).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why I want you to use slack threads</title>
        <published>2021-07-08T00:00:00+00:00</published>
        <updated>2021-07-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/07/08/why-i-want-you-to-use-slack-threads/"/>
        <id>https://0x5.uk/2021/07/08/why-i-want-you-to-use-slack-threads/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/07/08/why-i-want-you-to-use-slack-threads/">&lt;p&gt;Someone has probably sent you a link to this blog post in response to you posting multiple messages in a slack channel on the same topic.&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t worry, we&#x27;re not angry with you, we just want to help. We also know that the slack interface can be a bit confusing, especially on mobile, and it&#x27;s easy to accidentally respond in channel instead on a thread.&lt;&#x2F;p&gt;
&lt;p&gt;This post is not intended to shame or berate you, just to share information on how we can all make slack a nicer and less distracting thing to use for everyone.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;slack-two-channel-messages.png&quot; alt=&quot;two messages in a slack channel&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The above screenshot is an example of two consecutive messages in slack, this happens if you send the message in two parts. (Send one message, think of something extra, send another message.)&lt;&#x2F;p&gt;
&lt;p&gt;This post is here to explain to you with kindness why posting multiple messages like this might be causing issues for other people and offer some alternate approaches.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-multiple-messages-are-a-problem-for-others&quot;&gt;Why multiple messages are a problem for others&lt;&#x2F;h2&gt;
&lt;p&gt;It seems harmless to just post another couple of messages, right?&lt;&#x2F;p&gt;
&lt;p&gt;Slack in any active organisation can quickly become a firehose of information that can be quite hard to keep up with. It takes some effort from all involved to protect everyone&#x27;s focus and flow time. As an aside if you want an insight into just how damaging distractions can be I recommend diving into Cal Newport&#x27;s writings &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.calnewport.com&#x2F;books&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.calnewport.com&#x2F;books&#x2F;&lt;&#x2F;a&gt;, particularly &quot;Deep Work&quot;. Some of us have the luxury of turning off slack for most of the day, but some people need to keep up more actively than that.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;notifications-and-unread-messages&quot;&gt;Notifications and unread messages&lt;&#x2F;h3&gt;
&lt;p&gt;Slack allows you to carefully manage what notifications you receive, but for a channel it basically comes down to notifications on or off for channel messages.&lt;&#x2F;p&gt;
&lt;p&gt;If you have a channel that you want (or need) to keep up to date with in a timely manner then when someone sends a new channel message you will have intrusive notifications and as shown below an &quot;unread channel&quot; in bold-and-white sat glaring at you waiting to be read:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;slack-unread-channel.png&quot; alt=&quot;unread slack channel&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you use the convenient &quot;All unread&quot; feature then that will also sit glaring at you as below with an eye-catching &quot;1 new message&quot; button until you go and look:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;slack-unread.png&quot; alt=&quot;unread messages&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The problem with multiple related channel messages in this case is that if someone gets your first message, decides that it&#x27;s not a conversation relevant to them and then goes back to trying to concentrate your second message will set off all their notifications once again and send them back to having unread messages to worry about.&lt;&#x2F;p&gt;
&lt;p&gt;If you had instead used the below alternatives of editing or threads then there would be no new notifications and no new unread messages when you edit your message or add to the thread.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deciding-what-conversations-to-follow&quot;&gt;Deciding what conversations to follow&lt;&#x2F;h3&gt;
&lt;p&gt;As someone who is trying to avoid slack-overwhelm the ability to follow and unfollow threads is a very useful feature. Slack will automatically give new notifications for threads where you have been mentioned with an &lt;code&gt;@&lt;&#x2F;code&gt; or have added a message of your own to the thread.&lt;&#x2F;p&gt;
&lt;p&gt;To follow&#x2F;unfollow a thread, hover over the top message in the thread, click the dots, and click &quot;turn off notifications for replied&quot; as shown below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;unfollow-thread.png&quot; alt=&quot;unfollowing a thread&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If people are not correctly using threads to group themes of discussion then this feature becomes mostly useless.&lt;&#x2F;p&gt;
&lt;p&gt;As an aside this applies just as much to failure to start a new thread when the discussion changes topic as it does to failing to use threads in the first place.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;catching-up-with-a-channel&quot;&gt;Catching up with a channel&lt;&#x2F;h3&gt;
&lt;p&gt;Sometimes you will join a channel and then mute it (right-click, mute) because you want to be able to keep up to date on your own schedule, say daily or weekly.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;mute-channel.png&quot; alt=&quot;muting a channel&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When people in the channel have conversations in the form of channel messages you can easily end up having to read 1000 messages to just know what&#x27;s been going on for a day and catch up on anything important.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;new-messages.png&quot; alt=&quot;new messages bar&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If instead the people in the channel are disciplined in using threads then it can easily be down to 20 messages with some very long threads that you can dive into if you feel the need.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-you-can-do-instead&quot;&gt;What you can do instead&lt;&#x2F;h2&gt;
&lt;p&gt;By using the following methods you can help everyone else in your slack channel make better use of their time, more easily follow relevant conversations, and have fewer distracting FOMO moments (Fear Of Missing Out).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;start-a-thread&quot;&gt;Start a thread&lt;&#x2F;h3&gt;
&lt;p&gt;Start a thread on your own message and add more messages in there:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;start-slack-thread.png&quot; alt=&quot;screenshot of starting a thread in slack&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This allows you to add further context etc for those interested without writing a massive message in one go directly in the channel or creating a string of independent channel messages.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;reply-to-own-thread.png&quot; alt=&quot;replying to your own thread&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;slack.com&#x2F;intl&#x2F;en-gb&#x2F;help&#x2F;articles&#x2F;115000769927-Use-threads-to-organise-discussions-&quot;&gt;https:&#x2F;&#x2F;slack.com&#x2F;intl&#x2F;en-gb&#x2F;help&#x2F;articles&#x2F;115000769927-Use-threads-to-organise-discussions-&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;edit-your-existing-message&quot;&gt;Edit your existing message&lt;&#x2F;h3&gt;
&lt;p&gt;Did you just forget to mention something? You can edit the message you&#x27;ve already posted to make corrections or add more information.&lt;&#x2F;p&gt;
&lt;p&gt;Hover over the message and then press the &quot;more actions&quot; dots:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;slack-more-actions.png&quot; alt=&quot;more actions dots&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;slack-edit-message.png&quot; alt=&quot;edit message menu&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;slack.com&#x2F;intl&#x2F;en-gb&#x2F;help&#x2F;articles&#x2F;202395258-Edit-or-delete-messages&quot;&gt;https:&#x2F;&#x2F;slack.com&#x2F;intl&#x2F;en-gb&#x2F;help&#x2F;articles&#x2F;202395258-Edit-or-delete-messages&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;delete-your-subsequent-messages&quot;&gt;Delete your subsequent messages&lt;&#x2F;h3&gt;
&lt;p&gt;If you&#x27;ve already posted more than one channel message and then realise your mistake, you can delete the extra messages before converting to a thread or edit, leaving the channel nice and tidy for anyone who shows up later to read.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;delete-message.png&quot; alt=&quot;delete message&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is particularly important to avoid ending up with multiple threads on different channel messages (on the same topic) as other people reply to different bits of your message resulting in confusion and a disjointed conversation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;multiple-threads.png&quot; alt=&quot;multiple threads&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;slack.com&#x2F;intl&#x2F;en-gb&#x2F;help&#x2F;articles&#x2F;202395258-Edit-or-delete-messages&quot;&gt;https:&#x2F;&#x2F;slack.com&#x2F;intl&#x2F;en-gb&#x2F;help&#x2F;articles&#x2F;202395258-Edit-or-delete-messages&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;offering-gentle-reminders-with-an-emoji&quot;&gt;Offering gentle reminders with an emoji&lt;&#x2F;h2&gt;
&lt;p&gt;If your team knows to do this but forgets sometimes then add &lt;code&gt;:start_a_thread:&lt;&#x2F;code&gt; as an emoji (under &quot;customize workspace) to easily remind people when they forget.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;start_a_thread.gif&quot; alt=&quot;reply in thread animation gif&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(Thread gif image source: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;slackmojis.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;slackmojis.com&#x2F;&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;slack&#x2F;customize.png&quot; alt=&quot;customize slack&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;So in summary, please give a thought to others before you send a second message. It may be quick for you but if there are 50 people in the slack room then you are costing them much more time and attention than it saves you by not taking the time to construct a clean message or thread.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;EqualExperts&#x2F;slack-guide?tab=readme-ov-file#using-threads&quot;&gt;Equal Experts&#x27; slack guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GitHub rebase and squash considered harmful</title>
        <published>2021-03-15T00:00:00+00:00</published>
        <updated>2021-03-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/03/15/github-rebase-and-squash-considered-harmful/"/>
        <id>https://0x5.uk/2021/03/15/github-rebase-and-squash-considered-harmful/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/03/15/github-rebase-and-squash-considered-harmful/">&lt;p&gt;Not to be confused with &lt;code&gt;git rebase&lt;&#x2F;code&gt; and the ability to squash commits locally with interactive rebase, which is &lt;a href=&quot;&#x2F;2019&#x2F;10&#x2F;14&#x2F;merge-vs-rebase&#x2F;&quot;&gt;a whole other flamewar&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;github-squash-evil.png&quot; alt=&quot;Screenshot of github&amp;#39;s three PR merge options&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This post is predicated on giving a crap about the git history you and your team produce. If you don&#x27;t care about good quality git history then you are wrong because &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;timwise.co.uk&#x2F;2016&#x2F;03&#x2F;18&#x2F;yet-another-good-commit-messages-post&#x2F;&quot;&gt;git history is an important aspect of your engineering output&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In short, &quot;squash and merge&quot; is never good, &quot;rebase and merge&quot; is almost never good, &quot;create a merge commit&quot; is a good default, ... and if you have a really great team then mainlining while pairing&#x2F;mobbing can be great for mean-time-to-recovery but shouldn&#x27;t be the only allowed way.&lt;&#x2F;p&gt;
&lt;p&gt;If you don&#x27;t believe me yet, then let us now go reaaaally deep on all the details of all the ways you can do this and what makes them so good&#x2F;bad&#x2F;evil:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rebase-squash-and-merge-both-bad&quot;&gt;&quot;Rebase&#x2F;Squash and merge&quot; - both bad&lt;&#x2F;h2&gt;
&lt;p&gt;Personally I dislike the &quot;&lt;strong&gt;rebase&lt;&#x2F;strong&gt;&quot; and &quot;&lt;strong&gt;squash&lt;&#x2F;strong&gt;&quot; buttons on GitHub because:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You don&#x27;t find out what you actually put in &lt;code&gt;main&lt;&#x2F;code&gt; until after it&#x27;s done. If you don&#x27;t believe me check the sha1 of the tip of your PR branch with the new tip of &lt;code&gt;main&lt;&#x2F;code&gt;, your sha1 is nowhere to be seen. Github then has the gall to sign the commits as you if you&#x27;ve let it.&lt;&#x2F;li&gt;
&lt;li&gt;There is no record of which commit you based your branch on, so if there&#x27;s a new incompatibility because &lt;code&gt;main&lt;&#x2F;code&gt; has moved on there is no record of what commit your branch was based on to assist with figuring out where the problem was introduced, it just looks like a bad patch to main with a PR that could never have worked.&lt;&#x2F;li&gt;
&lt;li&gt;The generated commits lose the true commit metadata generated locally (authorship, timestamps, sha-1).&lt;&#x2F;li&gt;
&lt;li&gt;GitHub generates brand new commit(s) at the point of applying to &lt;code&gt;main&lt;&#x2F;code&gt; with no chance to review first.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These two options behave in ways that are not immediately obvious (to be fair github improved the labels on the options after I first ranted about this, but it doesn&#x27;t change the fundamental issues). And if you press one of them without realising what it&#x27;s going to do, tough because it&#x27;s already in &lt;code&gt;main&lt;&#x2F;code&gt;, and if you have branch protection on (you  probably should) then you can&#x27;t even undo it; it&#x27;s there foreeeeeeeever.&lt;&#x2F;p&gt;
&lt;p&gt;Someone reviewing your PR has no idea which of these three buttons you will push, which could have been the difference between approving (based on a tidy merge and nice branch history) and rejecting a PR (based on including junk history or a badly worded squash commit).&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s dive in to the hell that github have created for us:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;squash-and-merge-pure-evil&quot;&gt;&quot;Squash and merge&quot; - pure evil&lt;&#x2F;h3&gt;
&lt;p&gt;This one takes all your carefully crafted commits (or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;xkcd.com&#x2F;1296&#x2F;&quot;&gt;pile of &quot;wip&quot; junk&lt;&#x2F;a&gt; if you are lazy or plan to squash) and combines them into a single commit, pausing to allow you to write a better commit message (which few people I&#x27;ve worked with bother to actually do, immortalizing &quot;* wip&quot; in the history forever) and then pushing it to &lt;code&gt;main&lt;&#x2F;code&gt; without further opportunity to review what you are shipping.&lt;&#x2F;p&gt;
&lt;p&gt;The behaviour this option encourages, nay, mandates, is to create gigantic 100-file patches that make your eyes bleed to read, basically making &lt;code&gt;git blame&lt;&#x2F;code&gt; useless beyond knowing who to hate.&lt;&#x2F;p&gt;
&lt;p&gt;Anyone who tries to create many small meaningful and logically coherent patches but who has to use this option has the faustian bargain of choosing between making their team review piles of small PRs (too much overhead) or generating one stinking commit in &lt;code&gt;main&lt;&#x2F;code&gt; with all carefully crafted iterations lost to oblivion (for example commit 1: refactor everything, commit 2: make important one-line business change, commit to main: both at once, argh).&lt;&#x2F;p&gt;
&lt;p&gt;Note that github alters your original commit message to retro-fit PR numbers. Also evil.&lt;&#x2F;p&gt;
&lt;p&gt;If you make a change to a file that results in both renaming and modifying files such as a rename-refactor, you can make that easier to follow by doing it in two commits... unless you squash them together. This is exacerbated by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;7938582&#x2F;how-does-git-detect-similar-files-for-its-rename-detection&quot;&gt;git&#x27;s rename detection&lt;&#x2F;a&gt; which is actually not stored at all, but instead done as a heuristic when viewing patches. If you split the file name change and contents change into two patches you can help a future reader follow what you did, but if you change a file too much and then squash it all together then git will treat it as add and delete, breaking the ability to follow a line of code back through history without even more detective work and guessing.&lt;&#x2F;p&gt;
&lt;p&gt;I have nothing good to say about the &quot;Squash and merge&quot; option. If you don&#x27;t want to see the messy branches of your developers &lt;strong&gt;then use &lt;code&gt;--first-parent&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;. This option in github solves a non-problem and just makes everything worse. Anyone who thinks this option has any merit is wrong.&lt;&#x2F;p&gt;
&lt;p&gt;If an individual developer wants to create a single squashed commit for &lt;code&gt;main&lt;&#x2F;code&gt; &lt;strong&gt;they should squash locally and PR that&lt;&#x2F;strong&gt;. This option adds precisely nothing to what is possible, encourages reviewing and shipping junk history and encourages bad behaviour and unreadable patches. If you think it annoys me you&#x27;re right, it should never have been created. It enables shit developers to carry on being shit and generate less &quot;noise&quot; in the history. Why would you want a process that only exists to to take the edge off being around the worst developers?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rebase-and-merge-99-awful&quot;&gt;&quot;Rebase and merge&quot; - 99% awful&lt;&#x2F;h3&gt;
&lt;p&gt;This option takes your commits, rebases them on &lt;code&gt;main&lt;&#x2F;code&gt; and then fast-forwards main to the new top commit.&lt;&#x2F;p&gt;
&lt;p&gt;When this option has been used you can no longer tell by looking at the git history that there was ever a PR, which is actually useful context when looking back to work out why the hell something is how it is. (If you look at the commits in github it does magically show the PR number but you can&#x27;t find that context any other way.)&lt;&#x2F;p&gt;
&lt;p&gt;This option is marginally less offensive to me if used judiciously by skilled teams. You might sensibly use it because your PR was only for peer review rather than because your commits deserve a logical grouping. If you can trust your team to intelligently decide when the commits in a PR would look nice as straight-line history in &lt;code&gt;main&lt;&#x2F;code&gt; then perhaps leave this option available.&lt;&#x2F;p&gt;
&lt;p&gt;If you want your github workflow fool-proof and &quot;scalable&quot; then disable this option. Noobs will find this button and push it for the wrong reasons and give you a shit git history.&lt;&#x2F;p&gt;
&lt;p&gt;The upside of being clever occasionally is outweighed in my experience by the beautiful consistency of everything coming in as &quot;merge PR NNN for feature YYY&quot; and then being able to either ignore the details of the branch with &lt;code&gt;--first-parent&lt;&#x2F;code&gt; (which you can&#x27;t do if someone has used this button), or look at the commits in that PR as a logical group on the second-parent side when you need more granularity (easily done by running a first-parent log on the last commit of the branch before it was merged).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-a-merge-commit-aka-github-flow-good&quot;&gt;&quot;Create a merge commit&quot; aka &quot;github flow&quot; - good&lt;&#x2F;h2&gt;
&lt;p&gt;My preferred workflow is to use the normal &quot;merge&quot; button every time. This is sometimes know as &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;guides.github.com&#x2F;introduction&#x2F;flow&#x2F;&quot;&gt;GitHub Flow&lt;&#x2F;a&gt;&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;In my view you should generate your commits, sha-1 and all, exactly as they will be merged into &lt;code&gt;main&lt;&#x2F;code&gt;, and then as a separate merge commit those should be combined into &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To avoid many &quot;tramlines&quot; do local rebases to avoid PR branches being based on very outdated &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This retains the commit exactly as you crafted it locally.&lt;&#x2F;li&gt;
&lt;li&gt;It calls out the difference between you writing your commit and deciding it can go into &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;It retains the information about which commit you based your branch on.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There&#x27;s something to be said for being able to do a &lt;code&gt;git log --first-parent origin&#x2F;main&lt;&#x2F;code&gt; and get a consistent list of merged PR branches. It&#x27;s really quite readable compared to a mishmash of the different styles of merge to &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can configure GitHub to disallow the other options if your team are on-board with the idea.&lt;&#x2F;p&gt;
&lt;p&gt;You could argue that single commit PRs are a lot of overhead for something trivial, but equally having to decide each time results in more time worrying about whether something justifies the special treatment of ending up directly on main (in GitHub&#x27;s modified form), and getting it wrong sometimes.&lt;&#x2F;p&gt;
&lt;p&gt;If your PR branches are full of &quot;wip&quot;, &quot;fix tests&quot; and other junk then the answer is not to throw this option out, the answer is to &lt;strong&gt;get better at creating good patch sets&lt;&#x2F;strong&gt; by learning to use &lt;code&gt;git rebase --interactive&lt;&#x2F;code&gt; and thinking harder about what would make good patch before you start typing in your IDE. (And noticing when your patch is getting messy and stopping to reflect on good patch generation).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m aware there are counter-arguments, but in my experience on many teams this seems to end up being the cleanest balance of trade-offs. If you are an individual developer on your own project then pure mainline development can make more sense, though even then thinking of feature branches and having them explicitly merged where appropriate can neatly group related commits. The only compelling argument I&#x27;ve heard against this flow is mean-time-to-fix, but that doesn&#x27;t mean you have to kill this approach entirely, just be able to use other approaches too.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-my-interface-can-t-do-first-parent&quot;&gt;But my interface can&#x27;t do first-parent!&lt;&#x2F;h2&gt;
&lt;p&gt;Someone once complained at me that we shouldn&#x27;t do merge commits because they make no sense when viewed in github&#x27;s deficient history viewer, which shows a random mishmash of mainline and branch commits with no indication of which is which.&lt;&#x2F;p&gt;
&lt;p&gt;Seriously, use a better git viewer, there are literally thousands.&lt;&#x2F;p&gt;
&lt;p&gt;It 100% sucks that github, the flagship platform for git, still to this day does not have a proper branch view let alone first-parent view. Appalling. I&#x27;m even more horrified that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;desktop&#x2F;desktop&#x2F;issues&#x2F;1634&quot;&gt;GitHub desktop&lt;&#x2F;a&gt; has inherited this idiotic denial of branch based views. If the view of history &#x2F; PRs in github doesn&#x27;t show you what you need &lt;strong&gt;don&#x27;t use it&lt;&#x2F;strong&gt;. Did you know you can review PRs by just pulling down the branch and looking at it locally? You are a capable programmer who uses many tools not an idiot that needs to be spoonfed powerpoint presentations.&lt;&#x2F;p&gt;
&lt;p&gt;Even visual studio can show you branches, merges and first-parent views, it&#x27;s just a little tricky to find because they insisted on calling everything by different names and using mystery-meat buttons.&lt;&#x2F;p&gt;
&lt;p&gt;Sorry, but I don&#x27;t have much sympathy with the &quot;my tool is shit so we should do a worse job&quot; complaint against doing things properly, it&#x27;s weak.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-case-against-prs&quot;&gt;The case against PRs&lt;&#x2F;h2&gt;
&lt;p&gt;The only team I have ever come across that (incorrectly) disabled the &quot;create a merge commit&quot; option did so (I believe) in the name of &quot;mean-time-to-recovery&quot;. This is however a false dichotomy.&lt;&#x2F;p&gt;
&lt;p&gt;If you want fast &quot;mean time to recovery&quot; (MTTR) you need to be able to ship a patch to &lt;code&gt;main&lt;&#x2F;code&gt; and on to production fast. There is nothing about the &lt;em&gt;ability&lt;&#x2F;em&gt; to create merge commits or use PRs that prevents that. So long as you don&#x27;t enable the &quot;require a PR&quot; option in github, there&#x27;s nothing to stop a team pushing straight to &lt;code&gt;main&lt;&#x2F;code&gt; when that&#x27;s the right thing to do.&lt;&#x2F;p&gt;
&lt;p&gt;I like the idea that the requirement is not a pull request, but just two pairs of eyes on everything. That gives you the ability to be more responsive as pairs can now ship straight to production. That said, &lt;a href=&quot;&#x2F;2024&#x2F;04&#x2F;18&#x2F;trunk-based-development-is-wrong&#x2F;&quot;&gt;I just don&#x27;t buy the idea of &quot;mainline development&quot; for every patch&lt;&#x2F;a&gt;. Some changes are just more complicated than a single patch and it&#x27;s good to be able to break things down in a branch before merging. Don&#x27;t get me wrong, I&#x27;m all for pulling groundwork out and mainlining it (if your dev team is good enough to do this) so that your final patch is smaller, but sometimes a feature change has to go in in one commit to &lt;code&gt;main&lt;&#x2F;code&gt;, and without a branch plus a merge commit to main it is just not granular enough to make a useful history. And no, feature flags will not fix this for you, they are a useful thing for sure, and can reduce the size of unmerged branches, but sometimes you just have to change fundamental things that can&#x27;t be &quot;flagged&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Team culture is worth considering, regardless of tool configuration. If your team does everything by PR then when something is on fire they&#x27;ll probably raise a PR and then sit around waiting for approval; and if your team always commits everything to main as they go they&#x27;ll recover fast but their history will be full of mis-steps and fixups that could have been dealt with before they ever hit main. As always extremes are bad and anyone who fast-talks you into believing one extreme is a panacea is glossing over important nuance and interesting counter-examples.&lt;&#x2F;p&gt;
&lt;p&gt;Disabling merge commits doesn&#x27;t prevent people from having slow PR based async processes, and equally, enabling merge commits and PRs doesn&#x27;t stop you shipping a quick patch by pushing straight to main when something&#x27;s on fire. The two things are orthogonal.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-review-part-of-pr&quot;&gt;The Review part of PR&lt;&#x2F;h2&gt;
&lt;p&gt;The existence of a Pull Request implies a review by another developer before merging to &lt;code&gt;main&lt;&#x2F;code&gt;. The series of commits, including their summary, description, author and gpg signature is something that we can review and provide feedback on as part of the review process in order to provide a high quality history for those that need to understand why code is how it is, sometimes years in the future.&lt;&#x2F;p&gt;
&lt;p&gt;I have personally heard many developers say &quot;Don&#x27;t worry about the crappy history I&#x27;m going to squash it&quot;. Note the future tense in here. So the reviewer is supposed to just approved the awful &quot;wip&quot; history, or ignore it entirely, and trust that the person that does the merge will pick the right button and generate a sane commit to main.&lt;&#x2F;p&gt;
&lt;p&gt;The branch history in the PR that was reviewed and approved is then thrown away and something completely different goes in to main without any opportunity for the reviewer to object or comment.&lt;&#x2F;p&gt;
&lt;p&gt;What is the point of reviewing something and then committing something completely different to &lt;code&gt;main&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;The generated history does have value, should be of good quality, and peer-review is an important part of keeping that quality high.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;perfection&quot;&gt;Perfection?&lt;&#x2F;h2&gt;
&lt;p&gt;So what&#x27;s the ideal? In my view it&#x27;s the one of the following depending on the quality of your team and what your goals are:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;high-performing-team-with-top-end-developers-reducing-mean-time-to-fix&quot;&gt;High performing team with top-end developers - reducing mean-time-to-fix&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Two pairs of eyes rule.&lt;&#x2F;li&gt;
&lt;li&gt;Don&#x27;t disable anything, just educate and trust
&lt;ul&gt;
&lt;li&gt;(... apart from branch protection to avoid force-push to main because forward-only is good)&lt;&#x2F;li&gt;
&lt;li&gt;(...... and you can probably tell I wouldn&#x27;t mind if you did disable squash and perhaps rebase given the above ranting).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Use judgement for when to pair, mainline, PR etc.&lt;&#x2F;li&gt;
&lt;li&gt;Practice all approaches so that team is used to fast fixes.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Trust your team to use the right tool in the right moment. Big hairy feature? Break it down, use PRs if useful, ship as a merge commit with nice history and link to story and PR. Production on fire? Pair&#x2F;mob and mainline that sucker.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mediocre-mixed-team-avoiding-breakages-over-fast-fix&quot;&gt;Mediocre &#x2F; mixed team, avoiding breakages over fast-fix&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Require PR for all changes.&lt;&#x2F;li&gt;
&lt;li&gt;Disable everything but &quot;create merge commit&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Review PRs for quality of commit list and require rewriting branch history till it&#x27;s up to team standards before merging.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Link your outlook calendar with your google calendar</title>
        <published>2021-03-11T00:00:00+00:00</published>
        <updated>2021-03-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/03/11/link-outlook-calendar-with-google/"/>
        <id>https://0x5.uk/2021/03/11/link-outlook-calendar-with-google/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/03/11/link-outlook-calendar-with-google/">&lt;p&gt;If you have a Google&#x2F;GSuite calendar and a Microsoft Teams&#x2F;Office365&#x2F;Outlook calendar you can get the Microsoft Outlook calendar to pull in all the events from your Google calendar which is handy when you want to know if you have any gaps or conflicts.&lt;&#x2F;p&gt;
&lt;p&gt;Amazingly if you move google entries around in the outlook calendar they changes are pushed back to the google calendar.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;link-the-google-calendar-into-the-outlook-calendar&quot;&gt;Link the Google calendar into the Outlook calendar&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Go to your Teams calendar&lt;&#x2F;li&gt;
&lt;li&gt;Click the &quot;add calendar&quot; button&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;images&#x2F;blog&#x2F;google-teams-calendar&#x2F;1-add-cal.png&quot;&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;google-teams-calendar&#x2F;1-add-cal.png&quot; alt=&quot;Linked calendar with add button&quot; &#x2F;&gt;&lt;&#x2F;a&gt;
Here you can see the &quot;Add calendar&quot; button as well as the end result of showing the two calendars together (google in red, outlook in blue)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Click &quot;Add personal calendars&quot; and follow the instructions. The below shows the result. (The calendar defaults to blue but we can change that).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;images&#x2F;blog&#x2F;google-teams-calendar&#x2F;2-connect-to-google.png&quot;&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;google-teams-calendar&#x2F;2-connect-to-google.png&quot; alt=&quot;Add personal calendar screen&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;give-the-google-calendar-a-different-colour&quot;&gt;Give the Google calendar a different colour&lt;&#x2F;h2&gt;
&lt;p&gt;You can then give the calendar a different colour in &quot;Edit my calendars&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;images&#x2F;blog&#x2F;google-teams-calendar&#x2F;3-change-colour.png&quot;&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;google-teams-calendar&#x2F;3-change-colour.png&quot; alt=&quot;Edit calendar colour screen&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>House buying and selling tip - make contact!</title>
        <published>2021-03-04T00:00:00+00:00</published>
        <updated>2021-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/03/04/house-buying-and-selling-tip-make-contact/"/>
        <id>https://0x5.uk/2021/03/04/house-buying-and-selling-tip-make-contact/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/03/04/house-buying-and-selling-tip-make-contact/">&lt;p&gt;I&#x27;ve learned a useful trick as part of buying and selling house(s) that I want to share with you just in case you find it useful. It could save you months of stress and delay, and maybe even save a deal that was going to fail.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-big-secret&quot;&gt;The big secret&lt;&#x2F;h2&gt;
&lt;p&gt;Establish direct contact with the buyer&#x2F;seller.&lt;&#x2F;p&gt;
&lt;p&gt;This will allow you to co-ordinate on making the sale happen and spot anywhere that the chain of communication has broken down. (E.g. both solicitors waiting for each other and a message between them that has vanished into the ether).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-how&quot;&gt;But how?&lt;&#x2F;h2&gt;
&lt;p&gt;This should be easy, but estate agents don&#x27;t want you to go round them, and solicitors won&#x27;t necessarily pass on your request. But there is a way round this.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;buying-a-house&quot;&gt;Buying a house&lt;&#x2F;h3&gt;
&lt;p&gt;Simple, put a note through the seller&#x27;s letterbox offering direct contact and including your contact details.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;document&#x2F;d&#x2F;1PkJ-XiodC7bW0fXikQP0Ur3EyDLy0z1wGhRLtzfSh0I&#x2F;edit?usp=sharing&quot;&gt;a template note to a seller&lt;&#x2F;a&gt; that worked for me in a previous purchase.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sample-letter-to-sellers&quot;&gt;Sample letter to sellers&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;To:&lt;br &#x2F;&gt;
The Owners,&lt;br &#x2F;&gt;
[Address of house&lt;br &#x2F;&gt;
you want to buy]&lt;&#x2F;p&gt;
&lt;p&gt;[Your name here]&lt;br &#x2F;&gt;
[Your address (optional)]&lt;&#x2F;p&gt;
&lt;p&gt;Contact: [01184960000 &#x2F; your.email@example.org]&lt;&#x2F;p&gt;
&lt;p&gt;[Date]&lt;&#x2F;p&gt;
&lt;p&gt;Hi,&lt;&#x2F;p&gt;
&lt;p&gt;We’re the people who put the offer in on your house, and we just wanted to give you the opportunity to make direct contact should you have any questions.&lt;&#x2F;p&gt;
&lt;p&gt;We still absolutely love your house, and are very keen to proceed with the purchase. We are working with [Estate Agent] to move the sale of our house forward.&lt;&#x2F;p&gt;
&lt;p&gt;Our contact details are above, don’t hesitate to get in touch should you wish to. We will of course still do all formal communications through the estate agents and solicitors, we’ve just found it handy in the past to also have direct contact.&lt;&#x2F;p&gt;
&lt;p&gt;Yours,&lt;&#x2F;p&gt;
&lt;p&gt;[Your name here]&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;selling-a-house&quot;&gt;Selling a house&lt;&#x2F;h3&gt;
&lt;p&gt;Write a formal letter with an offer of direct communications and include your contact details, PDF it and send it to your solicitor to pass on. Because this is officially a letter to the seller both solicitors will I think be obliged to pass it on.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;document&#x2F;d&#x2F;1E677UNhLQq0CQkd4FuSfADiVMpGbHFdgztJzMQq4q9A&#x2F;edit?usp=sharing&quot;&gt;a template note to a buyer&lt;&#x2F;a&gt; that worked for me in a previous sale.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sample-letter-to-buyers&quot;&gt;Sample letter to buyers&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;FAO: [Buyer Name Here]&lt;br &#x2F;&gt;
C&#x2F;O: [Buyer’s Solicitors]&lt;br &#x2F;&gt;
Ref: [Property Address]&lt;br &#x2F;&gt;
Thu 4 Mar 21&lt;&#x2F;p&gt;
&lt;p&gt;Dear [Name],&lt;&#x2F;p&gt;
&lt;p&gt;This is just a personal note in addition to the formalities around the sale to let you know that we are keen for the process to go smoothly for both sides and that if there’s anything you need from us you are welcome to make direct contact as needed.&lt;&#x2F;p&gt;
&lt;p&gt;All contractual and legal issues will continue to be dealt with through our solicitors and the estate agent, however we have found it useful in the past to be able to co-ordinate directly to ensure a smooth route to a completed sale.&lt;&#x2F;p&gt;
&lt;p&gt;There is no pressure to accept, but should you wish to do so please find my contact details below.&lt;&#x2F;p&gt;
&lt;p&gt;Confirmation of your receipt of this letter would be greatly appreciated.&lt;&#x2F;p&gt;
&lt;p&gt;Yours&lt;&#x2F;p&gt;
&lt;p&gt;[Your Name]&lt;&#x2F;p&gt;
&lt;p&gt;[your.email@example.org]&lt;br &#x2F;&gt;
[01184960000]&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;i-ain-t-no-lawyer&quot;&gt;I ain&#x27;t no lawyer&lt;&#x2F;h2&gt;
&lt;p&gt;Do this at your own risk! Just as this could help, you could also use this communication channel to sink a deal that would have worked out, or even get yourself in legal trouble.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Podcasting hardware setup</title>
        <published>2021-01-26T00:00:00+00:00</published>
        <updated>2021-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/01/26/podcasting-hardware-setup/"/>
        <id>https://0x5.uk/2021/01/26/podcasting-hardware-setup/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/01/26/podcasting-hardware-setup/">&lt;h2 id=&quot;current-recording-playback-setup&quot;&gt;Current recording&#x2F;playback setup&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B001R747SG&#x2F;&quot;&gt;Samson Q2U cardiod XLR&#x2F;USB Microphone&lt;&#x2F;a&gt; ~ £90
&lt;ul&gt;
&lt;li&gt;USB means no need for a mixer or XLR adapter thing.&lt;&#x2F;li&gt;
&lt;li&gt;Seems to be the best price&#x2F;quality balance for me.&lt;&#x2F;li&gt;
&lt;li&gt;The cardiod effect is pretty good, greatly reducing input of noises from elsewhere, especially if you talk really close to it (which I don&#x27;t).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B002AI880O&#x2F;&quot;&gt;Proel RSM180 Microphone stand with boom&lt;&#x2F;a&gt; ~ £34
&lt;ul&gt;
&lt;li&gt;Because standing desk, plus the Samson mic doesn&#x27;t isolate vibrations from the desk if it&#x27;s on a desk mount.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B008AOH1O6&#x2F;&quot;&gt;AKORD Microphone Swivel Pop Filter&lt;&#x2F;a&gt; ~ £5
&lt;ul&gt;
&lt;li&gt;Because all the cool kids have one, and it was cheap. No idea if I really need it. Edit: yes I do, breathing on the mics and hard &quot;P&quot;s really do create a bass boom without it as the rush of air hits the mic.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Some old philips bluetooth headphones connected with a real headphone cable to the line out on the back of the Samson mic. I only use this for recording to avoid feedback from speakers. It has a feedback of your own voice which is disconcerting and nice in equal measure. For conference calls zoom and teams seem to do a decent job of cutting out the feedback, and I use mute a lot anyway so I don&#x27;t bother with the headphones.&lt;&#x2F;li&gt;
&lt;li&gt;The tiny and highly capable &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B07QQ47RTZ&#x2F;&quot;&gt;Nobsound G3 2 Channel Bluetooth 5.0 Power Amplifier 100W&lt;&#x2F;a&gt; hifi amp, driving a pair of bookshelf Kefs for editing, music and conference calls.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B0036EEOSQ&quot;&gt;Wharfedale Diamond SW150 Subwoofer&lt;&#x2F;a&gt; hiding at the back, because &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;open.spotify.com&#x2F;playlist&#x2F;3GTZ7nPFzsoC8F0iaMWDpG?si=074a2d5d6ca84bc9&quot;&gt;frequencies below 100Hz&lt;&#x2F;a&gt; are important too.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;video&quot;&gt;Video&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;camera&quot;&gt;Camera&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B006A2Q81M&#x2F;&quot;&gt;Logitech C920 HD Pro Webcam&lt;&#x2F;a&gt; ~ £60&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;lighting&quot;&gt;Lighting&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B08LNK7PGL&quot;&gt;WBTY Gooseneck Mount Stand&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B07YFY7H7J&quot;&gt;Neewer USB lights x2&lt;&#x2F;a&gt; ~ £51 (didn&#x27;t come with usb power units, bring your own, requires high-current capability)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;software&quot;&gt;Software&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;obsproject.com&#x2F;&quot;&gt;OBS (Open Broadcaster Software)&lt;&#x2F;a&gt;for live streaming + recording video+audio&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;restream.io&#x2F;&quot;&gt;restream.io&lt;&#x2F;a&gt; for streaming to multiple platforms&lt;&#x2F;li&gt;
&lt;li&gt;Audacity for editing (I &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=5KBFcuRWQ5s&amp;amp;t=1107s&quot;&gt;streamed a record+edit session&lt;&#x2F;a&gt; if you&#x27;re interested)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;everything-else&quot;&gt;Everything else&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Dell XPS15 (sometimes an XPS13)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linuxmint.com&#x2F;edition.php?id=288&quot;&gt;Linux mint cinnamon&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B00FOQD9EO&quot;&gt;Standing desk&lt;&#x2F;a&gt; (no chair these days, previously kneely chairs and exercise balls).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B01HHYQBB8&quot;&gt;Nextstand k2 Folding laptop stand&lt;&#x2F;a&gt; (amazing bit of kit, very portable too)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Microsoft-JQD-00006-Sidewinder-X4-Keyboard&#x2F;dp&#x2F;B0037KLSS8&quot;&gt;Microsoft sidewinder X4 keyboard&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B0042BBR2S&quot;&gt;Logitech M570 trackball&lt;&#x2F;a&gt; - I find the continuous thumb+finger grip needed for a mouse uncomfortable.
&lt;ul&gt;
&lt;li&gt;Recently upgraded to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B074W227RK&quot;&gt;Logitech MX Ergo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B0151VIQLW&quot;&gt;HP M477fdw laserjet + sheet feed scanner&lt;&#x2F;a&gt; because life&#x27;s too short for manually scanning one page at a time. Configured to automatically send scans to server over smb, then sync&#x27;d to all devices with syncthing. Win.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;pics&quot;&gt;Pics&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;desk.jpg&quot; alt=&quot;photo of standing desk&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;also-ran-hardware&quot;&gt;Also-ran hardware&lt;&#x2F;h2&gt;
&lt;p&gt;I started with a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B074BPJRBW&#x2F;&quot;&gt;Jabra Evolve 65 wireless headset&lt;&#x2F;a&gt; (~£130 because covid prices) but that heavily processes voice so while it&#x27;s great for conference calls it&#x27;s not good for anything beyond your third episode as people will unsubscribe just for the sound quality. Still use them for on the go conference calls and phone calls, and occasionally music (though my phone&#x27;s bluetooth is currently borked). They eventually also snapped after being thrown in a bag too often, so now I have a...&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B086M57V71&quot;&gt;Jabra Evolve2 65&lt;&#x2F;a&gt; headset, which I use for conference calls (and it&#x27;s great for that), especially out and about, but which is also too heavily processed to be suitable for recording high quality podcast audio.&lt;&#x2F;p&gt;
&lt;p&gt;I tried a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;gp&#x2F;product&#x2F;B002OO18NS&#x2F;&quot;&gt;Blue Microphones Snowball USB Microphone&lt;&#x2F;a&gt; (~£75) next, but that picks up &lt;em&gt;everything&lt;&#x2F;em&gt; even in it&#x27;s alleged cardioid mode. It did make a good recording of some thunder until the kids talked over it in excitement! You could use this if you have a &lt;em&gt;very&lt;&#x2F;em&gt; quiet environment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;out-of-my-price-range&quot;&gt;Out of my price range&lt;&#x2F;h2&gt;
&lt;p&gt;Some of my friends who take it more seriously splashed out on a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.shure.com&#x2F;en-GB&#x2F;products&#x2F;microphones&#x2F;sm7b&quot;&gt;Shure SM7B XLR Mic&lt;&#x2F;a&gt; at a mere £389, and you have to by an XLR mixer to run it. I have to say they sound lurvely, and when they knock it you hardly hear it so it&#x27;s got excellent vibration isolation built in.&lt;&#x2F;p&gt;
&lt;p&gt;You could also look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Shure-MV7-Microphone-Podcasting-Voice-Isolating&#x2F;dp&#x2F;B08G7RG9ML&quot;&gt;Shure MV7 USB Microphone&lt;&#x2F;a&gt; which has USB as well as XLR so you wouldn&#x27;t need a mixer. That&#x27;s £250 currently. Presumably it&#x27;s also got Shure&#x27;s excellent sound and vibration isolation, though I haven&#x27;t got one, so let me know if you get one!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hanselman.com&#x2F;blog&#x2F;good-better-best-creating-the-ultimate-remote-worker-webcam-setup-on-a-budget&quot;&gt;Scott Hansleman&#x27;s AV kit guide - &quot;good, better, best&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A book list for my children</title>
        <published>2021-01-25T00:00:00+00:00</published>
        <updated>2021-01-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2021/01/25/a-book-list-for-my-children/"/>
        <id>https://0x5.uk/2021/01/25/a-book-list-for-my-children/</id>
        
        <content type="html" xml:base="https://0x5.uk/2021/01/25/a-book-list-for-my-children/">&lt;p&gt;This is for my children when they&#x27;re old enough to read them and benefit from them, and when they decide to take an interest in the advice of their boring old man, however I&#x27;d recommend this list to anyone no matter their stage in life.&lt;&#x2F;p&gt;
&lt;p&gt;What book should you read next? Well, what problem are you trying to solve right now? That said, there are some eternal problems in life such as interpersonal relationships and the search for financial stability and fulfilment which these books help navigate.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve added a note to each explaining why you should read it, and when you might want to make it a priority. I&#x27;ve also put them in an order that I think would be sensible; with the most foundational first (personal growth) followed by more wealth and lifestyle focussed volumes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;being-human&quot;&gt;Being human&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;36072.The_7_Habits_of_Highly_Effective_People&quot;&gt;The 7 habits of highly effective people; Stephen Covey&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? It&#x27;s important to know you can change who you are and be a better person, and know how to do so. You can be better with relationships and those around you. This book is an inspiration in personal growth.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: as a young adult, and again when you&#x27;re older and wiser. Or right now if you&#x27;re already both of those.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;13588356-daring-greatly&quot;&gt;Daring Greatly by Brené Brown&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Our society teaches all the wrong lessons around guilt, shame and vulnerability. Our default responses to that are self-destructive. Brené shows us how to be brave enough to accept the challenges of life without hurting others to protect ourselves. The difference between guilt (&quot;I did something that was wrong and regret it&quot;) and shame (&quot;I&#x27;m a bad person&quot;) is often misunderstood or ignored entirely. When you think clearly about this it becomes clear that guilt is good and shame is bad.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: As early as you can, and maybe again if you find yourself falling into the traps of self-shaming, shaming others or not having the courage to do hard things for fear of failure.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;71730.Nonviolent_Communication&quot;&gt;Nonviolent Communication; Marshall Rosenberg&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Somewhat surprisingly perhaps the calm and empathic approach to communication is superior; but that&#x27;s easier said than done with our brains evolved for times gone by.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: As soon as you argue with someone and wonder what it achieved or it cost you dearly. Ideally before that happens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;310194.Bonds_That_Make_Us_Free&quot;&gt;Bonds That Make Us Free; C. Terry Warner&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Yes, it&#x27;s another book on dealing with people. The truth is it&#x27;s not them it&#x27;s you; but the good news is that you have the power to change what&#x27;s wrong. It turns out that dealing with people is important, and is foundational in all walks of life.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: As soon as you can, and then probably every decade after that.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;13525945-so-good-they-can-t-ignore-you&quot;&gt;So good they can&#x27;t ignore you; Cal Newport&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Don&#x27;t believe the hype at work, people hire for your real skills and what you can do for them. More details and foundational career advice for any path you choose lie within.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: Probably before your first or second job, but better late than never. If you&#x27;ve retired rich before you read this then maybe don&#x27;t bother!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;22318578-the-life-changing-magic-of-tidying-up&quot;&gt;The Life-Changing Magic of Tidying; Marie Kondo&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Because too much stuff ironically makes you less happy. Go figure. A practical guide to a calming and tidy house&#x2F;room&#x2F;boat&#x2F;mansion&#x2F;office from someone a little obsessed with tidy.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: When you&#x27;re fed up hearing me complain your room&#x27;s a mess. Or later on when you realise why I complained about it but don&#x27;t really know how to fix it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;1303.The_48_Laws_of_Power&quot;&gt;48 Laws of Power; Robert Greene&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Sadly the world is not the cuddly, friendly, fair and equitable world some people seem to think they can wish into existence by will power and singing alone. There are plenty of good things, but the hard truths about raw underlying human nature are best understood so you can deal with them if you need to. I trust you are a good human being who will only use some of the darker knowledge in here for good and personal survival.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: I hesitate to say early because used without experience this knowledge will get you into more trouble than it gets you out of. That said, earlier the better but don&#x27;t rush into using it, just observe the people around quietly with this new knowledge for the next few years at least.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;58536046-why-has-nobody-told-me-this-before&quot;&gt;Why Has Nobody Told Me This Before?; Julie Smith&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? We all think we are perfect and we know how to use our brains. Turns out that&#x27;s hubris, and it&#x27;s worth having an expert on hand to help you learn to use your own brain properly and communicate in non-destructive ways with those around us. Expert therapy and counselling are great and should be taken advantage of, but it&#x27;s useful to have a reference and guide to have and to study alone as well, regardless of whether you get expert help.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: as soon as you can, and probably every 5-10 years after that given we tend to forget the lessons and go back to default human patterns.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;money-and-work&quot;&gt;Money and work&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;69571.Rich_Dad_Poor_Dad&quot;&gt;Rich dad, poor dad; Robert T. Kiyosaki&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Money isn&#x27;t everything, but not having it will make you miserable. And the thing that will make you poor beyond anything else is your mindset and financial education. Read this to learn what the people who never seem to work do and why they never seem to run out of money.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: As soon as your bank account hits zero for the first time, and any time you are annoyed that you still have that sucky job you hate but can&#x27;t escape from (happens to us all I think).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;30186948-think-and-grow-rich&quot;&gt;Think and Grow Rich; Napoleon Hill&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? More money will let you solve more problems, have more freedom, help more people, and live your best life. But it&#x27;s not that easy to know where to start without a role model and a plan. Good practical guidance in here. Time will tell if I make good use of it myself.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: After the first few years of plying a trade perhaps, but don&#x27;t leave it too long.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;56447987-the-millionaire-fast-lane&quot;&gt;The Millionaire Fast Lane; M.J. DeMarco&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Having read a lot of books about business and money, none of them have the completeness of this one. It&#x27;s the best guide to the whole picture I&#x27;ve come across.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: As soon as you start trying to earn your own money, or as soon after that as you can.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;9278897-the-4-hour-work-week&quot;&gt;The 4-Hour Work Week; Tim Ferris&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Working for someone else 9-5 isn&#x27;t the only way to make a living. This book might age when it comes to tactics, but the inspirational vision of another way of life is timeless.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: Whenever you&#x27;ve had enough of a job. Or maybe if you just want to dream, or travel.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;36653486-the-road-less-stupid&quot;&gt;The Road Less Stupid; Keith J. Cunningham&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Whatever money and success you achieve, it&#x27;s very easy to throw it all away again by doing dumb things that seemed like a good idea. This is a straight-talking guide to not doing that. Contains important lesson about protecting against downside risk (i.e. a small chance you lose everything) when chasing upside risk (i.e. a chance to be much richer etc). Unmitigated downside risk has the power to destroy everything you&#x27;ve worked for.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: Sooner rather than later, especially if you&#x27;re feeling a bit ambitious.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;26089.Working_Identity&quot;&gt;Working Identity; Herminia Ibarra&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? The days of job-for-life are long gone, even the days of one-career lives are fading. You&#x27;ll almost certainly need to evolve your work life, if not blow it up completely and start over. This book is a wise guide to the opportunities and pitfalls of seeing if the grass really is greener.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: when you are sick of your job&#x2F;career and want to do something different.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;the-meaning-of-life-evolution-and-religion&quot;&gt;The meaning of life, evolution and religion&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;117047.The_Blind_Watchmaker&quot;&gt;The Blind Watchmaker; Richard Dawkins&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Evolution if often poorly understood. As the foundation of our existence and behaviours this to me is a must read to truly understand life. For me it answers the question of &quot;what is the point in life&quot;; ironically there is no point really, but that is more freeing than some deity with odd morals. Just know that you can know the raw mechanics and still live a full, happy and meaningful life; helping all those around you.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: Whenever you have some time. Kinda background knowledge for life.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;14743.The_God_Delusion&quot;&gt;The God Delusion; Richard Dawkins&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? God is all around us in the many people&#x27;s of the world. His name(s) are often used to manipulate and exploit, and play power games. You and I can probably do nothing about this (and it&#x27;s dangerous territory to tread in, I&#x27;m surprised Dawkins is still alive), however I think the knowledge is an important piece of the complex puzzle that is humanity. Once you&#x27;ve read this, don&#x27;t judge those who believe for whatever reason, you will not change them and you will only cause hurt.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: Whenever you have time, any time you are considering the meaning and truth of religion, and any time you want to be able to discuss the topic with more useful information.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;children-of-your-own&quot;&gt;Children of your own&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;10143584-pregnancy-for-men&quot;&gt;Pregnancy For Men&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Nothing can prepare you for this experience, and men are an anxious side-show. This book helped me cope, and even occasionally be useful.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: As soon as you think you&#x27;ll have a kid on the way, don&#x27;t leave it till the due date or you&#x27;ll miss the pre-natal stuff.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;769016.How_to_Talk_So_Kids_Will_Listen_Listen_So_Kids_Will_Talk&quot;&gt;How to talk so Kids Will listen&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Nothing about communicating well is natural or obvious. It takes work and understanding, and undoing cultural failings. This series is one of the best, kindest works out there, and helped me immensely.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: When your kids are starting to talk.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;106744.Hold_On_to_Your_Kids&quot;&gt;Hold on to Your Kids: Why Parents Need to Matter More Than Peers&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Why? Culture is teaching us to ignore our parents with devastating consequences for all involved. It turns out &quot;attachment&quot; is the key, and when it goes wrong nothing you do will work.&lt;&#x2F;li&gt;
&lt;li&gt;When to read: When your kids are 4+ years old.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Personally I like the audiobook format, and at time of writing a yearly subscription to Audible was good value for getting easy access to the content, and a narration from the author or a good speaker makes for a more memorable experience.&lt;&#x2F;p&gt;
&lt;p&gt;Beyond this list, check the best-seller lists for whatever subject you wish to excel at. There&#x27;s no point learning the hard way when you can learn from someone who has. Even in this digital age books still pack a tremendous punch; the result of someone pouring 20+ years of their experience into something you can read in a week is like liquid gold. I also have recorded a lot of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;user&#x2F;show&#x2F;50628592-tim-abell&quot;&gt;my personal reading list on GoodReads&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To my little people who will soon be bigger than me in every way, love you 💕️👊️, Diddy x&lt;&#x2F;p&gt;
&lt;p&gt;P.S. If you&#x27;re reading this and you&#x27;re not my kid, well I love you too for being the lovely human I know you are.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Remote code interview pairing tools</title>
        <published>2020-12-04T00:00:00+00:00</published>
        <updated>2020-12-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/12/04/remote-code-interview-pairing-tools/"/>
        <id>https://0x5.uk/2020/12/04/remote-code-interview-pairing-tools/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/12/04/remote-code-interview-pairing-tools/">&lt;p&gt;Things that you could use to do simple coding exercises in the new world of remote everything.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeinterview.io&#x2F;&quot;&gt;CodeInterview.io&lt;&#x2F;a&gt; - $5&#x2F;interview or $55&#x2F;month&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codesandbox.io&#x2F;&quot;&gt;CodeSandbox.io&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cyber-dojo.org&#x2F;creator&#x2F;home&quot;&gt;Cyber-dojo&lt;&#x2F;a&gt; - free for non-commercial, set your own price for commercial!&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=MS-vsliveshare.vsliveshare-pack&quot;&gt;VSCode live share&lt;&#x2F;a&gt; works well, it can do voice as well.&lt;&#x2F;li&gt;
&lt;li&gt;Zoom&#x2F;hangouts&#x2F;meet&#x2F;skype etc. built-in screen sharing and whatever coding setup they already use.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Thanks to my friends at eSynergySolutions for the suggestions, recorded here because the internet has a better memory than me.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Database migration options for dotnet core</title>
        <published>2020-11-26T00:00:00+00:00</published>
        <updated>2020-11-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/11/26/database-migration-options-for-dotnet-core/"/>
        <id>https://0x5.uk/2020/11/26/database-migration-options-for-dotnet-core/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/11/26/database-migration-options-for-dotnet-core/">&lt;h2 id=&quot;options&quot;&gt;Options&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;ef&#x2F;core&#x2F;managing-schemas&#x2F;migrations&#x2F;?tabs=dotnet-core-cli&quot;&gt;Built-in EF Core migrations&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fluentmigrator.github.io&#x2F;&quot;&gt;FluentMigrator&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;dbup.github.io&#x2F;&quot;&gt;DbUp&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;products&#x2F;redgate-deploy&#x2F;&quot;&gt;RedGate Deploy&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;documentation.red-gate.com&#x2F;sca&#x2F;developing-databases&#x2F;concepts&#x2F;migrations&#x2F;migration-scripts&quot;&gt;RedGate SQL Change Automation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;flywaydb.org&#x2F;&quot;&gt;Flyway by RedGate&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;timabell.github.io&#x2F;sqlHawk&#x2F;&quot;&gt;SqlHawk&lt;&#x2F;a&gt; (I wrote this years ago, forked from the excellent &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaspy.org&#x2F;&quot;&gt;SchemaSpy&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;tim_abell&quot;&gt;hit me up on twitter&lt;&#x2F;a&gt; if you know of any more options&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note that the excellent &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.realwire.com&#x2F;releases&#x2F;Redgate-acquires-database-migrations-and-deployment-tool-ReadyRoll&quot;&gt;ReadyRoll got bought by
RedGate&lt;&#x2F;a&gt;
and renamed to something I can never remember.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;46649238&#x2F;alternative-to-redgate-readyroll-yet&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;46649238&#x2F;alternative-to-redgate-readyroll-yet&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running the CosmosDB emulator on Linux</title>
        <published>2020-09-17T00:00:00+00:00</published>
        <updated>2020-09-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/09/17/cosmosdb-emulator-on-linux/"/>
        <id>https://0x5.uk/2020/09/17/cosmosdb-emulator-on-linux/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/09/17/cosmosdb-emulator-on-linux/">&lt;p&gt;Update: microsoft have released a linux compatible docker image it seems, let me know if it actually works and I&#x27;ll update this post. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;linux-emulator&quot;&gt;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;linux-emulator&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Unfortunately even though &quot;Microsoft 🖤 Linux&quot; the CosmosDB team seem less keen. This is not fun, pretty or stable, but at least it works which is something.&lt;&#x2F;p&gt;
&lt;p&gt;There is a docker image but it only runs on docker-for-windows so it&#x27;s no help here.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Grab a Windows VM, install the emulator.&lt;&#x2F;li&gt;
&lt;li&gt;Copy the emulator SSL cert to the host.&lt;&#x2F;li&gt;
&lt;li&gt;Map the ports.&lt;&#x2F;li&gt;
&lt;li&gt;Redirect the VM IP back to localhost with iptables.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;steps&quot;&gt;Steps&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;get-a-windows-virtualbox-vm-running&quot;&gt;Get a Windows VirtualBox VM Running&lt;&#x2F;h3&gt;
&lt;p&gt;Download the VirtualBox image from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.microsoft.com&#x2F;en-us&#x2F;windows&#x2F;downloads&#x2F;virtual-machines&#x2F;&quot;&gt;https:&#x2F;&#x2F;developer.microsoft.com&#x2F;en-us&#x2F;windows&#x2F;downloads&#x2F;virtual-machines&#x2F;&lt;&#x2F;a&gt; (2 month free trial, no key needed).&lt;&#x2F;p&gt;
&lt;p&gt;Install VirtualBox.&lt;&#x2F;p&gt;
&lt;p&gt;Fix the VM image configuration (if you are using the slightly older VirtualBox from ubuntu&#x27;s apt repositories) by removing &lt;code&gt;controller=&quot;VBoxSVGA&quot;&lt;&#x2F;code&gt; from the &lt;code&gt;.ovf&lt;&#x2F;code&gt; file in the &lt;code&gt;.ova&lt;&#x2F;code&gt; file (which is a tar.gz archive). See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;schnouki.net&#x2F;post&#x2F;2020&#x2F;how-to-run-a-win10-dev-vm-on-virtualbox-5&#x2F;&quot;&gt;https:&#x2F;&#x2F;schnouki.net&#x2F;post&#x2F;2020&#x2F;how-to-run-a-win10-dev-vm-on-virtualbox-5&#x2F;&lt;&#x2F;a&gt; for details.&lt;&#x2F;p&gt;
&lt;p&gt;Import the VM into VirtualBox&lt;&#x2F;p&gt;
&lt;p&gt;Run the VM&lt;&#x2F;p&gt;
&lt;p&gt;Install the guest additions (Devices &amp;gt; Insert guest additions CD)&lt;&#x2F;p&gt;
&lt;p&gt;Set the timezone (VM defaults to US).&lt;&#x2F;p&gt;
&lt;p&gt;Turn on seamless copy-paste &amp;amp; drag-and-drop (so that we can move certificate and data files to&#x2F;from the host easily).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;set-up-the-cosmosdb-emulator&quot;&gt;Set up the CosmosDB emulator&lt;&#x2F;h3&gt;
&lt;p&gt;In the Windows VM download and install the CosmosDB emulator in the VM from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;local-emulator?tabs=ssl-netstd21#installation&quot;&gt;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;local-emulator?tabs=ssl-netstd21#installation&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If the emulator is already running, shut it down:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;powershell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;C:\Program Files\Azure Cosmos DB Emulator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.\&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Microsoft.Azure.Cosmos.Emulator.exe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt;shutdown&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Start the emulator with network access enabled.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;powershell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;C:\Program Files\Azure Cosmos DB Emulator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.\&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Microsoft.Azure.Cosmos.Emulator.exe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt;AllowNetworkAccess &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;DisableRateLimiting &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;Key&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;C2y6yDjf5&#x2F;R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw&#x2F;Jw==&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(This key is the hard-coded well-known key that the emulator uses by default, which makes it easy to connect the storage explorer).&lt;&#x2F;p&gt;
&lt;p&gt;Check it is listening on &lt;code&gt;0.0.0.0:8081&lt;&#x2F;code&gt; (as opposed to &lt;code&gt;127.0.0.1:8081&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;netstat -a |findstr 8081&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;map-the-cosmosdb-port-to-the-host&quot;&gt;Map the CosmosDB port to the host&lt;&#x2F;h3&gt;
&lt;p&gt;In the VirtualBox network settings for the VM, click advanced and add a port mapping for 8081 on the VM to 8081 on the host.&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;122641&#x2F;how-to-forward-ports-to-a-virtual-machine-and-use-it-as-a-server&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;122641&#x2F;how-to-forward-ports-to-a-virtual-machine-and-use-it-as-a-server&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This makes the emulator appear as if it was running on the Linux host.&lt;&#x2F;p&gt;
&lt;p&gt;(Note there are replica ports that need mapping too, see the dotnet-core section below).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;connect-with-storage-explorer&quot;&gt;Connect with Storage Explorer&lt;&#x2F;h3&gt;
&lt;p&gt;Install the Azure Storage Explorer on your Linux host, either with the .tar.gz or from the snap store&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;azure.microsoft.com&#x2F;en-us&#x2F;features&#x2F;storage-explorer&#x2F;&quot;&gt;https:&#x2F;&#x2F;azure.microsoft.com&#x2F;en-us&#x2F;features&#x2F;storage-explorer&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Run the storage explorer.&lt;&#x2F;p&gt;
&lt;p&gt;Connect to the emulator on localhost.&lt;&#x2F;p&gt;
&lt;p&gt;You should now be able to create collections and add documents, and then view them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;connecting-from-dotnet-core&quot;&gt;Connecting from dotnet-core&lt;&#x2F;h3&gt;
&lt;p&gt;Problems connecting from core that I didn&#x27;t encounter with storage explorer:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The SSL certificate is rejected.&lt;&#x2F;li&gt;
&lt;li&gt;CosmosDB sets the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;api&#x2F;microsoft.azure.documents.client.documentclient.readendpoint&quot;&gt;&lt;code&gt;ReadEndpoint&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to be the VM&#x27;s IP address, which isn&#x27;t accessible from the host because we are using NAT and port mapping. (oddly this wasn&#x27;t consistently the interal IP address.&lt;&#x2F;li&gt;
&lt;li&gt;The replicas listen on additional ports which also need mapping.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;accepting-the-emulator-ssl-certificate&quot;&gt;Accepting the emulator SSL certificate&lt;&#x2F;h4&gt;
&lt;p&gt;This is the error you get trying to connect to the CosmosDB emulator from dotnet core on Linux without adding the certificate to the Linux host&#x27;s certificate authority (CA) list:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;System.Net.Http.HttpRequestException:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The SSL connection could not be established,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;see inner exception. ---&amp;gt; System.Security.Authentication.AuthenticationException:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The remote certificate is invalid according to the validation procedure.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  at at System.Net.Security.SslStream.StartSendAuthResetSignal(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Export the emulator&#x27;s public SSL certificate &quot;DocumentDbEmulatorCertificate&quot; as base64 X509.&lt;&#x2F;p&gt;
&lt;p&gt;Reference: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;local-emulator-export-ssl-certificates#how-to-export-the-azure-cosmos-db-tlsssl-certificate&quot;&gt;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;local-emulator-export-ssl-certificates#how-to-export-the-azure-cosmos-db-tlsssl-certificate&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Copy the exported file to your Linux host.&lt;&#x2F;p&gt;
&lt;p&gt;Add the certificate to the trusted certificates on your machine (these instructions are for Ubuntu&#x2F;Mint):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo cp --verbose cosmos-emulator.cer &#x2F;usr&#x2F;local&#x2F;share&#x2F;ca-certificates&#x2F;cosmos-emulator.crt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo update-ca-certificates --verbose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Reference: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;44159793&#x2F;trusted-root-certificates-in-dotnet-core-on-linux-rhel-7-1&#x2F;44160125#44160125&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;44159793&#x2F;trusted-root-certificates-in-dotnet-core-on-linux-rhel-7-1&#x2F;44160125#44160125&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note the change in file extension from &lt;code&gt;.cer&lt;&#x2F;code&gt; to &lt;code&gt;.crt&lt;&#x2F;code&gt; between export and import (I&#x27;m not 100% sure if this matters).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note that the certificate is regenerated on emulator startup&lt;&#x2F;em&gt; so you&#x27;ll either have to do this every time or pass the emulator a predefined certificate to use.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to validate the certificate has been installed, see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;97244&#x2F;list-all-available-ssl-ca-certificates&quot;&gt;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;97244&#x2F;list-all-available-ssl-ca-certificates&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;redirecting-readendpoint-traffic&quot;&gt;Redirecting ReadEndpoint traffic&lt;&#x2F;h4&gt;
&lt;p&gt;In the VM in a powershell or command prompt run &lt;code&gt;ipconfig&lt;&#x2F;code&gt; to get the machine&#x27;s IP address.&lt;&#x2F;p&gt;
&lt;p&gt;Tell &lt;code&gt;iptables&lt;&#x2F;code&gt; to redirect all requests for the VM&#x27;s IP address back to &lt;code&gt;localhost&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; iptables&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; nat&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;I&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; OUTPUT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-dst&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; 10.0.2.XXX&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tcp&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-dport&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt; 8081&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;j&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; REDIRECT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-to-ports&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt; 8081&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where &lt;code&gt;XXX&lt;&#x2F;code&gt; is the IP of your VM.&lt;&#x2F;p&gt;
&lt;p&gt;As per: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;441182&#x2F;how-to-map-an-ip-address-to-localhost&quot;&gt;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;441182&#x2F;how-to-map-an-ip-address-to-localhost&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;mapping-replica-port-s&quot;&gt;Mapping replica port(s)&lt;&#x2F;h4&gt;
&lt;p&gt;On the VM run &lt;code&gt;netstat -a |findstr LISTENING&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll see a bunch of ports in the 10,000-20,000 range. These are the replicas&lt;&#x2F;p&gt;
&lt;p&gt;I found out which ports to map by running the client code and looking at the exception when it failed to connect. It was only port &lt;code&gt;10253&lt;&#x2F;code&gt; for me so far. Here&#x27;s the error for a failure:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Microsoft.Azure.Documents.ServiceUnavailableException: Service is currently unavailable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ActivityId: 2dfaf5dc-0d5a-4ed7-828d-c16cdcd117a3, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RequestStartTime: 2020-09-17T20:00:16.8868999Z, RequestEndTime: 2020-09-17T20:00:46.7777188Z, Number of regions attempted: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ResponseTime: 2020-09-17T20:00:16.9400284Z, StoreResult: StorePhysicalAddress: rntbd:&#x2F;&#x2F;10.0.2.15:10253&#x2F;apps&#x2F;DocDbApp&#x2F;services&#x2F;DocDbServer15&#x2F;partitions&#x2F;a4cb495b-38c8-11e6-8106-8cdcd42c33be&#x2F;replicas&#x2F;1p&#x2F;, LSN: -1, GlobalCommittedLsn: -1, PartitionKeyRangeId: , IsValid: False, StatusCode: 410, SubStatusCode: 0, RequestCharge: 0, ItemLSN: -1, SessionToken: , UsingLocalLSN: True, TransportException: A client transport error occurred: Failed to connect to the remote endpoint. (Time: 2020-09-17T20:00:16.9221735Z, activity ID: 2dfaf5dc-0d5a-4ed7-828d-c16cdcd117a3, error code: ConnectFailed [0x0005], base error: socket error ConnectionRefused [0x0000274D], URI: rntbd:&#x2F;&#x2F;10.0.2.15:10253&#x2F;, connection: &amp;lt;not connected&amp;gt; -&amp;gt; rntbd:&#x2F;&#x2F;10.0.2.15:10253&#x2F;, payload sent: False, CPU history: not available, CPU count: 8), ResourceType: Document, OperationType: Query&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add these ports to the VirtualBox port mapping configuration for your VM.&lt;&#x2F;p&gt;
&lt;p&gt;In the VM in a powershell or command prompt run &lt;code&gt;ipconfig&lt;&#x2F;code&gt; to get the machine&#x27;s IP address.&lt;&#x2F;p&gt;
&lt;p&gt;Tell &lt;code&gt;iptables&lt;&#x2F;code&gt; to redirect all requests for the VM&#x27;s IP address back to &lt;code&gt;localhost&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; iptables&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; nat&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;I&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; OUTPUT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-dst&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; 10.0.2.XXX&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; tcp&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-dport&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt; 10253&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;j&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; REDIRECT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;-to-ports&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D33682, #D33682);&quot;&gt; 10253&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where &lt;code&gt;XXX&lt;&#x2F;code&gt; is the IP of your VM and &lt;code&gt;10253&lt;&#x2F;code&gt; is the replica port.&lt;&#x2F;p&gt;
&lt;p&gt;As per: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;441182&#x2F;how-to-map-an-ip-address-to-localhost&quot;&gt;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;441182&#x2F;how-to-map-an-ip-address-to-localhost&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;importing-data&quot;&gt;Importing data&lt;&#x2F;h2&gt;
&lt;p&gt;If you need to import data then use data migration tool from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;import-data#Install&quot;&gt;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;cosmos-db&#x2F;import-data#Install&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;success&quot;&gt;Success&lt;&#x2F;h2&gt;
&lt;p&gt;With all of the above I was then able to connect a dotnet-core application on Linux to a CosmosDB emulator.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;emulator-failures&quot;&gt;Emulator failures&lt;&#x2F;h2&gt;
&lt;p&gt;After a while and some unrecorded fiddling, the emulator then gave up the ghost, resulting in the Azure Storage Explorer reporting the apparently meaningless error message &quot;Unable to retrieve child resources.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;According to the internet this error could mean anything. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;social.technet.microsoft.com&#x2F;wiki&#x2F;contents&#x2F;articles&#x2F;53393.azure-storage-explorer-troubleshooting-unable-to-retrieve-child-resources-or-the-request-action-could-not-be-completed.aspx&quot;&gt;https:&#x2F;&#x2F;social.technet.microsoft.com&#x2F;wiki&#x2F;contents&#x2F;articles&#x2F;53393.azure-storage-explorer-troubleshooting-unable-to-retrieve-child-resources-or-the-request-action-could-not-be-completed.aspx&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I might just blow the whole VM away and start again...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;should-you-use-cosmosdb&quot;&gt;Should you use CosmosDB?&lt;&#x2F;h2&gt;
&lt;p&gt;CosmosDB comes with significantly increased costs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I gather it&#x27;s very expensive to run in production&lt;&#x2F;li&gt;
&lt;li&gt;Development is painful&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As a result you should only choose CosmosDB for your solution if you &lt;em&gt;really&lt;&#x2F;em&gt; need something it offers that you can&#x27;t get from a more straight-forward SQL or DocumentDB solution and your domain is a good match for the document-database (aka NoSQL) model.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;faun&#x2F;comosdb-offline-emulator-78559ae91cd1&quot;&gt;Azure Development using CosmosDB offline Emulator by Matt Thankachan&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Effective GTD with Trello</title>
        <published>2020-09-15T00:00:00+00:00</published>
        <updated>2020-09-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/09/15/effective-gtd-with-trello/"/>
        <id>https://0x5.uk/2020/09/15/effective-gtd-with-trello/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/09/15/effective-gtd-with-trello/">&lt;ul&gt;
&lt;li&gt;Learn how I&#x27;ve refined the GTD process with Trello for modern living.&lt;&#x2F;li&gt;
&lt;li&gt;Get a template GTD board to kick-start your own.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;GTD+Trello has really helped sooth my neurotic tendencies around todo lists. I&#x27;m often startled by starting off thinking I have more than I could ever achieve and then getting all my top priorities done in one sitting and being able to truly relax afterwards. No more nagging feeling there&#x27;s something urgent at the bottom of the pile of papers somewhere.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-gtd&quot;&gt;What is GTD?&lt;&#x2F;h2&gt;
&lt;p&gt;Getting Things Done &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Getting_Things_Done&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Getting_Things_Done&lt;&#x2F;a&gt; is an old but effective method for organising the flood of todos that enter your life in many forms. We need it now more than ever in our infinitely connected world. And as a middle-aged working parent I need it now more than I ever did.&lt;&#x2F;p&gt;
&lt;p&gt;The point of GTD is to eliminate all the other places that you might have hidden todo lists such as&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;unread emails&lt;&#x2F;li&gt;
&lt;li&gt;your memory&lt;&#x2F;li&gt;
&lt;li&gt;phone notes&lt;&#x2F;li&gt;
&lt;li&gt;bits of paper&lt;&#x2F;li&gt;
&lt;li&gt;phone screenshots&lt;&#x2F;li&gt;
&lt;li&gt;other unstructured todo lists (Trello, Evernote etc. let me know what you use now that isn&#x27;t working for you and I&#x27;ll add it to the list)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And then to make your todo list something that you can almost mindlessly churn through, eliminating huge task switching costs caused by badly defined and variably sized tasks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trello-gtd&quot;&gt;Trello + GTD&lt;&#x2F;h2&gt;
&lt;p&gt;The original GTD method involved bits of paper. But now we have Trello, which is an excellent fit for GTD with its cards, lists and many integrations. There&#x27;s a great write-up of using Trello for GTD here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.trello.com&#x2F;gtd-getting-things-done-maximizing-productivity-trello&quot;&gt;https:&#x2F;&#x2F;blog.trello.com&#x2F;gtd-getting-things-done-maximizing-productivity-trello&lt;&#x2F;a&gt; which I suggest you go and read first. It&#x27;s how I got started, however I found I was still left building my own process and set of lists from there before it really worked for me.&lt;&#x2F;p&gt;
&lt;p&gt;Trello is great for GTD because:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can set up lists how you like&lt;&#x2F;li&gt;
&lt;li&gt;There are apps so you have it everywhere&lt;&#x2F;li&gt;
&lt;li&gt;You can forward emails to it (yay, inbox zero at last)&lt;&#x2F;li&gt;
&lt;li&gt;It supports attaching pictures, PDFs etc.&lt;&#x2F;li&gt;
&lt;li&gt;You can add checklists, due dates, date-stamped comments etc.&lt;&#x2F;li&gt;
&lt;li&gt;Drag-n-drop sorting and moving of cards&lt;&#x2F;li&gt;
&lt;li&gt;Buttons for archive &#x2F; move on the cards&lt;&#x2F;li&gt;
&lt;li&gt;A lovely cross-platform interface&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s free!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;&#x2F;h2&gt;
&lt;p&gt;Neither GTD or Trello can give you more hours in the day, help you focus, get you to do things you really don&#x27;t want to do, or make your tax return go away. This still requires putting the work in. Having said that, at least you will know you haven&#x27;t just forgotten anything really important, it&#x27;s just a bit stuck on your list. Personally with life as it is for me now I never get close to the weekly&#x2F;daily GTD schedule laid out below, but that doesn&#x27;t make it less valuable.&lt;&#x2F;p&gt;
&lt;p&gt;If you are looking at GTD for the same reasons as I did then beware &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.wsj.com&#x2F;articles&#x2F;escaping-the-efficiency-trapand-finding-some-peace-of-mind-11628262751&quot;&gt;&quot;the efficiency trap&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-gtd-method&quot;&gt;My GTD Method&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s my actual GTD board (minus details) to give you an idea of what it looks like. You might be able to see I have far too much in Inbox and Action items as is often the case, but it doesn&#x27;t take too long to clear down when I actually focus on it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;gtd-real-trello.png&quot; alt=&quot;Blurry screenshot of my actual GTD board&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;First you need to get everything you might have to do into your GTD board. Don&#x27;t think too hard at this point, just ping everything to Trello and deal with it efficiently at your next GTD moment:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;getting-everything-to-the-board&quot;&gt;Getting Everything to the Board&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;emails&quot;&gt;Emails&lt;&#x2F;h4&gt;
&lt;p&gt;Forward emails to your GTD board &quot;send-to-board&quot; email address to get to inbox zero quickly. Make sure your GTD board email address is in your address book so you can just type &quot;gtd&quot; and hit send.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;gtd-from-email.png&quot; alt=&quot;Screenshot of forwarding an email to the GTD board&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using GTD instead of your unread email as a todo list makes inbox-zero possible again.&lt;&#x2F;p&gt;
&lt;p&gt;The subject line becomes the card title so edit that if you want. The body of the email becomes the card description so you can add to that too.&lt;&#x2F;p&gt;
&lt;p&gt;Top tip: When sending an email that you&#x27;ll need to follow up on, put the GTD email address in the Blind-Carbon-Copy (BCC) field so that you instantly get a copy in your GTD board with no extra faff. (Thanks to this podcast episode for that idea: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shows.acast.com&#x2F;flavor-of-leadership&#x2F;episodes&#x2F;organizing-the-legos-in-our-minds-to-build-the-ultimate-vers&quot;&gt;&quot;Organizing the LEGOs In Our Minds to Build the Ultimate Version of Ourselves with Tiago Forte - Flavor of Leadership&quot;&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;web-based-tasks&quot;&gt;Web based tasks&lt;&#x2F;h4&gt;
&lt;p&gt;Install &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.addtoany.com&#x2F;&quot;&gt;AddToAny&lt;&#x2F;a&gt; to send any webpage from Firefox to your GTD inbox.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;gtd-addtoany.png&quot; alt=&quot;Screenshot of add-to-any in action&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;documents-physical-objects-pictures-screenshots&quot;&gt;Documents, physical objects, pictures, screenshots&lt;&#x2F;h4&gt;
&lt;p&gt;Install the Trello app and use the native share buttons to share pictures, web pages etc to your GTD inbox. Use this to take photos of paper documents and physical things you need to deal with and send the picture straight to your GTD inbox on Trello.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;gtd-android-share.jpg&quot; alt=&quot;Screenshot: sharing picture to trello in android&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;verbally-received-tasks&quot;&gt;Verbally Received Tasks&lt;&#x2F;h4&gt;
&lt;p&gt;For when someone just says to you &quot;oh, can you do this for me?&quot; and you don&#x27;t want to be that person that lets them down by forgetting.&lt;&#x2F;p&gt;
&lt;p&gt;If you think you are &quot;the forgetful type&quot; (you aren&#x27;t, that&#x27;s just a negative self-label compounded by habits), then you can fix it forever by just being more organised, no-one will ever know it was GTD, they just think you remembered for them.&lt;&#x2F;p&gt;
&lt;p&gt;Open up Trello on your phone or laptop and add a card. Or if it&#x27;s easier write an email to your GTD board!&lt;&#x2F;p&gt;
&lt;h4 id=&quot;using-alexa-siri-etc&quot;&gt;Using Alexa&#x2F;Siri etc&lt;&#x2F;h4&gt;
&lt;p&gt;For advanced magic teach your Siri&#x2F;Alexa&#x2F;Google to email to GTD by mere voice command&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hey google, email gtd ...&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Or maybe set up a custom action. (If anyone&#x27;s done this send me some details and I&#x27;ll expand out this section. PRs welcome!)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gtding&quot;&gt;GTDing&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;inbox-processing-daily&quot;&gt;Inbox Processing (Daily)&lt;&#x2F;h4&gt;
&lt;p&gt;Go through inbox cards and triage them as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Unactionable or not important?
&lt;ul&gt;
&lt;li&gt;Archive the card&lt;&#x2F;li&gt;
&lt;li&gt;or move to reference&lt;&#x2F;li&gt;
&lt;li&gt;or move to someday.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Less than 2 mins?
&lt;ul&gt;
&lt;li&gt;Do now.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;For someone else?
&lt;ul&gt;
&lt;li&gt;Move to &quot;waiting&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Need to just mull it over a bit?
&lt;ul&gt;
&lt;li&gt;Move to &quot;incubate&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;For future time&#x2F;date?
&lt;ul&gt;
&lt;li&gt;Add to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;calendar.google.com&#x2F;&quot;&gt;google calendar&lt;&#x2F;a&gt; as event or timed reminder and move to &quot;scheduled&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;More than single step to complete? (Even two really small steps counts)
&lt;ul&gt;
&lt;li&gt;Move to &quot;projects&quot;
&lt;ul&gt;
&lt;li&gt;and add a checklist.&lt;&#x2F;li&gt;
&lt;li&gt;For some multi-step things I keep it as a single card, put it in actions but put the next step in the title (e.g. &quot;something to do - call bob&quot;), and when I&#x27;ve done that step I update the title to the next step. It&#x27;s a bit less overhead than juggling multiple cards, but it&#x27;s a judgement call whether it&#x27;s worth a project card. I like project cards for things that are going to drag on over months.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Finally if none of the above then:
&lt;ul&gt;
&lt;li&gt;move to &quot;action items&quot;
&lt;ul&gt;
&lt;li&gt;and edit the card to make sure it&#x27;s doable in one go (add links, forms, phone numbers etc).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I&#x27;ve learned to do more of this in the Trello app when I have five idle minutes during the day so that when I sit down at the laptop I don&#x27;t use all the time just getting GTD straight.&lt;&#x2F;p&gt;
&lt;p&gt;I add some Trello labels to the cards so that I can tell whether a card is something I can pick up in any particular situation (do I need the laptop? good phone signal? good internet? do I need to be somewhere in particular?) The situational ones are all black with an &lt;code&gt;@&lt;&#x2F;code&gt; prefix, e.g. &lt;code&gt;@home&lt;&#x2F;code&gt; or &lt;code&gt;@good-internet&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;projects-weekly&quot;&gt;Projects (Weekly)&lt;&#x2F;h4&gt;
&lt;p&gt;Go through each project&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Do I still need this project (move to someday, or just archive the card if not).&lt;&#x2F;li&gt;
&lt;li&gt;Create next action card - use the &quot;convert checklist item to card&quot; feature of Trello.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;waiting-weekly&quot;&gt;Waiting (Weekly)&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Set due dates on the cards so that they&#x27;ll get highlighted if they are due chasing next time you  review.&lt;&#x2F;li&gt;
&lt;li&gt;Chase up if no action from others and past the due date (maybe fire off an email or WhatsApp).&lt;&#x2F;li&gt;
&lt;li&gt;Archive if dealt with, or move back to inbox if it&#x27;s thrown up other issues.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;rules-thou-shall-not-scroll&quot;&gt;Rules - Thou Shall Not Scroll&lt;&#x2F;h4&gt;
&lt;p&gt;I.e. things that I&#x27;ve learned knock me off track when trying to do a &quot;GTD&quot; session.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;DO NOT READ the articles - send them to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;getpocket.com&#x2F;&quot;&gt;Pocket&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;DO NOT READ the newsletters - leave them as unread in mail inbox.&lt;&#x2F;li&gt;
&lt;li&gt;NO twitter&#x2F;facebook&#x2F;linkedin FEED reading (posting is okay).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;dealing-with-action-items&quot;&gt;Dealing With Action Items&lt;&#x2F;h3&gt;
&lt;p&gt;Once your GTD board is triaged your inbox should be empty and your action items should be prioritized and full of things that you can &quot;just do&quot; without getting blocked. Start at the top and work down as if your boss told you to get on with it.&lt;&#x2F;p&gt;
&lt;p&gt;This is where the magic happens!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-to-do-when-action-items-is-too-long-or-not-getting-done&quot;&gt;What to do when &quot;Action Items&quot; is too long or not getting done&lt;&#x2F;h3&gt;
&lt;p&gt;I found that after a while Action items gets overwhelming. Cards end up stuck in there forever, never quite getting to done.&lt;&#x2F;p&gt;
&lt;p&gt;To deal with this, use the &quot;move all cards in list feature of Trello&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;You have two choices here depending on the state of your list and how important thing things in it are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Move all cards back to Inbox and re-triage them.&lt;&#x2F;li&gt;
&lt;li&gt;Move all the cards to &quot;Someday&quot; because they actually weren&#x27;t that important.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Or you might pick a few to bump back to inbox then move everything else.&lt;&#x2F;p&gt;
&lt;p&gt;This gives you a complete reset, and eliminates the mental overwhelm that results from an unrealistic todo list.&lt;&#x2F;p&gt;
&lt;p&gt;You might initially think this is a failure of the GTD method, but actually without GTD you are just forgetting things that have been on your brain&#x27;s todo list, and maybe some of them were actually important. With this approach you have the opportunity to decide what you want to punt to the eternal pot of &quot;someday&quot; with no angst that you are dropping important tasks.&lt;&#x2F;p&gt;
&lt;p&gt;If you have tasks that really are important and they are never getting done, then&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;you&#x27;re avoiding it and you need to move them to the top and just do them, a well formed action card is often not as bad when you actually tackle it,&lt;&#x2F;li&gt;
&lt;li&gt;or you don&#x27;t allocate sufficient time in your life for these tasks, and it&#x27;s up to you if you want to adjust your schedule to get more done.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;watch-out-for&quot;&gt;Watch Out For&lt;&#x2F;h3&gt;
&lt;p&gt;Spending all your time just arranging your GTD board and never doing any of the action items. Are you avoiding an unpleasant task? Are your tasks too big and need breaking down?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;when-the-lists-get-long&quot;&gt;When the lists get long&lt;&#x2F;h3&gt;
&lt;p&gt;You have to make sure you&#x27;re investing enough time on average for the piles not to build up and up.&lt;&#x2F;p&gt;
&lt;p&gt;When my list got to the several hundred range I needed to know for my own sanity whether I was winning or losing week by week, it&#x27;s hard to remember whether the inbox was on 197 or 185 the week before. Being a bit of a systems person not afraid of a spreadsheet, I enabled the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;addons.mozilla.org&#x2F;en-US&#x2F;firefox&#x2F;addon&#x2F;firefox-trello-card-counter&#x2F;&quot;&gt;firefox trello card counter addon&lt;&#x2F;a&gt;, manually copied them into a spreadsheet, added a graph, and now I can see if I need to spend more or less time getting on top of it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;gtd&#x2F;card-count-addon.png&quot; alt=&quot;firefox trello card counter in action&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;gtd&#x2F;card-count-graph.png&quot; alt=&quot;screenshot of card count spreadsheet&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve shared a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;spreadsheets&#x2F;d&#x2F;e&#x2F;2PACX-1vTJ--K37eyRik0kpBbwaGlH5p5nxfYliJDuRxkZmitntMBAnp4Cl0fW71drbvZxqQ6ApZB3LcL9XX8q&#x2F;pubhtml&quot;&gt;google sheets copy of the card count graph spreadsheet&lt;&#x2F;a&gt; which you can use yourself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;learn-more&quot;&gt;Learn more&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;ready-for-anything-book&quot;&gt;Ready for Anything Book&lt;&#x2F;h3&gt;
&lt;p&gt;David Allen wrote a follow-up book with a huge amount of wisdom and experience embedded in it. This one is like having a management consultant in your ear guiding you to be the CEO of your life and work. Amazing. Not to be missed once you have the basics down.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Ready-Anything-Productivity-Principles-Work&#x2F;dp&#x2F;B003L1FWHG&quot;&gt;&quot;Ready for Anything: 52 Productivity Principles for Work and Life&quot; by David Allen&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;podcast&quot;&gt;Podcast&lt;&#x2F;h3&gt;
&lt;p&gt;Having run this system for a while, it grew to a daunting few-hundred cards in inbox&#x2F;actions. To figure out what I&#x27;m doing wrong I did some more research.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gettingthingsdone.com&#x2F;category&#x2F;podcast-2&#x2F;&quot;&gt;official GTD podcast&lt;&#x2F;a&gt; is gold, hearing from the creator and his consultants on how they really use it and help clients get unstuck was really helpful.&lt;&#x2F;p&gt;
&lt;p&gt;Key points I learned:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Projects are not what you&#x27;d normally think of, they&#x27;re just anything bigger than one action. &lt;em&gt;Anything&lt;&#x2F;em&gt;. (You can add another layer for big projects if that&#x27;s your world).&lt;&#x2F;li&gt;
&lt;li&gt;The weekly review isn&#x27;t just shuffling your todo pile. It&#x27;s stepping back and considering the big picture, setting strategic direction, and just having time to reflect.&lt;&#x2F;li&gt;
&lt;li&gt;If tasks are getting stuck, or you are avoiding them it&#x27;s probably because you haven&#x27;t taken the time to step back and think clearly about whether it&#x27;s something you actually want to do (someday&#x2F;incubate&#x2F;delete), and if you do then thinking about what the one next step might be (e.g. &quot;google xx to learn more&quot; about it).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;articles&quot;&gt;Articles&lt;&#x2F;h3&gt;
&lt;p&gt;In no particular order, and of varying usefulness:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;facilethings.com&#x2F;blog&#x2F;en&#x2F;starting-gtd-when-you-are-busy&quot;&gt;https:&#x2F;&#x2F;facilethings.com&#x2F;blog&#x2F;en&#x2F;starting-gtd-when-you-are-busy&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lifehacker.com&#x2F;the-weekly-review-how-one-hour-can-save-you-a-week-s-w-5908816&quot;&gt;https:&#x2F;&#x2F;lifehacker.com&#x2F;the-weekly-review-how-one-hour-can-save-you-a-week-s-w-5908816&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;todoist.com&#x2F;productivity-methods&#x2F;getting-things-done&quot;&gt;https:&#x2F;&#x2F;todoist.com&#x2F;productivity-methods&#x2F;getting-things-done&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.doist.com&#x2F;gtd-tips&#x2F;&quot;&gt;https:&#x2F;&#x2F;blog.doist.com&#x2F;gtd-tips&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;gtd&#x2F;comments&#x2F;8bv3as&#x2F;how_do_i_keep_my_gtd_inbox_from_overflowing_to&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;gtd&#x2F;comments&#x2F;8bv3as&#x2F;how_do_i_keep_my_gtd_inbox_from_overflowing_to&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;plan.io&#x2F;blog&#x2F;getting-things-done&#x2F;&quot;&gt;https:&#x2F;&#x2F;plan.io&#x2F;blog&#x2F;getting-things-done&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.taskade.com&#x2F;blog&#x2F;outliner-note-taking&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.taskade.com&#x2F;blog&#x2F;outliner-note-taking&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.taskade.com&#x2F;blog&#x2F;getting-things-done-gtd&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.taskade.com&#x2F;blog&#x2F;getting-things-done-gtd&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.taskade.com&#x2F;blog&#x2F;hierarchical-note-taking&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.taskade.com&#x2F;blog&#x2F;hierarchical-note-taking&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zapier.com&#x2F;blog&#x2F;gtd-getting-things-done&#x2F;&quot;&gt;https:&#x2F;&#x2F;zapier.com&#x2F;blog&#x2F;gtd-getting-things-done&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;get-started-with-a-template-gtd-trello-board&quot;&gt;Get started with a template GTD+Trello board&lt;&#x2F;h2&gt;
&lt;p&gt;You can easily &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;trello.com&#x2F;b&#x2F;4L9ezgRP&#x2F;gtd-template&quot;&gt;create your own GTD Trello board from this template&lt;&#x2F;a&gt; that I&#x27;ve created for you.&lt;&#x2F;p&gt;
&lt;p&gt;The template contains:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Preconfigured columns,&lt;&#x2F;li&gt;
&lt;li&gt;Labels,&lt;&#x2F;li&gt;
&lt;li&gt;Some example cards,&lt;&#x2F;li&gt;
&lt;li&gt;A full instruction list in the inbox for daily processing,&lt;&#x2F;li&gt;
&lt;li&gt;A butler action button for moving to &quot;someday&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I reckon using this ready-made template will save you at least an half-an-hour of your time just fiddling with Trello to get going. It&#x27;d also be a nice way of saying thanks if you found this article useful.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;gtd-trello-template.png&quot; alt=&quot;Screenshot of my template&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;beyond-gtd&quot;&gt;Beyond GTD&lt;&#x2F;h2&gt;
&lt;p&gt;I still struggle with what to do &lt;em&gt;today&lt;&#x2F;em&gt; even with GTD in place. I&#x27;ve found the (paid) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sunsama.com&#x2F;&quot;&gt;Sunsama&lt;&#x2F;a&gt; app to be a game changer, especially as I transition to full business owner from sole contractor. You could do it without, but having an app that continuously reminds you what you planned to do today &amp;amp; this week makes sticking to priorities so much easier.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;gtd-sunsama.png&quot; alt=&quot;Sunsama app asking &amp;quot;what do you want to get done today?&amp;quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Approaches to refactoring, technical debt and legacy code</title>
        <published>2020-07-09T00:00:00+00:00</published>
        <updated>2020-07-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/07/09/approaches-to-refactoring-and-technical-debt/"/>
        <id>https://0x5.uk/2020/07/09/approaches-to-refactoring-and-technical-debt/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/07/09/approaches-to-refactoring-and-technical-debt/">&lt;p&gt;Sometimes a codebase has an overwhelming amount of &quot;terrible&quot; stuff that as a developer you almost can&#x27;t help but just diving in and fixing it. Doing this without thinking too hard can result in many variations of failure, such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Upsetting the people paying you because you are doing something they don&#x27;t consider important.&lt;&#x2F;li&gt;
&lt;li&gt;Never finishing the mammoth rewrite you took on, resulting in a mess of two different styles of code.&lt;&#x2F;li&gt;
&lt;li&gt;Personal burnout.&lt;&#x2F;li&gt;
&lt;li&gt;Fixing things that maybe weren&#x27;t actually that important (even if they make you cry whenever you have to look at their source code), at the expense of failing to fix more urgent problems or building useful features.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This article is a collection of research, links, thoughts and ideas that I&#x27;ve captured here for both of our benefits. It&#x27;s a bit disjointed to read, but the point was more to capture all the key concepts and resources that are floating around in tech land.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;⏩ If you want the executive summary, head over to my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;charmconsulting.co.uk&#x2F;2020&#x2F;11&#x2F;27&#x2F;leaders-guide-to-technical-debt&#x2F;&quot;&gt;Leaders guide to technical debt - aka &quot;why can&#x27;t we ship anything!?&quot;&lt;&#x2F;a&gt; 🧐. For the technical details read on below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;debt-cloud.png&quot; alt=&quot;word cloud from article&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;must-read-articles&quot;&gt;Must-read articles&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s a couple of must-read articles on the subject:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;refactoring&quot;&gt;Refactoring&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;We take the next feature that we are asked to build, and instead of detouring around all the weeds and bushes, we take the time to clear a path through some of them.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Ron Jeffries&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In short, don&#x27;t make debt cleanup its own task, just tackle what gets in your way as you go, and leave the camp tidier than you found it.&lt;&#x2F;p&gt;
&lt;p&gt;I recommend reading the whole article here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ronjeffries.com&#x2F;xprog&#x2F;articles&#x2F;refactoring-not-on-the-backlog&#x2F;&quot;&gt;Refactoring -- Not on the backlog! by Ron Jeffries&lt;&#x2F;a&gt;, it&#x27;s not too long.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;technical-debt&quot;&gt;Technical Debt&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Tech debt&quot;: an overloaded term. There are at least 5 distinct things we mean [when] we say “technical debt”.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Maintenance work&lt;&#x2F;li&gt;
&lt;li&gt;Features of the codebase that resist change&lt;&#x2F;li&gt;
&lt;li&gt;Operability choices that resist change&lt;&#x2F;li&gt;
&lt;li&gt;Code choices that suck the will to live&lt;&#x2F;li&gt;
&lt;li&gt;Dependencies that resist upgrading&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Read the full explanation of each type of debt here: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;laughingmeme.org&#x2F;2016&#x2F;01&#x2F;10&#x2F;towards-an-understanding-of-technical-debt&#x2F;&quot;&gt;Towards an understanding of technical debt by Kellan Elliott-McCrea&lt;&#x2F;a&gt;, a bit longer but an important piece of writing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;huge-piles-of-debt&quot;&gt;Huge piles of debt&lt;&#x2F;h2&gt;
&lt;p&gt;If your project is sooo &quot;bad&quot; that you feel like throwing it out, you might do well to heed this quote:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;There is only one way to eat an elephant: a bite at a time.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.psychologytoday.com&#x2F;us&#x2F;blog&#x2F;mindfully-present-fully-alive&#x2F;201804&#x2F;the-only-way-eat-elephant&quot;&gt;Desmond Tutu (via Psychology today of all places!)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Which to me means iterate your way to good.&lt;&#x2F;p&gt;
&lt;p&gt;It doesn&#x27;t mean have no plan, in fact you should know where you are trying to get to and how realistic that is so you don&#x27;t end up with a rewrite that can never be completed because it was too ambitious.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;even-more-reading&quot;&gt;Even more reading&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;is-a-mess-a-debt&quot;&gt;Is a mess a debt?&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;A mess is not a technical debt. A mess is just a mess.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Uncle Bob&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sites.google.com&#x2F;site&#x2F;unclebobconsultingllc&#x2F;a-mess-is-not-a-technical-debt&quot;&gt;A Mess is not a Technical Debt by Uncle Bob&lt;&#x2F;a&gt; suggests that the use of the term debt is for a considered short term trade-off just like taking out a loan, but a mess is nothing of the sort as there is no up-side to creating a mess versus having a clean but temporary solution to a problem.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;more-taxonomy-of-bad-code-the-reckless-prudent-vs-deliberate-indavertent-quadrant&quot;&gt;More taxonomy of bad code: the Reckless&#x2F;Prudent vs Deliberate&#x2F;Indavertent quadrant&lt;&#x2F;h3&gt;
&lt;p&gt;Martin Fowler shows that you can categorize debt by whether it is reckless or prudent, and separately whether it was deliberately or inadvertently added to the code.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Technical Debt is a metaphor, so the real question is whether or not the debt metaphor is helpful about thinking about how to deal with design problems, and how to communicate that thinking. A particular benefit of the debt metaphor is that it&#x27;s very handy for communicating to non-technical people.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;The useful distinction isn&#x27;t between debt or non-debt, but between prudent and reckless debt ... there&#x27;s also a difference between deliberate and inadvertent debt.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;The decision of paying the interest versus paying down the principal still applies, so the metaphor is still helpful for this case.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;martinfowler.com&#x2F;bliki&#x2F;TechnicalDebtQuadrant.html&quot;&gt;The Technical Debt Quadrant by Martin Fowler&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;These are useful definitions that can help clearly communicate complex issues with the code to people not directly involved in the code.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s well worth reading much more of Martin Fowler&#x27;s writing. There&#x27;s so much to learn from Martin about programming good practice; the articles are all written in a very human and accessible style.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;legacy-tests&quot;&gt;Legacy tests&lt;&#x2F;h3&gt;
&lt;p&gt;Now that TDD is widely adopted we&#x27;re faced with cleaning up the output of those who &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cargo_cult_programming&quot;&gt;cargo-culted&lt;&#x2F;a&gt; test coverage, or had well meaning but ultimately badly formed attempts at adding tests to their code, sometimes with prodigious volumes of test code.&lt;&#x2F;p&gt;
&lt;p&gt;I think &quot;Legacy tests&quot; is a useful term to describe these problematic tests. Nat Pryce outlines some useful hints that you have legacy tests on your hands:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Symptoms of legacy tests I have encountered include:&lt;br &#x2F;&gt;
...&lt;br &#x2F;&gt;
Tests are named after issue identifiers in the company&#x27;s issue tracker.&lt;br &#x2F;&gt;
Bonus points if the issue tracker no longer exists.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Nat Pryce, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;natpryce.com&#x2F;articles&#x2F;000813.html&quot;&gt;Working Effectively with Legacy Tests&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;prevention-is-better-than-cure&quot;&gt;Prevention is better than cure&lt;&#x2F;h2&gt;
&lt;p&gt;How do we stop it building up in the first place?&lt;&#x2F;p&gt;
&lt;p&gt;I see several sources of the build up of technical debt:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Lack of knowledge and experiencd of programming patterns and practices to keep debt in check. This can be addressed with courses, learning from peers, attending meetups and conferences, reading books, watching youtube and many other ways of getting input from beyond the current code editor.&lt;&#x2F;li&gt;
&lt;li&gt;Problematic mindsets in programmers - short term thinking, narrow thinking, or blindness to the broader consequences of the choices being made in the moment. This is a more stubborn malaise, and people are not quick to change their identity. Some will respond well to just being asked to consider the second and third order effects of their choices (e.g. &quot;you could give this other team direct access to the sql db instead building an API for them, and yes it&#x27;s quicker, but then you won&#x27;t ever again be able to rename a column without consulting with them), but some people will double down in their thinking and are not open to improvement.&lt;&#x2F;li&gt;
&lt;li&gt;Dysfunctional dynamics between engineering and their non-technical peers and leaders. Common issues include:
&lt;ol&gt;
&lt;li&gt;Deadline-driven-development (especially when unrealistic and vigorously enforced),&lt;&#x2F;li&gt;
&lt;li&gt;Asking non-technical leaders to make engineering decisions.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;The client &#x2F; boss &#x2F; project manager responds [whilst thinking “I have no idea what you are talking about, or why you are asking] “Which is quicker? Do that one.”&lt;&#x2F;p&gt;
&lt;p&gt;Then the engineer gets the hump that they can’t do a good job.&lt;&#x2F;p&gt;
&lt;p&gt;~ from &lt;a href=&quot;&#x2F;2024&#x2F;03&#x2F;27&#x2F;why-do-automated-tests-matter&#x2F;#programmer-excuses&quot;&gt;&quot;Why do automated tests matter?&quot; by Tim Abell&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;the-audio-version-from-codurance&quot;&gt;The audio version from Codurance&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codurance.com&#x2F;&quot;&gt;Codurance&lt;&#x2F;a&gt; hosted an insightful round-table podcast episode with a group of people who are clearly very experienced. You can listen here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codurance.com&#x2F;podcasts&#x2F;2019-01-21-legacy-code&#x2F;&quot;&gt;https:&#x2F;&#x2F;codurance.com&#x2F;podcasts&#x2F;2019-01-21-legacy-code&#x2F;&lt;&#x2F;a&gt; and will doubtless be inspired by some things in there. The conversation takes a little while to build momentum but it&#x27;s worth the wait.&lt;&#x2F;p&gt;
&lt;p&gt;Here some highlights of what I learnt from listening to the show:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-feathers-book&quot;&gt;The Feathers Book&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Working-Effectively-Legacy-Michael-Feathers&#x2F;dp&#x2F;0131177052&#x2F;&quot;&gt;Working Effectively with Legacy Code by Michael C. Feathers&lt;&#x2F;a&gt; is &lt;em&gt;the&lt;&#x2F;em&gt; book to read on the subject.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Feathers defines legacy code as code without tests.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Preserving behaviour is a large challenge. When we need to make changes and preserve behaviour, it can involve considerable risk.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Michael C. Feathers&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This book is heavily geared towards unpicking the difficulties in getting untested code under test in object-oriented static typed languages such as Java, C# and C++, and modifying it safely.&lt;&#x2F;p&gt;
&lt;p&gt;It is a detailed and thorough treatment of all the tactics available to bring untested object-oriented code under test, specifically sprawling and smelly classes and methods. It won&#x27;t help you with larger scale problems such as poor structuring of microservice architecture, message bus systems etc.&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;understandlegacycode.com&#x2F;blog&#x2F;key-points-of-working-effectively-with-legacy-code&#x2F;&quot;&gt;article summarizing the Feathers&#x27; Legacy Code book&lt;&#x2F;a&gt; has some of the tactics detailed and gives a good flavour of the book so you can decide whether to dive deeper.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;named-techniques-and-related-libraries&quot;&gt;Named techniques and related libraries&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;michaelfeathers.silvrback.com&#x2F;characterization-testing&quot;&gt;Characterization testing&lt;&#x2F;a&gt; is the idea of creating tests to probe and demonstrate the existing behaviour of previously untested code.
&lt;ul&gt;
&lt;li&gt;Related to this is &quot;approval tests&quot; which allow you to easily incorporate snapshots of output (json, xml, logs etc) into your tests in order to capture existing behaviour and be able to spot any variations that pop up during refactoring.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;approvals&#x2F;ApprovalTests.Net&quot;&gt;ApprovalTests.net&lt;&#x2F;a&gt; is a dotnet library for implementing approval tests.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Introducing &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wiki.c2.com&#x2F;?SoftwareSeam&quot;&gt;seams&lt;&#x2F;a&gt; into software can be a useful technique for breaking down untestable monoliths into testable chunks on the way to better code.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mutation_testing&quot;&gt;Mutation testing (wikipedia)&lt;&#x2F;a&gt; (more info on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;csharp.academy&#x2F;mutation-testing&#x2F;&quot;&gt;mutation testing at csharp academy&lt;&#x2F;a&gt;) is a useful way of checking how good your test coverage really is. It is the idea of making (almost) random changes to the code under test to see what whether your tests spot the change in behaviour.
&lt;ul&gt;
&lt;li&gt;For dotnet this can be done with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;stryker-mutator&#x2F;stryker-net&quot;&gt;Stryker.net&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;approaches-from-hard-won-experience&quot;&gt;Approaches from hard-won experience&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Make as few changes as possible to get untested production code under test. The first cut of tests will likely be fragile.&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s more important that legacy code that is already in production continues to behave as it currently does than that it behaves as originally specified. People and downstream systems may now rely on that &quot;incorrect&quot; behaviour.&lt;&#x2F;li&gt;
&lt;li&gt;Does the organisation (culture, systems, pressures etc.) cause bad code to be created? If you don&#x27;t fix that then you will always get more &quot;legacy&quot; code.&lt;&#x2F;li&gt;
&lt;li&gt;The importance of competent technical leadership within an organisation for preventing the build up of catastrophic levels of technical debt.&lt;&#x2F;li&gt;
&lt;li&gt;When communicating, quantify the cost of problems with the legacy code. E.g. &quot;you are losing 1 in 5 developer-days to coping with bugs introduced due to the lack of automated regression tests&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Have the hard conversations with the business about the cost of fixing the mess.&lt;&#x2F;li&gt;
&lt;li&gt;Doing a rewrite is (almost) always the wrong answer.&lt;&#x2F;li&gt;
&lt;li&gt;Get small wins, even if you are facing a huge challenge.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;maybe-modelling-is-the-problem&quot;&gt;Maybe modelling is the problem&lt;&#x2F;h2&gt;
&lt;p&gt;Something that looks like bad code could be that way because of a failure to properly model the real world.&lt;&#x2F;p&gt;
&lt;p&gt;Domain Driven Design (DDD) has much to teach on the matter, and this is a great video on the why modelling could be the problem:
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;d2Ddo8OV7ig&quot;&gt;Technical debt isn&#x27;t technical - Einar Høst - DDD Europe 2019 - YouTube&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;small-batches-automated-testing-podcast-episode&quot;&gt;Small Batches Automated Testing Podcast Episode&lt;&#x2F;h2&gt;
&lt;p&gt;Podcast episode &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;share.transistor.fm&#x2F;s&#x2F;a5ca21cb&quot;&gt;Software Delivery in Small Batches: Automated Testing with Jason Swett&lt;&#x2F;a&gt; talks about practical approaches to legacy code, including the idea that you actually can&#x27;t always avoid writing some more untested code because of the cost-benefit trade-off.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;You can’t just slap a test on any change that you make because the underlying functionality might be really complex&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The episode describes the evolution of our industry in learning the importance of test coverage for avoiding known risks in software development, and declares that you cannot truly call yourself a professional developer if you are not writing tests.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I always recommend starting with the easiest most trivial stuff, adding some tests in those areas and then working up to the bigger areas&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Some relevant thoughts from the episode:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Good test coverage is a pre-requisite to any higher-level automation such as continuous-deployment. (1:35)&lt;&#x2F;li&gt;
&lt;li&gt;To add tests to a project that has no coverage you have to retrofit test tooling and infrastructure (CI, data management etc). &quot;That can be very non-trivial, even for someone very experienced, ... it&#x27;s going to be a huge challenge to add that stuff retroactively.&quot; (3:10)&lt;&#x2F;li&gt;
&lt;li&gt;With regards to the idea of &quot;Declaring that we are going to write tests for every PR from now on.&quot; (7:10)
&lt;ul&gt;
&lt;li&gt;&quot;You can&#x27;t just slap a test on any change that you make because the underlying functionality might be really complex. In order to write a test you might have to have certain setup data to create the state required for that test might be extremely complicated. To expect somebody to include a test with every PR is not realistic. For some features your change might be 10 minutes of work but to get the test setup, that might be weeks of work in order to take the 20-minutes to write the test.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;I always recommend starting with the easiest most trivial stuff, adding some tests in those areas and then working up to the bigger areas. It seems that you should start with the most important stuff but that&#x27;s not realistic because the most important stuff is also the hardest to test.&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;A useful step might be to just get tests in place on your own machine without worrying about CI initially (they were talking about training a developer, but it&#x27;s a useful thought for being efficient tackling legacy projects) (9:30)&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Having high quality code is almost impossible without good test coverage. Test coverage enables refactoring. If you can&#x27;t refactor your code it&#x27;s really hard to keep it in good shape.&quot; (17:15)&lt;&#x2F;li&gt;
&lt;li&gt;As you flush out bugs by adding more and more coverage: &quot;The type of issues you find over time, the complexity goes up, because they&#x27;re not really related to the interplay of something known, they&#x27;re usually related to more and more complications; instead of just one unit of code interacting... [it&#x27;s] 5 or 10 or 200; these larger components and permutations that you never considered in the first place, because some customer hit it for the first time.&quot; Moments where you go &quot;woah I never even knew that was possible&quot; (25:50)&lt;&#x2F;li&gt;
&lt;li&gt;&quot;It all comes down to managing risk, risk of the software in question being correct&quot; (30:20)
&lt;ul&gt;
&lt;li&gt;&quot;There&#x27;s a risk of producing incorrect software, but there&#x27;s also a risk to the business that the engineers will not be able to keep pace with the business if they have to spend so much extra time just verifying the software, there&#x27;s a mistake in thinking that writing tests takes more time, the reality is that if you have automated tests then you will be able to work much faster than if you didn&#x27;t&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;On a project that had tests once - &quot;...at some point tests had stopped passing&quot;, should you &quot;blow them away or fix them?&quot;. (32:22)
&lt;ul&gt;
&lt;li&gt;For an &quot;application that&#x27;s been developed for two years with no tests with this big team and they don&#x27;t have the skills; that&#x27;s going to be a big up front investment, it&#x27;s going to be a year or two before [adding test coverage] starts to pay off.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;... at some point tests had stopped passing and they were never updated - okay do I trust these or not? If they&#x27;re not passing, do I blow them away or fix them.&quot; - In this case blew them away and spent three months writing tests such that he could build new features. &quot;Even now [the project has] low test coverage. This has been a multi-year effort.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;This is one of the real problems when it comes to testing, is that if for some reason the people who start the project don&#x27;t do testing, and the project is successful enough to go on for X number of years without it, then the effort required to add testing after the fact is an order of magnitude than it would have been at the beginning.&quot; ... &quot;the can gets kicked down the road.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Frustrated by the attitude of &#x27;let&#x27;s not spend time making this code high quality because what if this startup fails&#x27; but what if this startup succeeds? Yes it may be possible you only survive by cutting corners but not convinced, think it might be a delusion.&quot;
&lt;ul&gt;
&lt;li&gt;&quot;The only way to go fast is to go well.&quot; ~ Bob Martin&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Why is good code good? It&#x27;s fast to work with. I prefer to say &#x27;the code is understandable&#x27; because that makes it more clear. Good&#x2F;bad sounds like inward looking practicing of a craft. &#x27;Not Understandable&#x27; is more tangible - that means it&#x27;s time-consuming and expensive to work with. Understandable code is faster and less expensive to work with.&quot; (35:20)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;It all comes down to managing risk&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The people on the episode are Ruby developers, but the lessons they talk of apply regardless of language.&lt;&#x2F;p&gt;
&lt;p&gt;(Some of the quotations above are paraphrased)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;thanks-now-i-m-even-less-sure-what-to-do&quot;&gt;Thanks, now I&#x27;m even less sure what to do&lt;&#x2F;h2&gt;
&lt;p&gt;Are you wrestling with something you don&#x27;t like in a codebase you have to deal with? I&#x27;m guessing that&#x27;s why you&#x27;re here. Or maybe someone sent you this along with a rant about the tech debt in the codebase you own.&lt;&#x2F;p&gt;
&lt;p&gt;Either way, I suggest slowing down a bit, sitting down together (while maintaining social distancing), and considering how all the things that bother you about the code in front of you fit in to the various taxonomies detailed above. Then use that assessment to make a calm and rational plan about roughly where you want to get to. Then decide on the &lt;em&gt;one&lt;&#x2F;em&gt; next thing you will do towards that. Use the Ron Jeffries approach to get you there without wasting time on things that don&#x27;t really matter.&lt;&#x2F;p&gt;
&lt;p&gt;Practically, that might mean if you have a user story, ticket or Trello card for a feature, it might take longer to do as you include the work to &quot;pay down&quot; some of that badness along the way, knowing that it will improve your overall velocity over time. Be wary of pulling out separate &quot;debt&quot; stories to do, though that can work if the team dynamic is right.&lt;&#x2F;p&gt;
&lt;p&gt;To keep your stress levels down make it a shared team problem, have a bit of a laugh about it, take regular breaks in the great outdoors, and support each other.&lt;&#x2F;p&gt;
&lt;p&gt;Good luck!&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll leave you with this little song I found on YouTube about bugs:&lt;&#x2F;p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;kuJI4hmvY8c&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;&#x2F;h2&gt;
&lt;p&gt;If you want to avoid the task at hand by reading the whole internet in the hope that it will help, start here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A lengthy set of opinions on what to do with a huge 10 year old untested pile of spaghetti code:  &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;questions&#x2F;416242&#x2F;is-it-the-correct-practice-to-keep-more-than-10-years-old-spaghetti-legacy-code&quot;&gt;https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;questions&#x2F;416242&#x2F;is-it-the-correct-practice-to-keep-more-than-10-years-old-spaghetti-legacy-code&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Pluralsight have written an excellent long-form article on the subject: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pluralsight.com&#x2F;blog&#x2F;software-development&#x2F;erasing-tech-debt&quot;&gt;https:&#x2F;&#x2F;www.pluralsight.com&#x2F;blog&#x2F;software-development&#x2F;erasing-tech-debt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The Engineering Manager on technical debt: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theengineeringmanager.com&#x2F;growth&#x2F;how-to-argue-the-space-to-tackle-technical-debt&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.theengineeringmanager.com&#x2F;growth&#x2F;how-to-argue-the-space-to-tackle-technical-debt&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;adevait.com&#x2F;software&#x2F;technical-debt&quot;&gt;https:&#x2F;&#x2F;adevait.com&#x2F;software&#x2F;technical-debt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@adamberlinskyschine&#x2F;wtf-is-technical-debt-b9e9d5f89d9&quot;&gt;https:&#x2F;&#x2F;medium.com&#x2F;@adamberlinskyschine&#x2F;wtf-is-technical-debt-b9e9d5f89d9&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wtfismyengineertalkingabout.com&#x2F;2017&#x2F;03&#x2F;18&#x2F;wtf-is-technical-debt&#x2F;&quot;&gt;https:&#x2F;&#x2F;wtfismyengineertalkingabout.com&#x2F;2017&#x2F;03&#x2F;18&#x2F;wtf-is-technical-debt&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codingsans.com&#x2F;blog&#x2F;technical-debt&quot;&gt;https:&#x2F;&#x2F;codingsans.com&#x2F;blog&#x2F;technical-debt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;builtin.com&#x2F;software-engineering-perspectives&#x2F;technical-debt&quot;&gt;https:&#x2F;&#x2F;builtin.com&#x2F;software-engineering-perspectives&#x2F;technical-debt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bmc.com&#x2F;blogs&#x2F;technical-debt-explained-the-complete-guide-to-understanding-and-dealing-with-technical-debt&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.bmc.com&#x2F;blogs&#x2F;technical-debt-explained-the-complete-guide-to-understanding-and-dealing-with-technical-debt&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dzone.com&#x2F;articles&#x2F;what-technical-debt-it-and-how-to-calculate-it&quot;&gt;https:&#x2F;&#x2F;dzone.com&#x2F;articles&#x2F;what-technical-debt-it-and-how-to-calculate-it&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bigrivertech.com&#x2F;technical_debt_assessment&#x2F;&quot;&gt;https:&#x2F;&#x2F;bigrivertech.com&#x2F;technical_debt_assessment&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cutter.com&#x2F;consulting&#x2F;technical-debt-assessment-and-valuation&quot;&gt;https:&#x2F;&#x2F;www.cutter.com&#x2F;consulting&#x2F;technical-debt-assessment-and-valuation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;martinfowler.com&#x2F;tags&#x2F;technical%20debt.html&quot;&gt;https:&#x2F;&#x2F;martinfowler.com&#x2F;tags&#x2F;technical%20debt.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeclimate.com&#x2F;blog&#x2F;10-point-technical-debt-assessment&#x2F;&quot;&gt;https:&#x2F;&#x2F;codeclimate.com&#x2F;blog&#x2F;10-point-technical-debt-assessment&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;thinkapps.com&#x2F;blog&#x2F;development&#x2F;technical-debt-calculation&#x2F;&quot;&gt;http:&#x2F;&#x2F;thinkapps.com&#x2F;blog&#x2F;development&#x2F;technical-debt-calculation&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.productplan.com&#x2F;glossary&#x2F;technical-debt&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.productplan.com&#x2F;glossary&#x2F;technical-debt&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;leadership.garden&#x2F;tips-on-prioritizing-tech-debt&quot;&gt;https:&#x2F;&#x2F;leadership.garden&#x2F;tips-on-prioritizing-tech-debt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.steveonstuff.com&#x2F;2022&#x2F;01&#x2F;27&#x2F;no-such-thing-as-clean-code&quot;&gt;https:&#x2F;&#x2F;www.steveonstuff.com&#x2F;2022&#x2F;01&#x2F;27&#x2F;no-such-thing-as-clean-code&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;leadership.garden&#x2F;tips-on-prioritizing-tech-debt&#x2F;&quot;&gt;https:&#x2F;&#x2F;leadership.garden&#x2F;tips-on-prioritizing-tech-debt&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=1MBpK_PxEnU&quot;&gt;Youtube: &quot;Types Of Technical Debt And How To Manage Them&quot; ~ Dave Farley&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Sense of design&quot; over life of system, not just good design up front.&lt;&#x2F;li&gt;
&lt;li&gt;Measure of quality is ability to make changes&lt;&#x2F;li&gt;
&lt;li&gt;Metaphors for different types of tech debt:
&lt;ul&gt;
&lt;li&gt;Family loan&lt;&#x2F;li&gt;
&lt;li&gt;Bank loan (lack of tests)&lt;&#x2F;li&gt;
&lt;li&gt;Loan shark (visit from knuckles)&lt;&#x2F;li&gt;
&lt;li&gt;Organised crime loan (fatal if not repaid. Legacy technology)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=kf1GzhiI9yQ&quot;&gt;Youtube: &quot;7 Ways to Get Ahead of Technical Debt &amp;amp; Keep It Under Control&quot; ~ Rob Walling &amp;amp; Derek Reimer&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Seen a business acquisition fail due to tech debt found during &quot;due diligence&quot;!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The &quot;Lava Flow&quot; anti-pattern where code is written, ossifies and leaves an archaeological record of all previous design attempts, libraries and technologies in the current production code rather than the git logs where they belong
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mikehadlow.blogspot.com&#x2F;2014&#x2F;12&#x2F;the-lava-layer-anti-pattern.html&quot;&gt;https:&#x2F;&#x2F;mikehadlow.blogspot.com&#x2F;2014&#x2F;12&#x2F;the-lava-layer-anti-pattern.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;antipatterns.com&#x2F;lavaflow.htm&quot;&gt;http:&#x2F;&#x2F;antipatterns.com&#x2F;lavaflow.htm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lava_flow_(programming)&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lava_flow_(programming)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Personal backlogs</title>
        <published>2020-06-30T00:00:00+00:00</published>
        <updated>2020-06-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/06/30/personal-backlogs/"/>
        <id>https://0x5.uk/2020/06/30/personal-backlogs/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/06/30/personal-backlogs/">&lt;h2 id=&quot;what-s-wrong-with-our-current-backlog-icebucket-todo-list&quot;&gt;What&#x27;s wrong with our current backlog &#x2F; icebucket &#x2F; todo list?&lt;&#x2F;h2&gt;
&lt;p&gt;Do you have a backlog of doom? A bottomless bucket full of probably unimportant things you possibly should do, interspersed with the occasional really import thing that will bite you hard if you don&#x27;t do it? Do you spend time repeatedly refining the list to make sure you don&#x27;t miss the important things? Or do you just ignore it and hope luck will save you from the things you let slip?&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve known for a long time that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;basecamp.com&#x2F;shapeup&#x2F;2.1-chapter-07#no-backlogs&quot;&gt;basecamp promote having no backlog at all&lt;&#x2F;a&gt;, based on the idea that it takes too much time and anything important will come up again anyway. To some extent I agree, but I have also found serious issues in systems that are perhaps less visible to the naked eye which will for sure have a consequence if not addressed (maybe something that is quietly corrupting data or failing to store it, or maybe a security issue).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;so-what-should-we-do-instead&quot;&gt;So what should we do instead?&lt;&#x2F;h2&gt;
&lt;p&gt;The answer came to me when I read &lt;a href=&quot;&#x2F;2019&#x2F;11&#x2F;26&#x2F;time-to-shape-up-your-scrum-process-the-new-thing-from-basecamp&#x2F;&quot;&gt;basecamp&#x27;s new Shape Up book (summarized here)&lt;&#x2F;a&gt; that describes their unique way of working. They don&#x27;t have a shared backlog, instead they leave it to each person in the organisation to use whatever method they choose to remember what &lt;em&gt;they&lt;&#x2F;em&gt; think is important, and then bring that to the table for consideration at the scheduled times that new work is considered.&lt;&#x2F;p&gt;
&lt;p&gt;The full shape-up process is a bit too much of a jump for the teams I usually work on, however I shared the above with a team I worked with, and they took it and came up with an excellent best-of-both-worlds solution. And it&#x27;s so good I think everyone should use it.&lt;&#x2F;p&gt;
&lt;p&gt;This solution...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;perfectly balances the elimination of a backlog-of-doom nightmare,&lt;&#x2F;li&gt;
&lt;li&gt;addresses the need to not lose important ideas as team members change,&lt;&#x2F;li&gt;
&lt;li&gt;and adds the ability to collaborate.&lt;&#x2F;li&gt;
&lt;li&gt;is ridiculously simple&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;trello&quot;&gt;Trello&lt;&#x2F;h3&gt;
&lt;p&gt;Set it up as follows: Set up a new trello board, name it &quot;shared backlog&quot; or similar, create a list (column) for every team member with their name (and optionally role) as the list title.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;shared-backlog.png&quot; alt=&quot;screenshot of shared backlog board in trello&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now when anyone thinks of anything that the team should possibly do, they add a card &lt;strong&gt;to their own list&lt;&#x2F;strong&gt; on the shared backlog trello board. It is now clear who owns the idea and is responsible for campaigning to get it prioritized.&lt;&#x2F;p&gt;
&lt;p&gt;In preparation for the next planning session each person organises their own list so that the things they think are most important are on the top.&lt;&#x2F;p&gt;
&lt;p&gt;On a regular basis, (say fortnightly during a sprint planning session or similar), the team goes through the board, and each person talks about their top one or two cards to say why they think it should be included in the sprint. The cards that are chosen by the team get added to the sprint to be done as part of the normal work for the team, thus making sure they actually happen.&lt;&#x2F;p&gt;
&lt;p&gt;Simple eh?&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s an example board &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;trello.com&#x2F;b&#x2F;cxRXPgcb&#x2F;personal-backlogs-example&quot;&gt;https:&#x2F;&#x2F;trello.com&#x2F;b&#x2F;cxRXPgcb&#x2F;personal-backlogs-example&lt;&#x2F;a&gt;, you can use it as a template if you wish.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;jira&quot;&gt;Jira&lt;&#x2F;h3&gt;
&lt;p&gt;If you&#x27;re using Jira you can achieve the same effect by abusing the &quot;sprint&quot; feature. Just create some extra sprints with the &quot;Create spring&quot; button and instead of calling them &quot;sprint 25&quot; etc, call them &quot;Tech backlog&quot;, &quot;Design Backlog&quot;, &quot;Customer Service Backlog&quot; etc. Then you can nicely group each role&#x27;s needs and they can manage their own priorities within their own backlog. The actual &quot;backlog&quot; in Jira can now be just for true user stories &#x2F; product features.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;jira-personal-backlogs.png&quot; alt=&quot;screenshot of using sprints as personal backlogs in Jira&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;useful&quot;&gt;Useful?&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;contact&quot;&gt;Let me know&lt;&#x2F;a&gt; if you use this approach and if it works for you or not.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-about-normal-feature-development&quot;&gt;What about normal feature development?&lt;&#x2F;h2&gt;
&lt;p&gt;You could theoretically have the product owner manage all the forthcoming product features in their column. I think it is better for them to continue to manage the product&#x27;s feature backlog in the existing jira&#x2F;trello&#x2F;github project system, which will now be beautifully free from tech debt, random ideas and other clutter. This is what we did and it worked great.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-ideas&quot;&gt;Bonus ideas&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Add a label &quot;next sprint&quot;, and get people to tag the cards they think should happen next.&lt;&#x2F;li&gt;
&lt;li&gt;Technical debt often ends up here, read this &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;laughingmeme.org&#x2F;2016&#x2F;01&#x2F;10&#x2F;towards-an-understanding-of-technical-debt&#x2F;&quot;&gt;http:&#x2F;&#x2F;laughingmeme.org&#x2F;2016&#x2F;01&#x2F;10&#x2F;towards-an-understanding-of-technical-debt&#x2F;&lt;&#x2F;a&gt; to be able to talk more coherently about this topic.&lt;&#x2F;li&gt;
&lt;li&gt;Turn on voting in trello and vote on each other&#x27;s cards.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;did-it-work-for-you&quot;&gt;Did it work for you?&lt;&#x2F;h2&gt;
&lt;p&gt;This setup worked superbly for us as a team and I&#x27;d recommend it to anyone who&#x27;ll listen.&lt;&#x2F;p&gt;
&lt;p&gt;We no longer have the overhead of a product owner losing the will to live trying to understand cryptic tech debt cards left by a previous developer, wondering if they were trivial or pending catastrophes.&lt;&#x2F;p&gt;
&lt;p&gt;When someone leaves, the new person or others on the team can look over their cards and decide what to move into their own column.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;also-available-on-the-podcast&quot;&gt;Also available on the podcast&lt;&#x2F;h2&gt;
&lt;p&gt;If you like this, you might want to have a listen to me and David talking about this and other lessons learned in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pod.timwise.co.uk&#x2F;8&quot;&gt;episode 8 of software should be free - Hiding from Covid-19 and the end of 2 years at DfE&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;A very similar idea of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;longform.asmartbear.com&#x2F;jit-backlogs&#x2F;&quot;&gt;&quot;JIT selection from independent streams&quot; by Jason Cohen (aka A Smart Bear)&lt;&#x2F;a&gt; which is well worth reading.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fast backup to external drive with lz4</title>
        <published>2020-04-23T00:00:00+00:00</published>
        <updated>2020-04-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/04/23/fast-backup-to-external-drive-with-lz4/"/>
        <id>https://0x5.uk/2020/04/23/fast-backup-to-external-drive-with-lz4/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/04/23/fast-backup-to-external-drive-with-lz4/">&lt;p&gt;The simplest backup is to just tar-gz your home directory, but it&#x27;s painfully
slow. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.luxagen.com&#x2F;2016&#x2F;build-backups-an-unexpected-journey&#x2F;&quot;&gt;A friend&lt;&#x2F;a&gt; put me on to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lz4.github.io&#x2F;lz4&#x2F;&quot;&gt;lz4&lt;&#x2F;a&gt; which isn&#x27;t installed by default in ubuntu &amp;amp;
mint, it moves the bottleneck from the compressor to disk i&#x2F;o for my spinning
rust usb disks.&lt;&#x2F;p&gt;
&lt;p&gt;The default output of this is basically silence for two hours while it runs
which isn&#x27;t great. Enter &lt;code&gt;pv&lt;&#x2F;code&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;428654&#x2F;how-to-monitor-the-progress-of-linux-commands-with-pv-and-progress&#x2F;&quot;&gt;pipe
viewer&lt;&#x2F;a&gt;)
which can show you progress based on byte count.&lt;&#x2F;p&gt;
&lt;p&gt;Install lz4 and pv with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo apt install liblz4-tool pv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then pipe the output of tar through pv and into lz4&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a quick script for backing up my home folder to an external drive;
customize to suit your needs:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);font-style: italic;&quot;&gt; https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;68d112d66623d9a4a3643c86a93debee#file-backup-sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Opening&#x2F;creating backup folder...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;mountpoint&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;k&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;u&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;mountpoint&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; fox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; fox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;base&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;h&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;src&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Getting source folder size...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;size_bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;du&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;sb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;base&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;src&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; awk&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;{print $1}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;size_bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; bytes to backup.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Backing up...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;tar&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;cpC&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;base&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;src&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;P&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; pv&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;size_bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; lz4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;date&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CB4B16, #CB4B16);&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;today&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;%Y%m%d-%H%M&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;-home.tar.lz4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;Done.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;This script is also available here:
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;68d112d66623d9a4a3643c86a93debee#file-backup-sh&quot;&gt;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;68d112d66623d9a4a3643c86a93debee#file-backup-sh&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;things-to-watch-out-for&quot;&gt;Things to watch out for&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Progress is inaccurate and variable because it&#x27;s based on input bytes
processed vs total, but the speed is limited by output bytes to the spinning
rust backup disk, and the ratio varies with the compressability of the input
data.&lt;&#x2F;li&gt;
&lt;li&gt;Finding a file will require reading or decompressing the entire archive
because of the way tar works.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;keeping-it-simple&quot;&gt;Keeping it simple&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s lots of great backup tools for backing up home but most of them create
obscure custom formatted backups, often with incremental backups and chunked up
files for efficient use of space. While that&#x27;s great I know from experience
that you don&#x27;t always have all the right tools available to unpack such things
when you really need them, and there&#x27;s always the chance that you are missing
an important incremental. In short complexity is worrying when it comes to
backup (and especially restore).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References:&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;24063846&#x2F;how-to-use-tar-with-lz4#24086155&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;24063846&#x2F;how-to-use-tar-with-lz4#24086155&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;168749&#x2F;is-there-a-way-to-see-any-tar-progress-per-file&#x2F;665181#665181&quot;&gt;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;168749&#x2F;is-there-a-way-to-see-any-tar-progress-per-file&#x2F;665181#665181&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;8228047&#x2F;adding-timestamp-to-a-filename-with-mv-in-bash&#x2F;8229220#8229220&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;8228047&#x2F;adding-timestamp-to-a-filename-with-mv-in-bash&#x2F;8229220#8229220&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Question: where are we at with dynamic static sites?</title>
        <published>2020-04-14T00:00:00+00:00</published>
        <updated>2020-04-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/04/14/question-where-are-we-at-with-dynamic-static-sites/"/>
        <id>https://0x5.uk/2020/04/14/question-where-are-we-at-with-dynamic-static-sites/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/04/14/question-where-are-we-at-with-dynamic-static-sites/">&lt;p&gt;So tell me about dynamic static sites...&lt;&#x2F;p&gt;
&lt;h1 id=&quot;history-lesson&quot;&gt;History lesson&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;ve been a software engineer primarily creating dynamic websites for a loooong
time. First there was a server with html files and caching proxies. Then there
were scripting extensions (cgi, php, asp-classic etc) to spice up your html,
then there were full mature web frameworks for all the things (asp.net mvc,
ruby on rails etc).&lt;&#x2F;p&gt;
&lt;p&gt;But then we got traffic and libraries and platforms and sdks and databases in
the cloud and everything became slow. 😞&lt;&#x2F;p&gt;
&lt;p&gt;So we added CDNs to make it all fast, and cache invalidation to make the
engineers cry.&lt;&#x2F;p&gt;
&lt;p&gt;Now what&#x27;s old is new again, but with a twist, static sites pre-generated by
dynamic code (such as my blog created with jekyll). We get the benefits of old&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CDNs love static sites; caching and proxying work again; and cache
invalidation still makes us cry.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The new saviour is serverless (functions as a service) so that we can still add
dynamic stuff to these static sites.&lt;&#x2F;p&gt;
&lt;p&gt;Yes I can go read endless articles about how to &lt;em&gt;do&lt;&#x2F;em&gt; all this stuff, and turn
my CV and skills on their head so I can sell the hot new thing. But what I
actually want to know now is....&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-are-you-doing-with-dynamic-static-sites&quot;&gt;What are &lt;em&gt;you&lt;&#x2F;em&gt; doing with dynamic static sites?&lt;&#x2F;h1&gt;
&lt;p&gt;Have you tried it? As a pet project? As a commercial project?&lt;&#x2F;p&gt;
&lt;p&gt;Did it go well? Is it the new future or is it just for niche needs?&lt;&#x2F;p&gt;
&lt;p&gt;I feel like because this is all &lt;em&gt;sooo&lt;&#x2F;em&gt; new, that it&#x27;s not clear yet how well
adopted this stuff is or will be, and how much of the old is being thrown out
and rewritten.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h1 id=&quot;my-opinion&quot;&gt;My opinion...&lt;&#x2F;h1&gt;
&lt;p&gt;...based on good knowledge of tech but not based on any actual experience is that
it depends entirely on the type of thing you are building:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Low volume intranet&#x2F;extranet style sites - don&#x27;t bother, asp.net &#x2F; rails is
fast enough, and it will cost you more to develop a blended static&#x2F;dynamic
thing.&lt;&#x2F;li&gt;
&lt;li&gt;E-commerce: totally worth it because you can handle any spike in traffic to
your front page, and serverless lets you seamlessly scale the dynamic parts.
Caveat &lt;strong&gt;it will be more expensive to build&lt;&#x2F;strong&gt; but that&#x27;s okay because money in
is proportional to how many customers you can serve well.&lt;&#x2F;li&gt;
&lt;li&gt;Government or other highly accessible services - don&#x27;t do it. You can&#x27;t meet
the accessibility needs if half your site&#x27;s critical behaviour is done in
client-side javascript with calls off to serverless functions in the cloud. I
might be wrong about this, I hope I am. Maybe it&#x27;s possible but just hard.&lt;&#x2F;li&gt;
&lt;li&gt;Your blog and other traditionally CMS driven sites: just &lt;a href=&quot;&#x2F;2019&#x2F;06&#x2F;24&#x2F;setting-up-a-jekyll-blog&#x2F;&quot;&gt;use jekyll for your
own blog&lt;&#x2F;a&gt; and put it on github pages.
For more complicated commercial sites static site generation is a big win in
terms of technical complexity reduction, reliability improvements and speed
improvements for users. Which static site generator you use will depend on your
organisation&#x27;s internal needs. (Can everyone use git? Or do you need a UI for
people to type in? How much money to you have?)&lt;&#x2F;li&gt;
&lt;li&gt;Etc. (there are sooo many reasons for tech, I&#x27;ve just picked a few)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h1 id=&quot;speak-out-now&quot;&gt;Speak out now&lt;&#x2F;h1&gt;
&lt;p&gt;Before you go, comment below.&lt;&#x2F;p&gt;
&lt;p&gt;What have your experiences been with the shift to dynamic-static sites? Have
you done any of it? Do you think I&#x27;m right&#x2F;wrong about any of this?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What you should do between contracts</title>
        <published>2020-04-09T00:00:00+00:00</published>
        <updated>2020-04-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2020/04/09/what-should-you-do-between-contracts/"/>
        <id>https://0x5.uk/2020/04/09/what-should-you-do-between-contracts/</id>
        
        <content type="html" xml:base="https://0x5.uk/2020/04/09/what-should-you-do-between-contracts/">&lt;h1 id=&quot;strange-times-with-covid-19&quot;&gt;Strange times with Covid-19&lt;&#x2F;h1&gt;
&lt;p&gt;I can&#x27;t post this without mentioning the context I&#x27;m writing in of the
coronavirus pandemic lock-down.&lt;&#x2F;p&gt;
&lt;p&gt;I consider myself extremely lucky to be in the line of work I am that allows me
the flexibility to continue working remotely whilst still protecting myself and
those around me by avoiding contact.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-i-normally-do&quot;&gt;What I normally do&lt;&#x2F;h2&gt;
&lt;p&gt;In calmer times I&#x27;d have taken the opportunity to spend at least a couple of
weeks with family (have small people and time with them is preciously
fleeting). Then get my life in order, then go hell for leather getting into the
next thing I can help build.&lt;&#x2F;p&gt;
&lt;p&gt;Some of my fellow contractors like to make sure they have the next contract
lined up ready for the finish date of their current contract. While this is
optimal for revenue I don&#x27;t do this because:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I find it is a full time job generating, tracking and dealing with
contracting leads&lt;&#x2F;li&gt;
&lt;li&gt;I wouldn&#x27;t want to be distracted from the current client&#x27;s work to the next
thing&lt;&#x2F;li&gt;
&lt;li&gt;I wouldn&#x27;t want to half-arse the contract hunt and not get the optimal
contract for myself and the next client.&lt;&#x2F;li&gt;
&lt;li&gt;There is a tendency for last-minute contract extensions to appear which would
mean letting down one or other client.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So after a contract is completely finished, and some time with family, only
then do I take the contract hunt seriously.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-i-m-doing-this-time&quot;&gt;What I&#x27;m doing this time&lt;&#x2F;h2&gt;
&lt;p&gt;Given the uncertainty caused by COVID-19 + IR35 (by the way COVID is short for
Corona Virus Disease) and the fact I just moved house (i.e. less cash reserves
than usual) I can&#x27;t take it too easy this time. Even though the IR35 changes
have been delayed a year a lot of the damage has been done so the contractor
market is challenging at the moment.&lt;&#x2F;p&gt;
&lt;p&gt;I finished my contract with DfE on a Tuesday, allowed myself till the following
Monday for uninterrupted family time. (Okay almost uninterrupted, I can&#x27;t
really put technology down for that long and I also have my charitable work for
&lt;a href=&quot;https:&#x2F;&#x2F;0x5.uk&#x2F;2020&#x2F;04&#x2F;09&#x2F;what-should-you-do-between-contracts&#x2F;doglost.co.uk&quot;&gt;DogLost&lt;&#x2F;a&gt; that takes up some time.)&lt;&#x2F;p&gt;
&lt;p&gt;Now that is over, I&#x27;m doing roughly 9am-1pm on the business related tasks
suggested below.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-should-you-do-to-make-the-most-of-finishing-a-contract&quot;&gt;What should you do to make the most of finishing a contract?&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;step-1-take-a-break&quot;&gt;Step 1. Take a break&lt;&#x2F;h2&gt;
&lt;p&gt;Contracting is in my experience much more intense than permanent employment.
This is in fact how I like it. But in order to be able to give your all to the
next contract I think it is important to give yourself the space to recharge.&lt;&#x2F;p&gt;
&lt;p&gt;When in a contract it&#x27;s easy to end up with tunnel vision, especially for one
as long as my last one (2 years!), where all you can think about is how it was
done there and how you reacted to the influences around you during that time.
One of the strengths you can bring to a contract as a contractor is the broader
perspective from seeing many organisations, approaches, technologies and
people. It requires a bit of down-time for your latest experience to sink in
once you are out of the hustle and bustle of delivery, and for it to be merged
into your bank of knowledge.&lt;&#x2F;p&gt;
&lt;p&gt;What better way to end a contract than with good chunk of time with family and
friends while your subconsious churns through and processes everything that&#x27;s
happened over the last contract.&lt;&#x2F;p&gt;
&lt;p&gt;I believe if you dive headlong into the next thing with nothing more than a
normal weekend off then your brain will not have the opportunity to properly
process what you&#x27;ve learnt before being overwhelmed with an influx of new
information from a new client.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-2-update-your-online-presence-and-cv&quot;&gt;Step 2. Update your online presence and CV&lt;&#x2F;h2&gt;
&lt;p&gt;You&#x27;ve probably learned a lot and changed a bit since you started the last
contract.&lt;&#x2F;p&gt;
&lt;p&gt;Review and update all your profiles:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;LinkedIn&lt;&#x2F;li&gt;
&lt;li&gt;Twitter (make a new pinned tweet!)&lt;&#x2F;li&gt;
&lt;li&gt;GitHub&lt;&#x2F;li&gt;
&lt;li&gt;StackOverflow&lt;&#x2F;li&gt;
&lt;li&gt;etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Think about what your next client will be interested in and what they want help
with and make sure your profiles provide evidence that you have done similar
things before and can get results.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-3-do-some-writing&quot;&gt;Step 3. Do some writing&lt;&#x2F;h2&gt;
&lt;p&gt;The best way to shape your thoughts on the whole thing is to put them into
writing. So spend some time blogging like I&#x27;m doing now, and make sure to
cross-post your articles to the places where your customers will see them. You
should own your own content, keep it on your own domain on your own blog where
no platform can take away your audience, then cross-post to places like
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dev.to&quot;&gt;dev.to&lt;&#x2F;a&gt;, LinkedIn and Medium (if that&#x27;s your thing) with links
back to your own domain. Better still on your posts ask people to sign up to
your mailing list and email them when you post new articles etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-4-catch-up-with-old-acquaintances&quot;&gt;Step 4. Catch up with old acquaintances&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s hard when you&#x27;re flat out with life and contracts to keep in touch with
everyone. Reach out to old business and personal friends. You never know it
might kick off your next opportunity, or help you learn something about
yourself that&#x27;s useful.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-5-go-all-guns-blazing-on-getting-the-next-piece-of-work&quot;&gt;Step 5. Go all guns blazing on getting the next piece of work&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;You will get all you want in life if you help enough other people get what they want,&quot;
~ Zig Ziglar&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Figure out who&#x27;d value your skills most even in these difficult times and have
at it.&lt;&#x2F;p&gt;
&lt;p&gt;You might find my previous article &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;timwise.co.uk&#x2F;2019&#x2F;06&#x2F;26&#x2F;how-to-find-contract-dev-jobs&#x2F;&quot;&gt;&quot;How to find contract developer
jobs&quot;&lt;&#x2F;a&gt; useful
at this point.&lt;&#x2F;p&gt;
&lt;p&gt;Personally I&#x27;m looking to also increase the value I provide beyond
implementation work. This might take the form of team lead roles, or some
digital transformation consultancy.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;end&quot;&gt;~ End ~&lt;&#x2F;h1&gt;
&lt;p&gt;What do you do between contracts or how do you avoid having gaps? Are you
between contracts now thanks to IR35?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Time to &quot;Shape Up&quot; your SCRUM processes? The new thing from Basecamp</title>
        <published>2019-11-26T00:00:00+00:00</published>
        <updated>2019-11-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/11/26/time-to-shape-up-your-scrum-process-the-new-thing-from-basecamp/"/>
        <id>https://0x5.uk/2019/11/26/time-to-shape-up-your-scrum-process-the-new-thing-from-basecamp/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/11/26/time-to-shape-up-your-scrum-process-the-new-thing-from-basecamp/">&lt;p&gt;Basecamp, who are famous for carving out their own path in the software world
have documented and shared their own way of defining and building their
software-as-a-serice (SaaS) product, also known as &quot;basecamp&quot;. You can read the
whole thing here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;basecamp.com&#x2F;shapeup&quot;&gt;https:&#x2F;&#x2F;basecamp.com&#x2F;shapeup&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If like me you&#x27;ve mostly worked with SCRUM&#x2F;Agile&#x2F;Kanban style teams you should
pay attention to the ideas they share. Unlike many people who teach and follow
the wikipedia truth of SCRUM as &lt;em&gt;the&lt;&#x2F;em&gt; way of building software, basecamp have
not satisfied themselves with cargo-culting &quot;industry best practice&quot; and have
instead carefully honed their own particular way of getting the best out of
their resources.&lt;&#x2F;p&gt;
&lt;p&gt;Although the &quot;ShapeUp&quot; process is finely tuned to suit basecamp, there are many
things in there that the average SCRUM team could take inspiration and
improvement from without throwing out everything in place at the moment. An
example I particularly like is the way everyone can bring a pitch to the
betting table, from their own personal backlog of priorities, contrasted with
the usual approach of throwing yet another another card&#x2F;story onto the
team-shared dumpster-fire of a backlog &#x2F; todo-list and hoping it somehow
magically gets to the top of the list just before all your chickens come home
to roost.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h1 id=&quot;key-features-of-shaping-up&quot;&gt;Key features of shaping up&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;shaping&quot;&gt;Shaping&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;An iterative process of taking concepts from initial idea to something that
could be built with bounded risk and expectations.&lt;&#x2F;li&gt;
&lt;li&gt;A largely solo or pair exercise, but done in consultation with experts on the
wider team.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;pitch&quot;&gt;Pitch&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;The output of shaping.&lt;&#x2F;li&gt;
&lt;li&gt;A detailed but high-level document outlining what should and shouldn&#x27;t be
built, with room for discretion and design work by the designers and
programmers.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;bets&quot;&gt;Bets&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;There is a meeting where pitches are discussed, prioritised and scheduled for
the next cycle of work, they &quot;take a bet&quot; on a pitch.&lt;&#x2F;li&gt;
&lt;li&gt;If a pitch blows its timebox, then the default is always to stop and it
doesn&#x27;t get any special priority in the next cycle. This limits the risk of
runaway unstoppable projects.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;6-week-cycle-with-gaps&quot;&gt;6-week cycle with gaps&lt;&#x2F;h2&gt;
&lt;p&gt;Basecamp operate a 6-week period of building what was decided in shaping and
betting. This can either be one 6 week bet or set of 2 week bets.&lt;&#x2F;p&gt;
&lt;p&gt;Once this is done there is a 2-week gap where people can do maintenance, tech
debt paydown, plan new things etc.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;If you&#x27;d like to hear a bit more about ShapeUp, have a listen to
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pod.timwise.co.uk&#x2F;5&quot;&gt;https:&#x2F;&#x2F;pod.timwise.co.uk&#x2F;5&lt;&#x2F;a&gt; where I go over their process in a bit more
detail with regular co-host David.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve also written up a nice approach to avoiding a &quot;backlog of doom&quot; in my
&lt;a href=&quot;&#x2F;2020&#x2F;06&#x2F;30&#x2F;personal-backlogs&#x2F;&quot;&gt;personal backlogs post&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Should you rebase or merge to update feature branches in git?</title>
        <published>2019-10-14T00:00:00+00:00</published>
        <updated>2019-10-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/10/14/merge-vs-rebase/"/>
        <id>https://0x5.uk/2019/10/14/merge-vs-rebase/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/10/14/merge-vs-rebase/">&lt;p&gt;You have a &quot;feature branch&quot; in git that you&#x27;ve been working on for a while but
now &lt;code&gt;main&lt;&#x2F;code&gt; or &lt;code&gt;master&lt;&#x2F;code&gt; has moved on.  You know of &lt;code&gt;merge&lt;&#x2F;code&gt; and &lt;code&gt;rebase&lt;&#x2F;code&gt;, but
which one should you use? And what can you do to avoid being in this position
in the first-place?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tldr&quot;&gt;TLDR&lt;&#x2F;h2&gt;
&lt;p&gt;Try rebase. If that dissolves into conflict-resolution-hell then give up, merge
master into your branch and move on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-options&quot;&gt;The Options&lt;&#x2F;h2&gt;
&lt;p&gt;You need to bring your feature branch up to date with with master to flush
out any incompatibilities and deal with any merge conflicts.&lt;&#x2F;p&gt;
&lt;p&gt;You have two common choices:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Merge&lt;&#x2F;strong&gt; &lt;code&gt;origin&#x2F;master&lt;&#x2F;code&gt; into your branch.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Rebase&lt;&#x2F;strong&gt; your branch onto &lt;code&gt;origin&#x2F;master&lt;&#x2F;code&gt; and force-push.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-trade-offs&quot;&gt;The Trade-offs&lt;&#x2F;h2&gt;
&lt;p&gt;A blanket rule here either for merge or rebase is unhelpful because there are
&lt;strong&gt;trade-offs&lt;&#x2F;strong&gt; to be made that vary depending on the specific circumstances. (Isn&#x27;t
that always the answer with git?! &quot;It depends!&quot;)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;should-you-merge&quot;&gt;Should You Merge?&lt;&#x2F;h3&gt;
&lt;p&gt;A merge from &lt;code&gt;master&lt;&#x2F;code&gt; is done like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git fetch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git merge origin&#x2F;master&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git push&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;merge-the-good&quot;&gt;Merge - The Good&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;👍 Reliable no-brainer that anyone can follow by rote.&lt;&#x2F;li&gt;
&lt;li&gt;👍 Resolve conflicts only once.&lt;&#x2F;li&gt;
&lt;li&gt;👍 Accurate representation of what happened over time.&lt;&#x2F;li&gt;
&lt;li&gt;👍 Avoids retrospectively &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@fredrikmorken&#x2F;why-you-should-stop-using-git-rebase-5552bee4fed1&quot;&gt;introducing bugs and test failures into commits that
used to be
valid&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;👍 Avoids re-writing previously shared branch, which can confuse less
experienced git users if they are working with you on the branch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;merge-the-bad&quot;&gt;Merge - The Bad&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;👎 Doing this repeatedly makes for a messy history for little or no benefit.&lt;&#x2F;li&gt;
&lt;li&gt;👎 Significant merges from master makes it harder&#x2F;impossible to then go back and
clean your branch&#x27;s commits with a &lt;code&gt;git rebase --interactive&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;👎 Tends to generate &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackernoon.com&#x2F;git-merge-vs-rebase-whats-the-diff-76413c117333&quot;&gt;wide tramlines in the commit
history&lt;&#x2F;a&gt;
that can be very hard to follow  when looking back to find out when&#x2F;why
something was done. (mitigated by &lt;code&gt;git log --first-parent&lt;&#x2F;code&gt;, until
you need to dig into a branch).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;should-you-rebase&quot;&gt;Should You Rebase?&lt;&#x2F;h3&gt;
&lt;p&gt;A rebase onto master is done like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git fetch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git rebase origin&#x2F;master&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git push --force-with-lease&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;rebase-the-good&quot;&gt;Rebase - The Good&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;👍 Avoids tramlines generated by long-lived feature branches
branch&lt;&#x2F;li&gt;
&lt;li&gt;👍 Makes resultant history in &lt;code&gt;master&lt;&#x2F;code&gt; much easier to follow&lt;&#x2F;li&gt;
&lt;li&gt;👍 Reflects the intention more clearly of &quot;merge these commits into master&quot; as
opposed to &quot;here&#x27;s how I flailed my way to a working thing&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;rebase-the-bad&quot;&gt;Rebase - The Bad&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;👎 Can confuse less experienced git users if they are working with you on the
branch (the answer is usually for them to run &lt;code&gt;git pull --rebase&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;👎 Results in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;5b-vNpSw6R8&quot;&gt;resolving conflicts multiple times (screencast)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;👎 Loses chronological order of creation of code (personally I think this is
less important than a series of clean intentional patches to be applied to
the codebase when merged to &lt;code&gt;master&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;👎 Could in somewhat rare circumstances retrospectively &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@fredrikmorken&#x2F;why-you-should-stop-using-git-rebase-5552bee4fed1&quot;&gt;introduce bugs and test
failures into commits that used to be
valid&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;heuristics-to-use&quot;&gt;Heuristics To Use&lt;&#x2F;h2&gt;
&lt;p&gt;Try rebase. If that dissolves into conflict-resolution-hell then give up, merge
master into your branch and move on.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Try rebase. If that dissolves into conflict-resolution-hell then give up,
merge master into your branch and move on.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ Tim Abell&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;intent&#x2F;tweet?text=%E2%80%9CTry%20rebase.%20If%20that%20dissolves%20into%20conflict-resolution-hell%20then%20give%20up%2C%20merge%20master%20into%20your%20branch%20and%20move%20on.%E2%80%9D%20~%20%40timabell%20%F0%9F%91%89%20https%3A%2F%2Ftimwise.co.uk%2F2019%2F10%2F14%2Fmerge-vs-rebase&quot;&gt;Tweet this&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Rebase is my preferred approach until:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Rebase becomes too costly to fix up due to conflicts with &lt;code&gt;master&lt;&#x2F;code&gt;, or&lt;&#x2F;li&gt;
&lt;li&gt;I become aware of an incompatibility with &lt;code&gt;master&lt;&#x2F;code&gt; that changes the meaning
of the previous commits and needs serious work to resolve.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You &lt;em&gt;can&lt;&#x2F;em&gt; usually make a difficult rebase work, and I&#x27;ve hunkered down and
tackled probably more than I should have in the name of perfect history graphs.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with a tricky rebase is that if you are doing this for business and
not just for fun then there is a major time cost for only a marginal benefit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-make-it-through-rebase-conflicts-unscathed&quot;&gt;How to make it through rebase conflicts unscathed&lt;&#x2F;h2&gt;
&lt;p&gt;If you decide to battle on with rebase in-spite of conflicts then my tip for
you is:&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t jump straight to the &quot;correct&quot; code when fixing each commit&#x27;s conflict,
as that guarantees the next commit won&#x27;t apply.&lt;&#x2F;p&gt;
&lt;p&gt;Instead as you work through the rebase make each commit apply with its original
meaning and nothing more.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s worth remembering that each commit on your branch describes how to change
the source code from a before-state to an after-state; so if you change the
after-state of one patch, then the next patch will no longer apply.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-avoid-the-pain-of-rebases-and-merges-entirely&quot;&gt;How to avoid the pain of rebases and merges entirely&lt;&#x2F;h2&gt;
&lt;p&gt;Pain around this topic is likely a symptom of not breaking down your stories &#x2F;
pull requests &#x2F; features into small enough chunks. On a fast moving team
&lt;code&gt;master&lt;&#x2F;code&gt; is very fluid and any large &amp;amp; long-running branches will be hard to
review and merge. Try to chip off smaller increments and ship those, maybe
using feature flags or hidden features (those with no visible way of getting to
them).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-resources&quot;&gt;More Resources&lt;&#x2F;h2&gt;
&lt;p&gt;In general merge vs rebase generates much debate, such as that found on
stackoverflow:
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;804115&#x2F;when-do-you-use-git-rebase-instead-of-git-merge&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;804115&#x2F;when-do-you-use-git-rebase-instead-of-git-merge&lt;&#x2F;a&gt;
but it is often lacking context.&lt;&#x2F;p&gt;
&lt;p&gt;There are many other articles on the merge&#x2F;rebase topic such as
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;derekgourlay.com&#x2F;blog&#x2F;git-when-to-merge-vs-when-to-rebase&#x2F;&quot;&gt;https:&#x2F;&#x2F;derekgourlay.com&#x2F;blog&#x2F;git-when-to-merge-vs-when-to-rebase&#x2F;&lt;&#x2F;a&gt; but I
couldn&#x27;t see anything that matched my heuristic for tackling feature branch
updates so I wrote this one.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bors.tech&#x2F;essay&#x2F;2017&#x2F;02&#x2F;02&#x2F;pitch&#x2F;&quot;&gt;Semantic merge conflicts&lt;&#x2F;a&gt;&quot; are where git reports no conflict but nonetheless the code is broken.&lt;&#x2F;p&gt;
&lt;p&gt;I also wrote &quot;&lt;a href=&quot;&#x2F;2021&#x2F;03&#x2F;15&#x2F;github-rebase-and-squash-considered-harmful&#x2F;&quot;&gt;GitHub rebase and squash considered harmful&lt;&#x2F;a&gt;&quot; which address a github specific horror.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;get-in-touch&quot;&gt;Get in touch&lt;&#x2F;h2&gt;
&lt;p&gt;Hey there! Thanks for reading!&lt;&#x2F;p&gt;
&lt;p&gt;This post gets far more traffic than anything else on my blog. I&#x27;d love to know what brought you here and if the above was helpful.&lt;&#x2F;p&gt;
&lt;p&gt;Please take a moment to fire an email to me at &lt;a href=&quot;mailto:tim@timwise.co.uk?subject=merge-rebase-article&quot;&gt;tim@timwise.co.uk&lt;&#x2F;a&gt; and tell me a bit about yourself.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why I made SQL Schema Explorer open source</title>
        <published>2019-10-08T00:00:00+00:00</published>
        <updated>2019-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/10/08/why-i-made-schemaexplorer-open-source/"/>
        <id>https://0x5.uk/2019/10/08/why-i-made-schemaexplorer-open-source/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/10/08/why-i-made-schemaexplorer-open-source/">&lt;h1 id=&quot;what-is-sql-schema-explorer&quot;&gt;What is SQL Schema Explorer?&lt;&#x2F;h1&gt;
&lt;p&gt;It&#x27;s a database schema &amp;amp; data browser that can follow foreign keys and draw
diagrams that I spent years building because I wanted it to exist and I thought
it might make a good first product.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;why-charge&quot;&gt;Why charge?&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;m pretty busy these days but I like working on software and building things
like this, to justify the amount of time that goes in I can no longer just have
it as a time-consuming hobby. I&#x27;ve also been learning about entrepreneurship as
a possible extension or next step from time-for-money contract-programming
services.&lt;&#x2F;p&gt;
&lt;p&gt;The idea was that if I could get enough yearly subscribers to the software then
I could get balsamiq-like success and focus on making it better and better for
the people using it.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;why-open-source-now&quot;&gt;Why open source now?&lt;&#x2F;h1&gt;
&lt;p&gt;I got plenty of interest and interactions by my standards, more than I&#x27;ve ever
had for something I&#x27;ve published; but I never got more than one good friend paid
up beyond a generous trial. The conversations I had with people were full of
enthusiasm for the idea but not for parting with money to buy it. One
particular conversation was very positive until the idea of putting the
theoretical purchase in front of the manager was raised and then suddenly it
didn&#x27;t seem viable at all; which I think speaks volumes. Useful, but not useful
enough to risk any political capital to get it, even for a pretty insignificant
amount of money.  I then had a coaching call with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;justinjackson.ca&#x2F;&quot;&gt;Justin
Jackson&lt;&#x2F;a&gt; and as part of that he suggested putting it
to one side. Up to this point I&#x27;d been unable to leave the idea alone; it had
been something I really wanted to exist. I&#x27;ve always worked with relational
databases, and this seemed like a painful gap. At this point I had finally
added every feature that I&#x27;d ever dreamed it should have, and the intrinsic
motivation to just build for the sake of building was waning, and without the
demands from paying users for more features it&#x27;s hard to justify continuing to
pour hours in even if it is on the train.&lt;&#x2F;p&gt;
&lt;p&gt;At this point there were 100 people on the mailing list (drip sent my first
bill!), one paying user&#x2F;fan (Hello David! Many thanks!), and zero MRR (monthly
recurring revenue). I&#x27;d spent a bit of money on hosting (I&#x27;m still paying
digital ocean to keep the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;demo.schemaexplorer.io&#x2F;&quot;&gt;demo site&lt;&#x2F;a&gt; up).&lt;&#x2F;p&gt;
&lt;p&gt;I didn&#x27;t want to let down the few people who had really liked it by having it
just vanish into the ether like so many failed startups. Fortunately this is
downloadable and installable software, not a SaaS that would have to be shut
down. I&#x27;ve always liked the open-source ethos, and given this was no longer a
direct financial opportunity it made sense to me to give it away freely under a
copyleft license.&lt;&#x2F;p&gt;
&lt;p&gt;It feels like having this as a portfolio piece given I sell coding for a living
won&#x27;t do me any harm, and it makes it easier to take with me to client
projects, where I can use it to help them improve their database.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;schema-explorer-for-client-work&quot;&gt;Schema Explorer for client work&lt;&#x2F;h1&gt;
&lt;p&gt;Here&#x27;s some things I&#x27;ve been using schema explorer for to help my contracting clients&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Finding missing foreign keys without looking up complex &lt;code&gt;pg_schema&lt;&#x2F;code&gt; queries&lt;&#x2F;li&gt;
&lt;li&gt;Analysing data in tables and sharing screenshots with the teams&lt;&#x2F;li&gt;
&lt;li&gt;Sharing screenshots of the generated diagrams to improve team understanding&lt;&#x2F;li&gt;
&lt;li&gt;Using it as a tool for discussing database design&lt;&#x2F;li&gt;
&lt;li&gt;Finding records needed for troubleshooting and debugging&lt;&#x2F;li&gt;
&lt;li&gt;Improving my mental model of the database structure&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;tell-me-more&quot;&gt;Tell me more&lt;&#x2F;h1&gt;
&lt;p&gt;It&#x27;s now &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Affero_General_Public_License&quot;&gt;A-GPL&lt;&#x2F;a&gt;
which requires sharing any modified source code even if you are just letting
users access the generated site. If I&#x27;m giving my years of hard work for free,
I think it&#x27;s only fair to require people to contribute their improvements back
to the community.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the source code at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;schema-explorer&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;schema-explorer&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;feedback&quot;&gt;Feedback&lt;&#x2F;h1&gt;
&lt;p&gt;Please do get in touch if this sparked a thought or interest. Just a simple
email will do &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;tim@timwise.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for listening.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Laptop setup notes</title>
        <published>2019-08-20T00:00:00+00:00</published>
        <updated>2019-08-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/08/20/laptop-setup/"/>
        <id>https://0x5.uk/2019/08/20/laptop-setup/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/08/20/laptop-setup/">&lt;p&gt;This is mostly for my benefit YMMV. Used for XPS13 and XPS15. Last run with Linux Mint Cinnamon 22&lt;&#x2F;p&gt;
&lt;p&gt;Things to go from blank machine to fully functioning work laptop.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-not-use-machine-images&quot;&gt;Why not use machine images?&lt;&#x2F;h2&gt;
&lt;p&gt;Because when you want to upgrade your OS image you have to do this anyway.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-this-will-break&quot;&gt;But this will break!&lt;&#x2F;h2&gt;
&lt;p&gt;Indeed, and it does, a continuous labour of love. Ideas welcome!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;os-install&quot;&gt;OS install&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linuxmint.com&#x2F;download.php&quot;&gt;Download mint cinnamon x64 torrent&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Burn to USB stick&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;696413&#x2F;ubuntu-installer-cant-find-any-disk-on-dell-xps-13-9350&#x2F;696414#696414&quot;&gt;Configure Dell XPS 13 to use AHCI mode&lt;&#x2F;a&gt; (one time fix)&lt;&#x2F;li&gt;
&lt;li&gt;Boot to stick with &lt;code&gt;F12&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Install mint
&lt;ul&gt;
&lt;li&gt;Full disk encryption (LUKS), default whole disk partitioning&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Run updates and reboot &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;hibernate-hybrid-sleep-unfinished&quot;&gt;Hibernate &#x2F; hybrid sleep (unfinished)&lt;&#x2F;h2&gt;
&lt;p&gt;Not working at moment, needs more research.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Enable hibernate?
&lt;ul&gt;
&lt;li&gt;Bigger swap?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;unfinished-research-into-missing-hibernation&quot;&gt;Unfinished research into missing hibernation&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;1539378&#x2F;what-size-swap-partition-will-allow-a-mint-19-3-installation-with-64g-ram-to-hib?noredirect=1&amp;amp;lq=1&quot;&gt;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;1539378&#x2F;what-size-swap-partition-will-allow-a-mint-19-3-installation-with-64g-ram-to-hib?noredirect=1&amp;amp;lq=1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;1434301&#x2F;enabling-hibernate-on-linux-mint-19-1?noredirect=1&amp;amp;lq=1&quot;&gt;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;1434301&#x2F;enabling-hibernate-on-linux-mint-19-1?noredirect=1&amp;amp;lq=1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.ubuntu.com&#x2F;community&#x2F;SwapFaq&quot;&gt;https:&#x2F;&#x2F;help.ubuntu.com&#x2F;community&#x2F;SwapFaq&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;568093&#x2F;enable-hibernation-in-power-management&quot;&gt;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;568093&#x2F;enable-hibernation-in-power-management&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dewaka.com&#x2F;blog&#x2F;2021&#x2F;04&#x2F;08&#x2F;linux-mint-hibernate&#x2F;&quot;&gt;https:&#x2F;&#x2F;dewaka.com&#x2F;blog&#x2F;2021&#x2F;04&#x2F;08&#x2F;linux-mint-hibernate&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.fosslinux.com&#x2F;45454&#x2F;enable-hibernate-mode-linux-mint.htm&quot;&gt;https:&#x2F;&#x2F;www.fosslinux.com&#x2F;45454&#x2F;enable-hibernate-mode-linux-mint.htm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;12383&#x2F;how-to-go-automatically-from-suspend-into-hibernate&quot;&gt;https:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;12383&#x2F;how-to-go-automatically-from-suspend-into-hibernate&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;linuxmint&#x2F;comments&#x2F;93ta9u&#x2F;enable_hibernation_in_linux_mint_19_tara&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;linuxmint&#x2F;comments&#x2F;93ta9u&#x2F;enable_hibernation_in_linux_mint_19_tara&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;packaged-software-install&quot;&gt;Packaged software install&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Bootstrap my dotmatrix package list &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;blob&#x2F;main&#x2F;software&#x2F;bootstrap.sh&quot;&gt;my bootstrap file&lt;&#x2F;a&gt; like this (don&#x27;t laugh&#x2F;cringe):&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;curl https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;timabell&#x2F;dotmatrix&#x2F;main&#x2F;software&#x2F;bootstrap.sh | sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This installs my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;blob&#x2F;main&#x2F;software&#x2F;packages.txt&quot;&gt;usual package list&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hardware&quot;&gt;Hardware&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;video&quot;&gt;Video&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Disable nvidia GPU in favour of intel card&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo prime-select intel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;bluetooth&quot;&gt;Bluetooth&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;andrebrait&#x2F;961cefe730f4a2c41f57911e6195e444&quot;&gt;Enable fast-connect etc for bluetooth keyboard&#x2F;mouse&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zsh&quot;&gt;zsh&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Switch to z-shell &lt;code&gt;chsh -s &#x2F;usr&#x2F;bin&#x2F;zsh&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ref: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;131823&#x2F;how-to-make-zsh-the-default-shell&#x2F;131838#131838&quot;&gt;https:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;131823&#x2F;how-to-make-zsh-the-default-shell&#x2F;131838#131838&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inotify&quot;&gt;inotify&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;inotify increase for:
&lt;ul&gt;
&lt;li&gt;RubyMine&lt;&#x2F;li&gt;
&lt;li&gt;Guard - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;guard&#x2F;listen&#x2F;wiki&#x2F;Increasing-the-amount-of-inotify-watchers&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;guard&#x2F;listen&#x2F;wiki&#x2F;Increasing-the-amount-of-inotify-watchers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Syncthing - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.syncthing.net&#x2F;users&#x2F;faq.html#inotify-limits&quot;&gt;https:&#x2F;&#x2F;docs.syncthing.net&#x2F;users&#x2F;faq.html#inotify-limits&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo fs.inotify.max_user_watches=524288 | sudo tee -a &#x2F;etc&#x2F;sysctl.conf &amp;amp;&amp;amp; sudo sysctl -p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;file-sync-with-syncthing&quot;&gt;File sync with syncthing&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Run syncthing-gtk from system menu (auto-installs syncthing binary)
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;localhost:8080&#x2F;&quot;&gt;Configure syncthing&lt;&#x2F;a&gt; not to route over internet
(no relay, no public discovery, no NAT traversal)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;firewalld.org&#x2F;documentation&#x2F;utilities&#x2F;firewall-config.html&quot;&gt;Configure firewall-config&lt;&#x2F;a&gt;
to allow syncthing
&lt;ul&gt;
&lt;li&gt;Add manual service syncthing&lt;&#x2F;li&gt;
&lt;li&gt;Allow tcp 22000 and 21027 udp&lt;&#x2F;li&gt;
&lt;li&gt;Make home network use home zone&lt;&#x2F;li&gt;
&lt;li&gt;Add syncthing to home zone&lt;&#x2F;li&gt;
&lt;li&gt;Runtime to permanent&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;firewall-config-syncthing.png&quot; alt=&quot;firewall config screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Remove old install machine name from syncthing network&lt;&#x2F;li&gt;
&lt;li&gt;Tell new and old devices about each other in syncthing&lt;&#x2F;li&gt;
&lt;li&gt;watch &lt;code&gt;~&#x2F;Documents&lt;&#x2F;code&gt; etc. magically sync (amazing)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;all-the-things-from-dotmatrix&quot;&gt;All the things from dotmatrix&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd repo&#x2F;dotmatrix&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bin&#x2F;symlinks.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bin&#x2F;install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;software&#x2F;delta.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;link-local-git-config&quot;&gt;Link local git config&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ln -s ~&#x2F;Documents&#x2F;config&#x2F;.gitconfig.local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;desktop-system-config&quot;&gt;Desktop&#x2F;system config&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Setup touchpad
&lt;ul&gt;
&lt;li&gt;Set mouse and trackpad speed&#x2F;acceleration to max&lt;&#x2F;li&gt;
&lt;li&gt;Enable horizontal touchpad scroll&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;mouse-and-touchpad.png&quot; alt=&quot;Screenshot of mint touchpad settings with customisations&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Setup terminal colours and turn off transparency&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;terminal-colours.png&quot; alt=&quot;Screenshot mint terminal colours set to solarized&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Turn off all the system sounds and turn the volume down to 0%.&lt;&#x2F;li&gt;
&lt;li&gt;Customize time in task bar to &lt;code&gt; 📅 %a %e %b %Y   🕓 %H:%M:%S&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Lock screen with &lt;code&gt;Win+L&lt;&#x2F;code&gt; - start &amp;gt; keyboard &amp;gt; system &amp;gt; lock screen (Windows user habits).&lt;&#x2F;li&gt;
&lt;li&gt;Turn on automatic updates in update manager preferences, and automatic obsolete kernal removal.&lt;&#x2F;li&gt;
&lt;li&gt;Configure nemo file manager to always use list view.&lt;&#x2F;li&gt;
&lt;li&gt;Add workspace switcher applet to taskbar.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;firefox&quot;&gt;Firefox&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Sign-in to sync&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Remove firefox tabs (because I use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;addons.mozilla.org&#x2F;en-US&#x2F;firefox&#x2F;addon&#x2F;tree-style-tab&#x2F;&quot;&gt;Tree Style Tabs&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cd ~&#x2F;.mozilla&#x2F;firefox&#x2F;&amp;lt;profile_id_folder&amp;gt;&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;mkdir chrome&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;echo &#x27;#TabsToolbar { visibility: collapse !important; }&#x27; &amp;gt;&amp;gt; chrome&#x2F;userChrome.css&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;about:config &amp;gt; &lt;code&gt;toolkit.legacyUserProfileCustomizations.stylesheets&lt;&#x2F;code&gt; &amp;gt; &lt;code&gt;true&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;restart firefox&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Reference: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;1268732&#x2F;how-to-hide-tab-bar-tabstrip-in-firefox-57-quantum#1268734&quot;&gt;https:&#x2F;&#x2F;superuser.com&#x2F;questions&#x2F;1268732&#x2F;how-to-hide-tab-bar-tabstrip-in-firefox-57-quantum#1268734&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;startup-list&quot;&gt;Startup list&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Menu &amp;gt; Startup Applications&lt;&#x2F;li&gt;
&lt;li&gt;Adjust to current tastes&lt;&#x2F;li&gt;
&lt;li&gt;Add additional startup apps:
&lt;ul&gt;
&lt;li&gt;Syncthing GTK&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;non-apt-program-installations&quot;&gt;Non-apt program installations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Use Applets config to download and add &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cinnamon-spices.linuxmint.com&#x2F;applets&#x2F;view&#x2F;131&quot;&gt;Pomodoro timer&lt;&#x2F;a&gt; in task bar.&lt;&#x2F;li&gt;
&lt;li&gt;Install &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jetbrains.com&#x2F;toolbox&#x2F;app&#x2F;&quot;&gt;jetbrains toolbox&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;blob&#x2F;main&#x2F;software&#x2F;flatpaks.sh&quot;&gt;Install flatpak apps from dotmatrix&lt;&#x2F;a&gt;, sign in to them all
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;1086529&#x2F;how-to-give-a-flatpak-app-access-to-a-directory&#x2F;1247345#1247345&quot;&gt;Give flatpak access wider home folder access&lt;&#x2F;a&gt; (for sending pics) with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;flathub.org&#x2F;apps&#x2F;details&#x2F;com.github.tchx84.Flatseal&quot;&gt;flatseal&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Install all the other things in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;tree&#x2F;main&#x2F;software&quot;&gt;dotmatrix&#x2F;software&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ssh&quot;&gt;SSH&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Generate ssh key &lt;code&gt;ssh-keygen&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;settings&#x2F;keys&quot;&gt;Add public key to github&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;postgres&quot;&gt;Postgres&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackernoon.com&#x2F;dont-install-postgres-docker-pull-postgres-bee20e200198&quot;&gt;Use a docker image&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xps-firmware-updates&quot;&gt;XPS firmware updates&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fwupdmgr get-devices&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fwupdmgr get-updates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fwupdmgr update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;refs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fwupd.org&#x2F;lvfs&#x2F;docs&#x2F;users&quot;&gt;https:&#x2F;&#x2F;fwupd.org&#x2F;lvfs&#x2F;docs&#x2F;users&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;shutter&quot;&gt;Shutter&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Change default save location to &lt;code&gt;~&#x2F;tmp&#x2F;shutter&lt;&#x2F;code&gt; (new folder)&lt;&#x2F;li&gt;
&lt;li&gt;change filename to &lt;code&gt;shutter_%Y%-m-%d_%NN&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;thunderbird&quot;&gt;Thunderbird&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Restore recent backup (from data sync)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;asdf&quot;&gt;asdf&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;asdf-vm.com&#x2F;#&#x2F;core-manage-asdf-vm?id=install-asdf-vm&quot;&gt;install asdf version manager&lt;&#x2F;a&gt; for all the things (ruby, node, golang etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;nodejs-setup&quot;&gt;NodeJs setup&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;asdf plugin-add nodejs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bash ~&#x2F;.asdf&#x2F;plugins&#x2F;nodejs&#x2F;bin&#x2F;import-release-team-keyring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;asdf install nodejs 8.16.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;node -v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Keyring because nodejs packages are signed and validated
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asdf-vm&#x2F;asdf-nodejs#install&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;asdf-vm&#x2F;asdf-nodejs#install&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ruby&quot;&gt;Ruby&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;asdf plugin add ruby&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd some-project&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;asdf install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gem install bundler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thoughtbot&#x2F;laptop&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;thoughtbot&#x2F;laptop&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why every team needs a Delivery Manager (DM)</title>
        <published>2019-07-08T00:00:00+00:00</published>
        <updated>2019-07-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/07/08/why-every-team-needs-a-delivery-manager/"/>
        <id>https://0x5.uk/2019/07/08/why-every-team-needs-a-delivery-manager/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/07/08/why-every-team-needs-a-delivery-manager/">&lt;p&gt;I was explaining to someone the team structure I&#x27;m working in at the Department
for Education&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dfedigital.blog.gov.uk&#x2F;&quot;&gt;DfE Digital&lt;&#x2F;a&gt; and realised not
everyone has seen this structure at work and the magic it brings.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;team-structures&quot;&gt;Team structures&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;gds-government-team-structure&quot;&gt;GDS (government) team structure&lt;&#x2F;h3&gt;
&lt;p&gt;In short the team looks something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Product Manager&lt;&#x2F;li&gt;
&lt;li&gt;Delivery Manager&lt;&#x2F;li&gt;
&lt;li&gt;Developer(s)&lt;&#x2F;li&gt;
&lt;li&gt;User Researcher(s)&lt;&#x2F;li&gt;
&lt;li&gt;Content Designer(s)&lt;&#x2F;li&gt;
&lt;li&gt;Interaction Designer(s)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;At the top of the whole thing there&#x27;s a &quot;Service Owner&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Involved from the very early stages, but a bit less in the daily grind of building technical solutions, you&#x27;ll find a &quot;Service Designer&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s a very flat structure. It&#x27;s a group of peers who all bring their own
strengths to the team, but with no hard boundaries, we all muck in with
everything now and then. I particularly like helping with user research as it
keeps me connected with the users. I&#x27;m constantly feeling guilty for not
attending enough user research!&lt;&#x2F;p&gt;
&lt;p&gt;This structure is modelled on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gov.uk&#x2F;service-manual&#x2F;the-team&#x2F;what-each-role-does-in-service-team&quot;&gt;the structure of a team at the Government
Digital Service
&lt;&#x2F;a&gt;(GDS)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;aside-product-who&quot;&gt;Aside: Product who?&lt;&#x2F;h4&gt;
&lt;p&gt;You may also not be familiar with Product Manager (I&#x27;ve not seen it as much in
private industry), so as an aside let me explain:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;del&gt;The Product Manager is more widely known in industry as Product Owner&lt;&#x2F;del&gt; (well
that&#x27;s what I thought, actually it turns out &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;melissaperri.com&#x2F;blog&#x2F;2017&#x2F;06&#x2F;29&#x2F;product-manager-vs-product-owner&quot;&gt;product owner and product manager
are not quite the
same&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.romanpichler.com&#x2F;blog&#x2F;product-manager-vs-product-owner&#x2F;&quot;&gt;there is depth to the product manager&#x2F;owner question&lt;&#x2F;a&gt;).
This is someone who figures out the balance of features in a service and the
software that supports it, based on all the various constraints and inputs
(e.g. user need, security, stability, internal need). One output of this role
is prioritization of work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;private-company-team-structure&quot;&gt;Private company team structure&lt;&#x2F;h3&gt;
&lt;p&gt;The kind of structure I&#x27;ve more commonly see in the private sector is something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Project Manager&lt;&#x2F;li&gt;
&lt;li&gt;Business Analyst (BA)&lt;&#x2F;li&gt;
&lt;li&gt;SCRUM Master (in title if not in deed)&lt;&#x2F;li&gt;
&lt;li&gt;Developer(s)&lt;&#x2F;li&gt;
&lt;li&gt;Testers(s) &#x2F; QA (Quality Assurance)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;which-is-better&quot;&gt;Which is better?&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve seen good and not so good people in all of the roles, and number of roles
varies with team size.&lt;&#x2F;p&gt;
&lt;p&gt;I think the GDS-style team structure is superior when it comes to shipping
user-value as a development team.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dm-for-the-win&quot;&gt;DM for the win&lt;&#x2F;h2&gt;
&lt;p&gt;The role I want to focus on here (though they are all awesome) is Delivery
Manager as it&#x27;s the most uncommon in my experience.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve personally never seen delivery management called out as a specific named
role outside of my work for &quot;Digital&quot; teams in UK Government. I hope this role
becomes more common everywhere.&lt;&#x2F;p&gt;
&lt;p&gt;So what does a Delivery Manager actually do?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;greasing-the-enterprise-wheels&quot;&gt;Greasing the enterprise wheels&lt;&#x2F;h3&gt;
&lt;p&gt;In any organisation beyond about 20 people the bureaucracy starts to sneak in,
layers of rules are added as a business tries to avoid repeating previous
mistakes, and as you hit enterprise scale it&#x27;s positively stifling, to the
point that people issues and an inability to even open &lt;em&gt;Microsoft Word (TM) (R)
((c) 1908)&lt;&#x2F;em&gt; on a work computer without signing 3 forms &lt;strong&gt;in blood&lt;&#x2F;strong&gt;, become
nearly impossible. The thing is, a dev team is usually building something that
hasn&#x27;t been built before, maybe as part of a &lt;strong&gt;major change to how the
organisation functions&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Web development is more than just taking your sales
brochures and putting them online, if that was all we wanted I&#x27;d give you a
copy of WordPress and find something else to build.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes you can hide the team away in a
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Skunk_Works&quot;&gt;skunkworks&lt;&#x2F;a&gt; project, but that can&#x27;t
last forever and eventually the old meets the new, and suddenly the whole
project is at risk of being rejected by the legacy organisation.  The
productivity can be sucked out of a development team for good, they can end up
unable to deliver anything.&lt;&#x2F;p&gt;
&lt;p&gt;This is where a &lt;strong&gt;Delivery Manager&lt;&#x2F;strong&gt; role is golden; they deal with making sure
the organisation&#x27;s goals to have this new service &#x2F; system &#x2F; product &#x2F; software
are able to be progressed, conversations &amp;amp; endless meetings had, finance
obtained, hardware procured, forms filled, security audits managed sensibly,
pile-on demands defended … the list is endless. By having this role the team
can focus on building and shipping, comfortable that they won&#x27;t be sidetracked
or blocked.&lt;&#x2F;p&gt;
&lt;p&gt;I still like the way the wonderful Mark &#x27;Stanners&#x27; Stanley put it back in 2012.
I think this cuts to best thing about it:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The delivery manager is there to remove any and all things that are hindering
or ‘blocking’ them, so the team can deliver the product.&lt;&#x2F;p&gt;
&lt;p&gt;~ Mark Stanley -
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gds.blog.gov.uk&#x2F;2012&#x2F;12&#x2F;12&#x2F;a-day-in-the-life-of-a-delivery-manager&#x2F;&quot;&gt;https:&#x2F;&#x2F;gds.blog.gov.uk&#x2F;2012&#x2F;12&#x2F;12&#x2F;a-day-in-the-life-of-a-delivery-manager&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The approach is not new, back in the year 2000 Joel Spolsky wrote:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Compare this to Microsoft, where things are done at the lowest level, and
most managers act like their most important job is to run around the room,
moving the furniture out of the way, so people can concentrate on their work.&lt;&#x2F;p&gt;
&lt;p&gt;~ Joel Spolsky -
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2000&#x2F;03&#x2F;19&#x2F;two-stories&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2000&#x2F;03&#x2F;19&#x2F;two-stories&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;running-great-delivery-teams&quot;&gt;Running great delivery teams&lt;&#x2F;h3&gt;
&lt;p&gt;You&#x27;ll also find the Delivery Manager doing inward-looking work similar to the
role of &quot;SCRUM Master&quot;. This includes setting up the right agile environment
(which may SCRUM, Kanban, or something else), tackling any dysfunction and poor
team performance that has built up, keeping in touch with all the team to make
sure they are happy and productive, running team retrospective sessions, and
sometimes hiring-and-firing to get the best team in place.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;is-it-good-for-devs&quot;&gt;Is it good for devs?&lt;&#x2F;h3&gt;
&lt;p&gt;As a developer on an Agile team working inside a government team (not for the
first time), I am eternally grateful for all the things I &lt;em&gt;don&#x27;t&lt;&#x2F;em&gt; have to worry
about because we have a DM. It&#x27;s not that I&#x27;m not capable, I&#x27;ll happily turn my
hand to the biggest problem of the day for a team at any time, but the code
won&#x27;t write itself and that&#x27;s what I was hired to be a pro at. Having a DM lets
me focus more creating software that actually does a job for our users, and
makes sure we can do what&#x27;s needed to make great systems even if that reaches
beyond the team&#x27;s original boundaries.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gov.uk&#x2F;service-manual&#x2F;the-team&#x2F;what-each-role-does-in-service-team&quot;&gt;https:&#x2F;&#x2F;www.gov.uk&#x2F;service-manual&#x2F;the-team&#x2F;what-each-role-does-in-service-team&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bizfluent.com&#x2F;info-8704880-role-software-delivery-manager.html&quot;&gt;https:&#x2F;&#x2F;bizfluent.com&#x2F;info-8704880-role-software-delivery-manager.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;itsadeliverything.com&#x2F;delivery-manager-a-new-role-for-an-agile-world&quot;&gt;http:&#x2F;&#x2F;itsadeliverything.com&#x2F;delivery-manager-a-new-role-for-an-agile-world&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;it.toolbox.com&#x2F;blogs&#x2F;deliverydr&#x2F;what-is-delivery-management-070606&quot;&gt;https:&#x2F;&#x2F;it.toolbox.com&#x2F;blogs&#x2F;deliverydr&#x2F;what-is-delivery-management-070606&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.greatsampleresume.com&#x2F;job-responsibilities&#x2F;delivery-manager-responsibilities&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.greatsampleresume.com&#x2F;job-responsibilities&#x2F;delivery-manager-responsibilities&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;work.chron.com&#x2F;job-description-service-delivery-manager-24247.html&quot;&gt;https:&#x2F;&#x2F;work.chron.com&#x2F;job-description-service-delivery-manager-24247.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;Whats-the-difference-between-a-delivery-manager-and-a-project-manager&quot;&gt;https:&#x2F;&#x2F;www.quora.com&#x2F;Whats-the-difference-between-a-delivery-manager-and-a-project-manager&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;melissaperri.com&#x2F;blog&#x2F;2017&#x2F;06&#x2F;29&#x2F;product-manager-vs-product-owner&quot;&gt;https:&#x2F;&#x2F;melissaperri.com&#x2F;blog&#x2F;2017&#x2F;06&#x2F;29&#x2F;product-manager-vs-product-owner&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to find contract developer clients</title>
        <published>2019-06-26T00:00:00+00:00</published>
        <updated>2019-06-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/06/26/how-to-find-contract-dev-jobs/"/>
        <id>https://0x5.uk/2019/06/26/how-to-find-contract-dev-jobs/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/06/26/how-to-find-contract-dev-jobs/">&lt;h2 id=&quot;handling-recruiters&quot;&gt;Handling recruiters&lt;&#x2F;h2&gt;
&lt;p&gt;Before you dive in, you might want to look at my &lt;a href=&quot;&#x2F;recruiters&#x2F;&quot;&gt;page on dealing with
recruiters&lt;&#x2F;a&gt;, especially if you are going to be dealing with
multiple recruiters at once.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rate-research-with-itjobswatch-co-uk&quot;&gt;Rate research with ITJobsWatch.co.uk&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itjobswatch.co.uk&#x2F;contracts&#x2F;uk&#x2F;developer.do&quot;&gt;IT JobsWatch&lt;&#x2F;a&gt; is a great guide to market prices. You can see numbers, graphs, trends, compare tech, and see what appears together.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s also a useful source of ideas for considering what might be a good investment in saleable skills.&lt;&#x2F;p&gt;
&lt;p&gt;Note the volume as well as the price, for example C# is massively higher volume than Ruby.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lead-sources&quot;&gt;Lead sources&lt;&#x2F;h2&gt;
&lt;p&gt;In rough order of the success I&#x27;ve had with them over the 7 years of contracting:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;jobserve&quot;&gt;JobServe&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jobserve.com&#x2F;gb&#x2F;en&#x2F;Job-Search&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.jobserve.com&#x2F;gb&#x2F;en&#x2F;Job-Search&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;By far the most reliable source of leads. Slightly shonky website, bit fiddly
to use but it seems that all the recruiters post their wares here.&lt;&#x2F;p&gt;
&lt;p&gt;Tactics:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Upload a pdf cv&lt;&#x2F;li&gt;
&lt;li&gt;Run a not particularly tight search (e.g. asp.net as a keyword with 50 mile radius, ordered by distance)&lt;&#x2F;li&gt;
&lt;li&gt;Blindly send your cv to all of them without worrying too much or bothering to address the post.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;jobserve-search.png&quot; alt=&quot;searching jobserve&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This might sound lazy, but in my experience I almost never hear back about the
advertised role, but what this does do is let recruiters that specialize in
your particular skills know you are actively looking, which is a lot easier for
them to make use of than hoping to tempt someone who isn&#x27;t.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;workable&quot;&gt;Workable&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jobs.workable.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;jobs.workable.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linkedin&quot;&gt;LinkedIn&lt;&#x2F;h3&gt;
&lt;p&gt;By posting regularly the progress of my search and asking contacts for help I
have had some luck getting referrals. I&#x27;ve never used LinkedIn&#x27;s proper job
posting system but it&#x27;s probably worth checking out.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s worth being careful if you are looking before leaving. I tend to not look
till I&#x27;ve finished the previous contract and had some time to refresh so that
hasn&#x27;t been an issue for me.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;linkedin-job-hunt-status&quot;&gt;LinkedIn job hunt status&lt;&#x2F;h4&gt;
&lt;p&gt;You can now set your &quot;open to work&quot; status to everyone, recruiters etc so be
sure to set that. I&#x27;ve definitely had inbound interest from that, albeit
relatively low quality. It also adds an overlay to your profile image which your
network might see when you post things.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;linkedin-hiring-groups&quot;&gt;LinkedIn Hiring groups&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;groups&#x2F;9031918&#x2F;&quot;&gt;Outside IR35 contracts board&lt;&#x2F;a&gt; group. - I can do invites if you want them. Let me know.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;recruiters&quot;&gt;Recruiters&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s probably worth reaching out to recruiters directly.&lt;&#x2F;p&gt;
&lt;p&gt;They cold email us so no reason not to go the other way when you need a job.
Could work out for everyone.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a useful list that you could use as a source of leads as well as a way
of filtering all the inbound email into a folder
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;alexmbird&#x2F;uk-it-recruiter-domains&#x2F;blob&#x2F;master&#x2F;domains.txt&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;alexmbird&#x2F;uk-it-recruiter-domains&#x2F;blob&#x2F;master&#x2F;domains.txt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;people-you-know-your-network&quot;&gt;People you know (your &quot;network&quot;)&lt;&#x2F;h3&gt;
&lt;p&gt;Possibly with the assistance of LinkedIn, WhatsApp, Telegram, Signal, Facebork etc.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t like to mention this as the idea of &quot;networking&quot; always made me cringe,
but the truth is who you know matters and can get you an &quot;in&quot; where you might
not have before, and indeed in the past I&#x27;ve won contracts through friends of
friends and repeat business.&lt;&#x2F;p&gt;
&lt;p&gt;It doesn&#x27;t seem very actionable, and when you need it it&#x27;s probably too late to
build a &quot;network&quot; of trust, but you can still reach out to the people you do
know with a friendly message and make it clear you&#x27;re looking (and be clear
about what you&#x27;re looking for - to trigger what &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jonathanstark.com&#x2F;daily&#x2F;20170127-dogfooding---rolodex-moments&quot;&gt;Jonathan Stark calls &quot;Rolodex
Moments&quot;&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;This is also a reminder to leave a trail of positive experiences with everyone you meet, go the extra mile, and invest a little regularly in your relationships whether you &quot;need&quot; them in the moment or not.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;others&quot;&gt;Others&lt;&#x2F;h3&gt;
&lt;p&gt;These are ones I&#x27;ve come across that you might want to cover if you are looking
to not miss anything, but I haven&#x27;t either used or succeeded with these myself.
Suggestions for additions to this list welcome, just drop me an email or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;timwise.co.uk&#x2F;edit&#x2F;master&#x2F;_posts&#x2F;2019-06-26-how-to-find-contract-dev-jobs.md&quot;&gt;raise
a PR&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gun.io&#x2F;find-work&#x2F;&quot;&gt;https:&#x2F;&#x2F;gun.io&#x2F;find-work&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;submitted?id=whoishiring&quot;&gt;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;submitted?id=whoishiring&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;outsideir35roles.com&#x2F;contract-listings&#x2F;&quot;&gt;https:&#x2F;&#x2F;outsideir35roles.com&#x2F;contract-listings&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;remoteok.io&#x2F;&quot;&gt;https:&#x2F;&#x2F;remoteok.io&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;snap.hr&#x2F;&quot;&gt;https:&#x2F;&#x2F;snap.hr&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;uk.indeed.com&quot;&gt;https:&#x2F;&#x2F;uk.indeed.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wellpaid.io&#x2F;&quot;&gt;https:&#x2F;&#x2F;wellpaid.io&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.jobs&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.amazon.jobs&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.contractoruk.com&#x2F;it_contract_jobs&quot;&gt;https:&#x2F;&#x2F;www.contractoruk.com&#x2F;it_contract_jobs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.contractspy.co.uk&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.contractspy.co.uk&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cv-library.co.uk&quot;&gt;https:&#x2F;&#x2F;www.cv-library.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cwjobs.co.uk&quot;&gt;https:&#x2F;&#x2F;www.cwjobs.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.icontract.co.uk&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.icontract.co.uk&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itcontractjobs.co.uk&quot;&gt;https:&#x2F;&#x2F;www.itcontractjobs.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.itjobboard.net&quot;&gt;https:&#x2F;&#x2F;www.itjobboard.net&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jobserve.com&quot;&gt;https:&#x2F;&#x2F;www.jobserve.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jobsite.co.uk&quot;&gt;https:&#x2F;&#x2F;www.jobsite.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;jobs&quot;&gt;https:&#x2F;&#x2F;www.linkedin.com&#x2F;jobs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.monster.co.uk&quot;&gt;https:&#x2F;&#x2F;www.monster.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reed.co.uk&quot;&gt;https:&#x2F;&#x2F;www.reed.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.technojobs.co.uk&quot;&gt;https:&#x2F;&#x2F;www.technojobs.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.upwork.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.upwork.com&#x2F;&lt;&#x2F;a&gt; - seems to be low paid commodity labour on an
international market largely, however I think some people have managed to
break through this and become in demand. At that point you&#x27;re basically an
entrepreneur.
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;What-should-I-do-to-increase-my-earnings-on-Upwork-when-I-have-been-registered-on-it-for-over-a-year-and-have-done-only-one-10-job-for-which-I-received-a-five-star-rating&quot;&gt;https:&#x2F;&#x2F;www.quora.com&#x2F;What-should-I-do-to-increase-my-earnings-on-Upwork-when-I-have-been-registered-on-it-for-over-a-year-and-have-done-only-one-10-job-for-which-I-received-a-five-star-rating&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.yunojuno.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.yunojuno.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;deceased-sites&quot;&gt;Deceased sites&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;del&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jobs.github.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;jobs.github.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;del&gt; - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.blog&#x2F;changelog&#x2F;2021-04-19-deprecation-notice-github-jobs-site&#x2F;&quot;&gt;github jobs decommissioned&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Sadly &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;meta.stackoverflow.com&#x2F;questions&#x2F;415293&#x2F;sunsetting-jobs-developer-story&quot;&gt;stackoverflow jobs has been decommissioned&lt;&#x2F;a&gt;. &lt;del&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;jobs?j=contract&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;jobs?j=contract&lt;&#x2F;a&gt;&lt;&#x2F;del&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;places-to-find-even-more&quot;&gt;Places to find even more&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;What-are-the-best-job-boards-for-software-engineers&quot;&gt;https:&#x2F;&#x2F;www.quora.com&#x2F;What-are-the-best-job-boards-for-software-engineers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;practical-tips&quot;&gt;Practical tips&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Track everything you&#x27;ve applied to (Trello, or HubSpot if you&#x27;re feeling rich).&lt;&#x2F;li&gt;
&lt;li&gt;Keep a copy of the full advert description and rate, they are often taken down before you speak to anyone which weakens your negotiation position.&lt;&#x2F;li&gt;
&lt;li&gt;Follow up with phone calls after applying - makes you more real, makes it easier for them.&lt;&#x2F;li&gt;
&lt;li&gt;Track all the businesses in your sector and technology, and their hiring managers and contact them before letting recruiters get in the middle.&lt;&#x2F;li&gt;
&lt;li&gt;See also my &lt;a href=&quot;&#x2F;recruiters&quot;&gt;recruiters page&lt;&#x2F;a&gt; for defense against the dark arts. Or you could just blanket declare &quot;no recruiters&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;about-this-post&quot;&gt;About this post&lt;&#x2F;h2&gt;
&lt;p&gt;Someone I know is looking for work (hello!) so rather than just emailing I
thought I&#x27;d make a more permanent list of all the places I&#x27;ve come across for
finding work as a contract developer.&lt;&#x2F;p&gt;
&lt;p&gt;For context, I&#x27;m a backend developer, specialising in Microsoft ASP.NET &#x2F; C# &amp;amp;
SQL Server databases, with a smattering of other things (t-shaped people as
they say).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up a static website&#x2F;blog with jekyll</title>
        <published>2019-06-24T00:00:00+00:00</published>
        <updated>2019-06-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/06/24/setting-up-a-jekyll-blog/"/>
        <id>https://0x5.uk/2019/06/24/setting-up-a-jekyll-blog/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/06/24/setting-up-a-jekyll-blog/">&lt;p&gt;A couple of people asked me for more info on my new blog setup here&#x27;s a rough
outline of what&#x27;s involved in setup and posting. There are &lt;em&gt;many&lt;&#x2F;em&gt; ways of doing
this, this is just the way that suited me best for now.&lt;&#x2F;p&gt;
&lt;p&gt;What you need to follow along:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A domain from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;uk.godaddy.com&#x2F;&quot;&gt;GoDaddy&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;An account on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;&quot;&gt;GitHub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;things-i-like-about-this-setup&quot;&gt;Things I like about this setup&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Built-in backups,&lt;&#x2F;li&gt;
&lt;li&gt;offline editing,&lt;&#x2F;li&gt;
&lt;li&gt;no shonkey web gui,&lt;&#x2F;li&gt;
&lt;li&gt;no charge for hosting with custom domain and https,&lt;&#x2F;li&gt;
&lt;li&gt;simple dev friendly templating,&lt;&#x2F;li&gt;
&lt;li&gt;a nice simple code-friendly mobile-friendly design,&lt;&#x2F;li&gt;
&lt;li&gt;full control.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;timwise.co.uk&#x2F;commits&#x2F;master&quot;&gt;public revision
history&lt;&#x2F;a&gt; of blog
posts with no extra effort (no more &quot;updated: blah&quot; in blog posts)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;why-jeykll-fits-that&quot;&gt;Why jeykll fits that&lt;&#x2F;h1&gt;
&lt;p&gt;A blog post like this one is just a text file in a special format called
markdown. These can then be trivially source-controlled with git, which serves
as version control and distributed backup in one neat package. I use git for
work so although it&#x27;s not the easiest tool to use that&#x27;s not a problem for me.
Theoretically if you don&#x27;t know git you could probably just do all your editing
in the github web interface these days.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the &lt;em&gt;entire&lt;&#x2F;em&gt; folder structure of this blog as it stands right now. You
can see there&#x27;s really not a lot too it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@fox:~&#x2F;repo&#x2F;timwise.co.uk(master)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ tree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── 404.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── about.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── categories.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── CNAME&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── _config.yml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── _drafts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── 2019-06-24-setting-up-a-jekyll-blog.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── favicon.ico&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── fonts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── aramisi.ttf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── EBGaramond-Regular.ttf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── FuturaPTLight.otf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── images&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── 404.jpg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── reverie-demo.png&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── reverie.png&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── reverie-text.png&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── _includes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── analytics.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── disqus.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── meta.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── svg-icons.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── index.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── _layouts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── default.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── page.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── post.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── LICENSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── _posts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── 2019-06-21-yet-another-new-blog.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── _sass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── _darcula.scss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── _highlights.scss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── _reset.scss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── _svg-icons.scss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── _variables.scss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── style.scss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 directories, 30 files&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The posts are just text files using the markdown format with a &lt;code&gt;.md&lt;&#x2F;code&gt; file extension instead of &lt;code&gt;.txt&lt;&#x2F;code&gt; and a short header for information like page title and tags. Here&#x27;s the top of this one:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;layout: post&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;title: Setting up a static website&#x2F;blog with jekyll&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;categories: [howto,backstage]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A couple of people asked me for more info on my new blog setup here&amp;#39;s a rough&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;outline of what&amp;#39;s involved in setup and posting. There are *many* ways of doing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;this, this is just the way that suited me best for now.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;how-i-set-it-up&quot;&gt;How I set it up&lt;&#x2F;h1&gt;
&lt;p&gt;I actually am reconfiguring from another setup, and used some advanced
sillyness, but I&#x27;ll simplify that here down to roughly the steps you&#x27;d need to
go from cold as I&#x27;m sure that&#x27;s more interesting to you.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Buy a domain from GoDaddy&lt;&#x2F;li&gt;
&lt;li&gt;Create a GitHub account&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duckduckgo.com&#x2F;?q=jekyll+themes&amp;amp;t=lm&amp;amp;ia=we:&#x2F;&#x2F;duckduckgo.com&#x2F;?q=jekyll+themes&amp;amp;t=lm&amp;amp;ia=web&quot;&gt;Find a jekyll
theme&lt;&#x2F;a&gt;
on become a base for your new site (the themes vary on how ready they are
for you to just crack on). Here&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;amitmerchant1990&#x2F;reverie&quot;&gt;the reverie
theme&lt;&#x2F;a&gt; that I used with minimal
customisation.&lt;&#x2F;li&gt;
&lt;li&gt;Go into the settings for your repo, &lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;jekyll-setup&#x2F;github-repo-settings-tab.png&quot; alt=&quot;enabling github pages by choosing a branch&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;turn on github pages, &lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;jekyll-setup&#x2F;github-pages-setup.png&quot; alt=&quot;github settings tab&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;configure your domain name, &lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;jekyll-setup&#x2F;github-custom-domain.png&quot; alt=&quot;github settings tab&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;enable https &lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;jekyll-setup&#x2F;github-https.png&quot; alt=&quot;github settings tab&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Go to GoDaddy and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.github.com&#x2F;en&#x2F;articles&#x2F;using-a-custom-domain-with-github-pages&quot;&gt;set up the DNS to point to the github
servers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;blogging-with-jekyll&quot;&gt;Blogging with Jekyll&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;Create new text file in the &lt;code&gt;_posts&lt;&#x2F;code&gt; folder, name it
&lt;code&gt;yyyy-mm-dd-your-post-title.md&lt;&#x2F;code&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;steal the header block from above and customise it for your post,&lt;&#x2F;li&gt;
&lt;li&gt;write stuff&lt;&#x2F;li&gt;
&lt;li&gt;use markdown for layout,&lt;&#x2F;li&gt;
&lt;li&gt;add images by saving them to an images folder and also adding them to your
git repo, use &lt;code&gt;![alt text](&#x2F;images&#x2F;something.png)&lt;&#x2F;code&gt; to show the image in your &lt;code&gt;.md&lt;&#x2F;code&gt; file,&lt;&#x2F;li&gt;
&lt;li&gt;check everything in &amp;amp; &lt;code&gt;git push&lt;&#x2F;code&gt; to github,&lt;&#x2F;li&gt;
&lt;li&gt;your changes are live within seconds of pushing.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If you aren&#x27;t up to the full &lt;code&gt;git&lt;&#x2F;code&gt; setup, you can edit your blog directly in github&#x27;s web interface.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Creating a new post
&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;jekyll-setup&#x2F;editing-new-file.png&quot; alt=&quot;creating a post&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Editing a post
&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;jekyll-setup&#x2F;editing-edit.png&quot; alt=&quot;editing a post&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Editing the text of a post
&lt;img src=&quot;&#x2F;images&#x2F;blog&#x2F;jekyll-setup&#x2F;editing-editing.png&quot; alt=&quot;editing the text of a post&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;advanced-ninja-coder-blogging&quot;&gt;Advanced ninja coder blogging&lt;&#x2F;h1&gt;
&lt;p&gt;Part of the reason I chose this particular setup is that plain markdown blogging with github pages allows me to use my existing coder tools to blog things really fast, reducing the barrier to me actually sharing useful insights and thoughts with you all.&lt;&#x2F;p&gt;
&lt;p&gt;You can see the advanced editing flow in action here:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=w3gMZTKcGKc&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=w3gMZTKcGKc&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;w3gMZTKcGKc&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;Here&#x27;s the tools I use, as shown in the above video:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Z_shell&quot;&gt;zsh&lt;&#x2F;a&gt; - allows changing directory without &lt;code&gt;cd&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;287014&#x2F;how-to-create-and-use-symbolic-links-aka-symlinks-on-linux&#x2F;&quot;&gt;symlinks&lt;&#x2F;a&gt; to link blog folder into &lt;code&gt;~&#x2F;blog&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;timwise.co.uk&#x2F;blob&#x2F;1024d49afab27b08ef060ac2d245a37a9d8b3837&#x2F;new&quot;&gt;shell script &lt;code&gt;new&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;timwise.co.uk&#x2F;blob&#x2F;1024d49afab27b08ef060ac2d245a37a9d8b3837&#x2F;_drafts&#x2F;template.md?plain=1&quot;&gt;template md file&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;jekyllrb.com&#x2F;&quot;&gt;jekyll&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pages.github.com&#x2F;&quot;&gt;github pages&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;timwise.co.uk&#x2F;actions&quot;&gt;github actions&lt;&#x2F;a&gt; - automatically deploys pages (automatically set up when you enable github pages)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;commonmark.org&#x2F;help&#x2F;&quot;&gt;markdown&lt;&#x2F;a&gt; - this is important, it allows efficiently writing richly formatted blog posts with nothing but an (advanced) text editor such as vim or vscode&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.vim.org&#x2F;&quot;&gt;vim&lt;&#x2F;a&gt; the original text editor (see also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;neovim.io&#x2F;&quot;&gt;neovim&lt;&#x2F;a&gt; that I haven&#x27;t got around to using yet)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;junegunn&#x2F;fzf&quot;&gt;fzf the fuzzy finder&lt;&#x2F;a&gt; - so I can type &lt;code&gt;**[tab]&lt;&#x2F;code&gt; and find any blog post easily&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;code.visualstudio.com&#x2F;&quot;&gt;vscode&lt;&#x2F;a&gt; with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=vscodevim.vim&quot;&gt;vscode vim emulator extension&lt;&#x2F;a&gt; - ctrl-p to open any post quickly&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;&quot;&gt;git&lt;&#x2F;a&gt; - provides history, and a very quick way to ship changes to the host (github) all on the command line&lt;&#x2F;li&gt;
&lt;li&gt;I have many &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;blob&#x2F;main&#x2F;.aliases&quot;&gt;command line aliases in my dotmatrix&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;blob&#x2F;main&#x2F;.gitconfig&quot;&gt;aliases in my gitconfig&lt;&#x2F;a&gt; - these make working on the commandline (cli) muuuch faster.&lt;&#x2F;li&gt;
&lt;li&gt;Ruby locally (advanced coder things)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;asdf-vm.com&#x2F;&quot;&gt;asdf-vm&lt;&#x2F;a&gt; to ensure I always have the right ruby version available on any machine, or can easily install it&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;671422&#x2F;how-to-use-tmux-on-linux-and-why-its-better-than-screen&#x2F;&quot;&gt;tmux&lt;&#x2F;a&gt; to allow me to have the server running in the background while I use the editor&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;⚠️ Note: ignore the &lt;code&gt;_site&lt;&#x2F;code&gt; folder when choosing the file to edit, that&#x27;s the generated cache and will be overwritten.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h1&gt;
&lt;p&gt;Wordpress was overcomplicated for my needs, and slower to use&#x2F;read, this new setup should mean I can tap away on the train and send new thoughts your way more regularly.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;extras&quot;&gt;Extras&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Bonus points for MailChimp&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mailchimp.com&#x2F;features&#x2F;rss-to-email&#x2F;&quot;&gt;rss to email&lt;&#x2F;a&gt; which means it&#x27;ll automatically hit your inbox. (I haven&#x27;t manageed to make it work yet though.)&lt;&#x2F;li&gt;
&lt;li&gt;Here&#x27;s all the jekyll gems github pages allows you to add &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;github&#x2F;pages-gem&#x2F;blob&#x2F;master&#x2F;lib&#x2F;github-pages&#x2F;plugins.rb#L5&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;github&#x2F;pages-gem&#x2F;blob&#x2F;master&#x2F;lib&#x2F;github-pages&#x2F;plugins.rb#L5&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Blog refresh - bye bye wordpress, hello jekyll</title>
        <published>2019-06-21T00:00:00+00:00</published>
        <updated>2019-06-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/06/21/yet-another-new-blog/"/>
        <id>https://0x5.uk/2019/06/21/yet-another-new-blog/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/06/21/yet-another-new-blog/">&lt;p&gt;The old blog is gone. Move over wordpress, long live &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pages.github.com&#x2F;&quot;&gt;github
pages&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I haven&#x27;t redirected the old subdomain or urls, but the stats tell me I had no
visitors so meh. If you want something let me know and I&#x27;ll repost it.&lt;&#x2F;p&gt;
&lt;p&gt;The new theme is : &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;amitmerchant1990&#x2F;reverie&quot;&gt;Reverie&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The full history and source of this blog is available in the open at
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;timwise.co.uk&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;timwise.co.uk&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Database tools I was surprised existed</title>
        <published>2019-06-10T00:00:00+00:00</published>
        <updated>2019-06-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2019/06/10/database-tools-you-didnt-know-about/"/>
        <id>https://0x5.uk/2019/06/10/database-tools-you-didnt-know-about/</id>
        
        <content type="html" xml:base="https://0x5.uk/2019/06/10/database-tools-you-didnt-know-about/">&lt;p&gt;But you already know all the tools for working with databases don&#x27;t you?&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s what I thought too before I started working on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&quot;&gt;SQL Schema
Explorer&lt;&#x2F;a&gt;. Even after 18 years working with
databases it turns out I only knew a fraction of the tools that are out there.&lt;&#x2F;p&gt;
&lt;p&gt;Working on SQL Schema Explorer gave me a reason I didn&#x27;t have before to search
the internet in new ways relating to databases, and now that I&#x27;m reaching out
to people about SQL Schema Explorer people are in turn sharing their favourite
tools with me.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d hate for this gift to sit hidden away in my private product trello board,
so I&#x27;ve turned it into this article so that you can skip the wilderness years
and gain a zen-like awareness of all the tools of your trade. I&#x27;m sure you
won&#x27;t like or use all of them, and many overlap in function, but the following
list will allow you to try out and asses each one against your needs; perhaps
you&#x27;ll find a new tool that will save you hours, or make your job that much
more enjoyable. Never again will you have to say to a new colleague &quot;oh I
hadn&#x27;t heard of that one!&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;microsoft-sql-server&quot;&gt;Microsoft Sql Server&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;ssms-tools-pack&quot;&gt;SSMS Tools Pack&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ssmstoolspack.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.ssmstoolspack.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An add-on to management studio that improves many pieces of of ssms and adds new capabilities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.ssmstoolspack.com&#x2F;Content&#x2F;Images&#x2F;Features&#x2F;CRUD.png&quot; alt=&quot;Screenshot of CRUD generation in SSMS Tools&quot; &#x2F;&gt;{:height=&quot;200px&quot;}&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;€30 for first computer to €5000 for unlimited enterprise use (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ssmstoolspack.com&#x2F;Licensing&quot;&gt;SSMS Toolpack
Pricing page&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A friend of mine saved many hours using the &quot;CRUD&quot; stored procedure generation capabilities.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sql-server-management-studio-ssms&quot;&gt;Sql Server Management Studio (SSMS)&lt;&#x2F;h3&gt;
&lt;p&gt;Okay you know this one but I have to mention it.&lt;&#x2F;p&gt;
&lt;p&gt;It has awkward but functional diagram support. You can version control these
diagrams and move them between servers with
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;database-diagram-scm&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;database-diagram-scm&lt;&#x2F;a&gt; which is worth knowing about
if you ever use the ssms diagrams.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;you-can-now-run-mssql-on-open-source&quot;&gt;You can now run MSSQL on open source&lt;&#x2F;h3&gt;
&lt;p&gt;Did you know Microsoft SQL Server (aka mssql) is now available on both linux
natively and in docker containers? It&#x27;s the real deal, not like mono vs .net&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;sql&#x2F;linux&#x2F;sql-server-linux-setup&quot;&gt;SQL Server on Linux&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;sql&#x2F;linux&#x2F;quickstart-install-connect-docker?view=sql-server-2017&quot;&gt;SQL Server in Docker&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here&#x27;s all it takes to fire up mssql, the only pre-requisite is docker itself.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;docker run -e &amp;#39;ACCEPT_EULA=Y&amp;#39; -e &amp;#39;SA_PASSWORD=your_new_sa_passwod&amp;#39; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-p 1433:1433 --name mssql1 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-d mcr.microsoft.com&#x2F;mssql&#x2F;server:2017-latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This isn&#x27;t a tool per-se, but this is too important to not mention, especially
as it&#x27;s quite new and not everyone is aware of this exciting change from
redmond.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t know about you but one less reason to fire up the Windows VM sure does
make me happy. Combined with dotnet core I haven&#x27;t fired up Windows in months
now.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cross-database&quot;&gt;Cross-database&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;razor-sql&quot;&gt;Razor Sql&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.razorsql.com&#x2F;images&#x2F;razorsql&#x2F;main45.jpg&quot; alt=&quot;Razor Sql Screenshot&quot; &#x2F;&gt;{:height=&quot;200px&quot;}&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.razorsql.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.razorsql.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;RazorSQL is an SQL query tool, database browser, SQL editor, and database
administration tool for Windows, macOS, Mac OS X, Linux, and Solaris.
RazorSQL has been tested on over 40 databases, can connect to databases via
either JDBC or ODBC&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;ez-data-browser&quot;&gt;EZ Data Browser&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;www.softimum-solutions.com&#x2F;Content&#x2F;Images&#x2F;Overview.png&quot; alt=&quot;EZ Data Browser Screenshot&quot; &#x2F;&gt;{:height=&quot;200px&quot;}&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.softimum-solutions.com&#x2F;Data-Browser&#x2F;Overview.aspx&quot;&gt;http:&#x2F;&#x2F;www.softimum-solutions.com&#x2F;Data-Browser&#x2F;Overview.aspx&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;$29.99 per computer&lt;&#x2F;li&gt;
&lt;li&gt;Licence key by email&lt;&#x2F;li&gt;
&lt;li&gt;pay via PayPal of credit card&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;software from Softimum Solutions to help users to browse and to edit SQL Server databases quickly and easily&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Provides a configurable MSAccess-like interface to a database.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sqleo&quot;&gt;SQLeo&lt;&#x2F;h3&gt;
&lt;p&gt;Cross-database query builder&#x2F;analyser. Feature rich - data&#x2F;schema compare, pivot queries, diagrams etc.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;sqleo.sourceforge.net&#x2F;images&#x2F;Pivot%20Query.PNG&quot; alt=&quot;SQLeo screenshot&quot; &#x2F;&gt;{:height=&quot;200px&quot;}&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sqleo.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;sqleo.sourceforge.net&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;A powerful SQL tool to transform or reverse complex queries (generated by
OBIEE, Microstrategy, Cognos, Hyperion, Pentaho ...) into diagrams to ease
visualization and analysis. A graphical query builder that permits to create
complex SQL queries easily. The GUI with multi-connections supports virtually
all JDBC drivers, including ODBC bridge, Oracle, MySQL, PostgreSQL, Firebird,
HSQLDB, H2, CsvJdbc, SQLite. And top of that, everything is open-source!&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=emDrdj0IxNI&quot;&gt;SQLeo demo video on youtube&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Sourceforge page (ugh) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;sqleo&#x2F;&quot;&gt;https:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;sqleo&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Fork on github &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ojwanganto&#x2F;SQLeo&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;ojwanganto&#x2F;SQLeo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;sql-fiddle&quot;&gt;SQL Fiddle&lt;&#x2F;h3&gt;
&lt;p&gt;Live online sql editor &#x2F; runner&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;static&#x2F;images&#x2F;blog&#x2F;db-tools&#x2F;sqlfiddle-screenshot.png&quot; alt=&quot;SQL Fiddle screenshot&quot; &#x2F;&gt;{:height=&quot;200px&quot;}&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sqlfiddle.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;sqlfiddle.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;dbschema&quot;&gt;DbSchema&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.dbschema.com&#x2F;images&#x2F;screenshots&#x2F;database-er-diagram.png&quot; alt=&quot;DbSchema screenshot&quot; &#x2F;&gt;{:height=&quot;200px&quot;}&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.dbschema.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.dbschema.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;DbSchema is an SQL and No-SQL database designer featuring interactive
diagrams, HTML and PDF documentation, schema versioning and migration,
relational data browse, random data generator, visual query builder, SQL
editor and database reports.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;dbprompt&quot;&gt;DbPrompt&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;www.dbschema.com&#x2F;images&#x2F;dbprompt.png&quot; alt=&quot;DbPrompt screenshot&quot; &#x2F;&gt;{:height=&quot;200px&quot;}&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.dbschema.com&#x2F;dbprompt.html&quot;&gt;http:&#x2F;&#x2F;www.dbschema.com&#x2F;dbprompt.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Free Universal Multi-Database SQL Prompt - DbPrompt can execute queries on
multiple databases, transfer data between databases, upload result files on
ftp servers, execute complex SQL scripts using Java Groovy and cron-schedule
scripts for execution and report failures per email. DbPrompt supports all
SQL and NoSQL databases, like MySql, Cassandra, PostgreSql, MongoDb,
Redshift, SqlServer, Azure, Oracle, Teradata and more. DbPrompt can work on
all operating systems. DbPrompt is free of charge. &quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;unsorted-omg-will-it-never-end&quot;&gt;Unsorted - omg will it never end&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.magereverse.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.magereverse.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dataedo.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;dataedo.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dbvis.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;dbvis.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;sql&#x2F;azure-data-studio&quot;&gt;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;sql&#x2F;azure-data-studio&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ajdeziel&#x2F;SQL-Data-Viewer&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;ajdeziel&#x2F;SQL-Data-Viewer&lt;&#x2F;a&gt; - abandoned&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;preston&#x2F;railroady&#x2F;&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;preston&#x2F;railroady&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.talend.com&#x2F;reader&#x2F;ISPDm8GQ6s0HN0348QulWg&#x2F;Ij~7tBlW8im63rAGnGHT3A&quot;&gt;https:&#x2F;&#x2F;help.talend.com&#x2F;reader&#x2F;ISPDm8GQ6s0HN0348QulWg&#x2F;Ij~7tBlW8im63rAGnGHT3A&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;portableapps.com&#x2F;apps&#x2F;development&#x2F;database_browser_portable&quot;&gt;https:&#x2F;&#x2F;portableapps.com&#x2F;apps&#x2F;development&#x2F;database_browser_portable&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;redash.io&#x2F;&quot;&gt;https:&#x2F;&#x2F;redash.io&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sequelpro.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;sequelpro.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;softwarerecs.stackexchange.com&#x2F;questions&#x2F;11346&#x2F;tool-to-visualize-sql-database-schema&quot;&gt;https:&#x2F;&#x2F;softwarerecs.stackexchange.com&#x2F;questions&#x2F;11346&#x2F;tool-to-visualize-sql-database-schema&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqldbm.com&#x2F;en&#x2F;&quot;&gt;https:&#x2F;&#x2F;sqldbm.com&#x2F;en&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqlitestudio.pl&#x2F;&quot;&gt;https:&#x2F;&#x2F;sqlitestudio.pl&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.codediesel.com&#x2F;data&#x2F;5-tools-to-visualize-database-schemas&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.codediesel.com&#x2F;data&#x2F;5-tools-to-visualize-database-schemas&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.datasparc.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.datasparc.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.dbsoftlab.com&#x2F;online-tutorials&#x2F;active-table-editor-online-tutorials.html&quot;&gt;https:&#x2F;&#x2F;www.dbsoftlab.com&#x2F;online-tutorials&#x2F;active-table-editor-online-tutorials.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.devart.com&#x2F;dbforge&#x2F;sql&#x2F;studio&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.devart.com&#x2F;dbforge&#x2F;sql&#x2F;studio&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.idera.com&#x2F;er-studio-data-architect-saftware&quot;&gt;https:&#x2F;&#x2F;www.idera.com&#x2F;er-studio-data-architect-saftware&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jetbrains.com&#x2F;datagrip&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.jetbrains.com&#x2F;datagrip&#x2F;&lt;&#x2F;a&gt; - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Xb9K8IAdZNg&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Xb9K8IAdZNg&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.metabase.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.metabase.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.navicat.com&#x2F;en&#x2F;products&#x2F;navicat-data-modeler&quot;&gt;https:&#x2F;&#x2F;www.navicat.com&#x2F;en&#x2F;products&#x2F;navicat-data-modeler&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.schemacrawler.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.schemacrawler.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlservercentral.com&#x2F;articles&#x2F;microsoft-sql-server-utilities-and-tools-1&quot;&gt;https:&#x2F;&#x2F;www.sqlservercentral.com&#x2F;articles&#x2F;microsoft-sql-server-utilities-and-tools-1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jetbrains.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;jetbrains.com&#x2F;&lt;&#x2F;a&gt; intellij&#x2F;rider&#x2F;rubymine etc all have the datagrip capabilities built in&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.red-gate.com&#x2F;&lt;&#x2F;a&gt; sql prompt etc&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.oracle.com&#x2F;database&#x2F;technologies&#x2F;appdev&#x2F;datamodeler.html&quot;&gt;https:&#x2F;&#x2F;www.oracle.com&#x2F;database&#x2F;technologies&#x2F;appdev&#x2F;datamodeler.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;erwin.com&#x2F;products&#x2F;erwin-data-modeler&#x2F;&quot;&gt;https:&#x2F;&#x2F;erwin.com&#x2F;products&#x2F;erwin-data-modeler&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;DBeaver&lt;&#x2F;li&gt;
&lt;li&gt;Azure Data Studio - PostgreSQL extension&lt;&#x2F;li&gt;
&lt;li&gt;SAP PowerDesigner &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sap.com&#x2F;products&#x2F;powerdesigner-data-modeling-tools.html&quot;&gt;https:&#x2F;&#x2F;www.sap.com&#x2F;products&#x2F;powerdesigner-data-modeling-tools.html&lt;&#x2F;a&gt; - I have no idea what this is. Sounds enterprisey.
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;PowerDesigner&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;PowerDesigner&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.idera.com&#x2F;er-studio-enterprise-data-modeling-and-architecture-tools&quot;&gt;https:&#x2F;&#x2F;www.idera.com&#x2F;er-studio-enterprise-data-modeling-and-architecture-tools&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.idera.com&#x2F;er-studio-data-architect-software&quot;&gt;https:&#x2F;&#x2F;www.idera.com&#x2F;er-studio-data-architect-software&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sparxsystems.com&#x2F;products&#x2F;ea&#x2F;&quot;&gt;https:&#x2F;&#x2F;sparxsystems.com&#x2F;products&#x2F;ea&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ibm.com&#x2F;us-en&#x2F;marketplace&#x2F;infosphere-data-architect&quot;&gt;https:&#x2F;&#x2F;www.ibm.com&#x2F;us-en&#x2F;marketplace&#x2F;infosphere-data-architect&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.postgrescompare.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.postgrescompare.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;places-to-find-even-more-database-tools-and-learn-more&quot;&gt;Places to find even more database tools and learn more&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Comparison_of_database_tools&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Comparison_of_database_tools&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;How-do-I-generate-an-entity-relationship-diagram-for-a-SQLite-database-file?share=1&quot;&gt;https:&#x2F;&#x2F;www.quora.com&#x2F;How-do-I-generate-an-entity-relationship-diagram-for-a-SQLite-database-file?share=1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;What-are-some-good-online-database-schema-design-tool-with-larger-days-of-expiry&quot;&gt;https:&#x2F;&#x2F;www.quora.com&#x2F;What-are-some-good-online-database-schema-design-tool-with-larger-days-of-expiry&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;alternativeto.net&#x2F;software&#x2F;mysql-workbench&#x2F;&quot;&gt;https:&#x2F;&#x2F;alternativeto.net&#x2F;software&#x2F;mysql-workbench&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.datasciencecentral.com&#x2F;profiles&#x2F;blogs&#x2F;top-6-data-modeling-tools&quot;&gt;https:&#x2F;&#x2F;www.datasciencecentral.com&#x2F;profiles&#x2F;blogs&#x2F;top-6-data-modeling-tools&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.educba.com&#x2F;9-best-data-modeling-tools&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.educba.com&#x2F;9-best-data-modeling-tools&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.agiledata.org&#x2F;essays&#x2F;dataModeling101.html&quot;&gt;http:&#x2F;&#x2F;www.agiledata.org&#x2F;essays&#x2F;dataModeling101.html&lt;&#x2F;a&gt; - I had no idea what data modelling really meant before reading this.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sqlservercentral.com&#x2F;articles&#x2F;Tools&#x2F;157911&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.sqlservercentral.com&#x2F;articles&#x2F;Tools&#x2F;157911&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.apgdiff.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.apgdiff.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;toolsfordatabases.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;toolsfordatabases.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.webfx.com&#x2F;blog&#x2F;web-design&#x2F;top-five-best-database-management-tools&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.webfx.com&#x2F;blog&#x2F;web-design&#x2F;top-five-best-database-management-tools&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solutionsreview.com&#x2F;data-management&#x2F;data-management-solutions-directory&#x2F;&quot;&gt;https:&#x2F;&#x2F;solutionsreview.com&#x2F;data-management&#x2F;data-management-solutions-directory&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.softwaretestinghelp.com&#x2F;tools&#x2F;26-best-data-integration-tools&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.softwaretestinghelp.com&#x2F;tools&#x2F;26-best-data-integration-tools&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;information-overload&quot;&gt;Information overload&lt;&#x2F;h2&gt;
&lt;p&gt;If you got this far you probably need to get back to work. It&#x27;s clear this
article is a bit ridiculous now so I&#x27;m not going to carry on sorting it out.
The internet is littered with catalog articles of varying completeness and
quality. To make it complete and good would make it dull and endless.&lt;&#x2F;p&gt;
&lt;p&gt;Watch this space, I think I&#x27;ll try and work out what people actually are trying
to do and cater for that. Maybe we can all build a collaborative index
somewhere.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-end&quot;&gt;The end&lt;&#x2F;h2&gt;
&lt;p&gt;I hope you found at least a few you didn&#x27;t know about and that they make your
life better in some way. Please do tell me the story of how this helped you on
&lt;a href=&quot;https:&#x2F;&#x2F;0x5.uk&#x2F;2019&#x2F;06&#x2F;10&#x2F;database-tools-you-didnt-know-about&#x2F;tim@schemaexplorer.io&quot;&gt;email&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;tim_abell&quot;&gt;twitter&lt;&#x2F;a&gt;.
Did I miss something? If you wish to improve this article please ping me a PR
with additions here: https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sdv-website or just &lt;a href=&quot;https:&#x2F;&#x2F;0x5.uk&#x2F;2019&#x2F;06&#x2F;10&#x2F;database-tools-you-didnt-know-about&#x2F;tim@schemaexplorer.io&quot;&gt;email
me&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not being paid to promote these, these are not affiliate links, I share
this learning with you all for free so that we can all enjoy our work with
databases more, and create better more reliable databases for ourselves, our
clients and our projects.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to be notified of new articles, sign up to the mailing list (which
currently is also the trial download list).&lt;&#x2F;p&gt;
&lt;p&gt;Till next time!&lt;&#x2F;p&gt;
&lt;p&gt;Originally posted at &lt;a href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;blog&#x2F;2019&#x2F;06&#x2F;10&#x2F;database-tools-you-didnt-know-about.html&quot;&gt;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;blog&#x2F;2019&#x2F;06&#x2F;10&#x2F;database-tools-you-didnt-know-about.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Teardown of a landing page story</title>
        <published>2018-12-10T08:40:13+00:00</published>
        <updated>2018-12-10T08:40:13+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/12/10/teardown-of-a-landing-page-story/"/>
        <id>https://0x5.uk/2018/12/10/teardown-of-a-landing-page-story/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/12/10/teardown-of-a-landing-page-story/">&lt;p&gt;Here&#x27;s my analysis of the depth of information and thought that&#x27;s gone into a deceptively brief piece of landing-page copy. It&#x27;s from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;realtimeboard.com&#x2F;blog&#x2F;accelerate-growth-early-stage-startups&#x2F;&quot;&gt;https:&#x2F;&#x2F;realtimeboard.com&#x2F;blog&#x2F;accelerate-growth-early-stage-startups&#x2F;&lt;&#x2F;a&gt; that I&#x27;m trying to use as inspiration for &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&quot;&gt;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I had to de-construct the example story in order to work out how to do my own so having put the work in I thought I&#x27;d share it with you all here.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Here&#x27;s the original in full:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Hey, I know that you have two kids and you’re always buying the same milk, eggs, peanut butter, and bread every single week, but you’re also both really busy working parents. You don’t have much time and you’d much rather be able to spend time at home with your family than being at a busy grocery store. So there’s this great service called Farmstead where you’re able to have that same stuff delivered to you. You don’t even have to think about it, you don’t have to remember each week to put in all of those same things that you order on a weekly basis anyway. They can just bring it to you and you don’t have to worry about it. Delivery is free with a weekly subscription. I think you should definitely try this out, I think you’re going to save yourself a bunch of time.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;And now one piece at a time with my observations about what is being conveyed in this information-dense block of prose. You are looking at the work of a pro when you read the above text, and unless you look closely it&#x27;s easy to miss just how carefully crafted the whole thing is and how it touches on so many thoughts and feelings the ideal customer of Farmstead is likely to have, guiding them to the conclusion that they should give the service a try.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;blockquote&gt;
&lt;p&gt;Hey,&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;being personable, we are not a big faceless corporation, you can actually talk to us like humans&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I know that you have two kids&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;narrow down audience to parents (turn off non-parents, get parents more interested)&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;and you’re always buying the same milk, eggs, peanut butter, and bread&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;describe a behaviour they recognise they already do (increase engagement with the text, encourage reading further), hint that we&#x27;re going to solve a problem they have because they might be annoyed about the regular chore&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;every single week,&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;slightly pejorative terminology hints at the fact you might not be happy about repeating this tedious task, draw attention to your current pain that we&#x27;re going to solve&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;but you’re also both really busy working parents.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;focus down the pain point to be that it&#x27;s a time consuming repeating the task and you wish you had more time back, hint that we&#x27;re going to be giving that time back to you&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;You don’t have much time&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;really drive that &lt;em&gt;you have no time&lt;&#x2F;em&gt; point home&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;and you’d much rather be able to spend time at home with your family&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;paint a picture of how much better your life would be if you take on our solution to your pain. Point out just what you&#x27;re sacrificing to go to the shops.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;than being at a busy grocery store.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;not only do you have the pain of lost time, but the experience of shopping is unpleasant (because it&#x27;s so busy)&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Now that you know it&#x27;s you we want to help, we recognise your pain and we&#x27;ve shown we know how your life could be better...&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;So there’s this great service called Farmstead&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Introduce the brand name. Tease. Read on to satisfy that completion-bias tendency in your brain that leaves you yearning to know what information you don&#x27;t have about this &quot;Farmstead&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Also the name itself conveys a lot of meaning&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Farm&quot; - fresh produce, direct from the supplier
&quot;stead&quot; - homely, small supplies, not industrial or full of chemicals&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;where you’re able to have that same stuff&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;allay the fear that you&#x27;ll still have to go back to the old thing anyway because there&#x27;s something we don&#x27;t sell&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;delivered to you.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;oh I see, so it&#x27;s a door to door delivery service. Noted. The shape of the offering is starting to emerge.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;You don’t even have to think about it,&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We&#x27;ve worked really hard on all our UX (user experience), automated as much as possible etc. so this will be easier than what you do now and better than competitors can do&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;you don’t have to remember each week to put in all of those same things that you order on a weekly basis anyway.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;now you know it&#x27;s even got built in scheduled deliveries&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;They can just bring it to you&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;re-iterate delivery&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;and you don’t have to worry about it.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;reminder that you do have have to worry about getting your normal shop done, speaks to pain of running out of the things because you forgot, worrying how you&#x27;re going to fit it in your day. Differentiates new offering as being something that just happens meaning you never run out&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Delivery is free&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Objection handling - people don&#x27;t want to pay for delivery when they could go to shops for nothing (even though it has a cost it&#x27;s how people see it). People have been burned before by finding something good then being stung for expensive delivery. I would expect that this is a common objection&#x2F;question that came back in earlier rounds of testing with users and it&#x27;s been integrated into this prose to pre-empt the question before it&#x27;s even been asked.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;with a weekly subscription.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;warm people up to the payments they&#x27;ll have to make in a non-threatening way&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I think you should definitely try this out,&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;nudge to take action. &quot;Try&quot; implies that it&#x27;s not a commitment and you can change your mind, allaying fears of being locked in for a year&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I think you’re going to save yourself a bunch of time.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;point to hard cost-benefit for the service - you don&#x27;t have time (as mentioned to start with, we know this person feels like they have no time because they are still reading after they identified with the first section). One last reminder of the key pain to the offering solves - lack of time&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Let me know if that&#x27;s helped you in any way.&lt;&#x2F;p&gt;
&lt;p&gt;If you happen to be someone that deals with databases and are keen to try new tools then please do me a favour and sign up to the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&quot;&gt;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&lt;&#x2F;a&gt; mailing list (you&#x27;ll have to ignore my terrible marketing text till I&#x27;m as good as Brady).&lt;&#x2F;p&gt;
&lt;p&gt;~ Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Modern Digital Government Outsourcer</title>
        <published>2018-10-30T14:19:26+00:00</published>
        <updated>2018-10-30T14:19:26+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/10/30/a-modern-digital-government-outsourcer/"/>
        <id>https://0x5.uk/2018/10/30/a-modern-digital-government-outsourcer/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/10/30/a-modern-digital-government-outsourcer/">&lt;p&gt;I&#x27;ve done a few contracts for our dear government and an idea for a business is starting to form. Here is the first draft of these ideas as a starting point for discussion and improvement.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem-as-i-see-it&quot;&gt;The problem as I see it&lt;&#x2F;h2&gt;
&lt;p&gt;From my somewhat limited perspective as someone who has worked on a few software projects for government, including having the privilege of a brief stint with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gov.uk&#x2F;government&#x2F;organisations&#x2F;government-digital-service&quot;&gt;GDS&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Government_Digital_Service&quot;&gt;wikipedia page on GDS&lt;&#x2F;a&gt;), I can see a looming problem of capacity that I wonder if I can help with.&lt;&#x2F;p&gt;
&lt;p&gt;A change is happening to the way government runs digital projects (or entire services with a digital aspect I should say). This change was kicked off with the formation of GDS back in 2011, and has been &lt;strong&gt;rippling out&lt;&#x2F;strong&gt; across the many departments of government ever since.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;strong&gt;skills&lt;&#x2F;strong&gt; to run such projects are in ever increasing demand as more politicians and senior civil servants realise the effectiveness of the approach and are pushed into the approach by the controls made available to GDS through the Cabinet Office.&lt;&#x2F;p&gt;
&lt;p&gt;Some of the projects going on in government a resourced with &lt;strong&gt;existing internal people&lt;&#x2F;strong&gt; (many of whom are contractors) who have been moving around departments executing brilliantly in the true spirit of who GDS started, but there are only so many of these people to go around.&lt;&#x2F;p&gt;
&lt;p&gt;There are &lt;strong&gt;consultancies who &quot;do agile&quot;&lt;&#x2F;strong&gt;, but that is only part of the picture of spinning up a new digital-focussed project and having it succeed.&lt;&#x2F;p&gt;
&lt;p&gt;And then there&#x27;s the &lt;strong&gt;big old outsourcers&lt;&#x2F;strong&gt; who have for decades been the go-to for large government IT. It strikes me that the old-world outsources struggle to meet the needs of the new world, as it&#x27;s a fundamental shift away from outsource-all-the-knowledge &#x2F; lowest-bidder-wins &#x2F; change-requests-for-profit model that to be fair they have been incentivised to operate within.&lt;&#x2F;p&gt;
&lt;p&gt;All of this leaves ministers and civil servants who have seen how well it can be done wondering where on earth they can find the people they need to make a project a success. It&#x27;s all very well having a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gov.uk&#x2F;service-manual&#x2F;service-standard&quot;&gt;service standard&lt;&#x2F;a&gt; that advocates a modern user-centred service but if you can&#x27;t rustle up a team or outsourcer who can make that happen then you are stuck in the old world with broken, overpriced and inflexible IT systems that we are so used to.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the GDS way is not a refusal to use outsourcers at all, rather it is a call to not be held to ransom by outsourcers by passing all skills and knowledge over to them wholesale and them being unable to control them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-new-breed-of-outsourcer&quot;&gt;A new breed of outsourcer&lt;&#x2F;h2&gt;
&lt;p&gt;Here I&#x27;m going to set out a rough design for a business that could help senior people in government deliver these services. Your feedback and ideas would be greatly appreciated as I cannot create this alone.&lt;&#x2F;p&gt;
&lt;p&gt;The business would take &lt;strong&gt;leadership&lt;&#x2F;strong&gt; in researching, designing, iterating and building services where a department currently lacks the capacity to do so but has the desire to build a modern service for some perceived user need. It would do this by supplying one or more people who truly understand the GDS-way, and will guide the service through the cycles of discovery and delivery.&lt;&#x2F;p&gt;
&lt;p&gt;The business would explicitly &lt;strong&gt;not&lt;&#x2F;strong&gt; try to capture ownership, insider knowledge or advantage over the department in order to gain control over the service. Instead the business would ensure that the department receives the benefit of learning that happens during the project, producing outputs that can be referred to in the long run, and ensuring that relevant people within the department are (with the assistance of the department) deeply involved in the process.&lt;&#x2F;p&gt;
&lt;p&gt;The business would attain speed of delivery by recruiting and training a team to be able to assist the department in conducting research and delivering services. This team would consist of mixture of senior people who can make sure the GDS way is followed as much in spirit as in letter, and a deeper pool of more mixed experience who can be guided by the senior team members in delivering effectively in a way that works for the department, GDS, and the users. The business shall build processes around this team that assist them in repeatably recruiting, training and scaling while retaining the core principles that work in the favour of government and our users.&lt;&#x2F;p&gt;
&lt;p&gt;The department will be encouraged (maybe even required?) to build internal capability (i.e. have enough smart skilled people) to retain the knowledge gained during the process of building a service (or perhaps learning that it doesn&#x27;t make sense to build a particular service). The department will also be encouraged to actively recruit team members to bolster their ability to run the services in the long term and retain the knowledge gained as a service is created and evolved (perhaps for an appropriate fee to compensate for the investment in the people who pass through the business&#x27;s doors).&lt;&#x2F;p&gt;
&lt;p&gt;The business needs to be a profitable enterprise in order to be a sustainable entity that can help our government in the long run. Suggestions for funding models most welcome!&lt;&#x2F;p&gt;
&lt;p&gt;The business will not retain any assets &#x2F; intellectual property etc. would allow the government to be held to ransom by the business. The government will always have the option to take the whole service in-house, or choose another outsourcer. Support for transition will gladly be provided (for a reasonable fee). The government is encouraged to own its own services.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-are-you-different-from-public-digital&quot;&gt;How are you different from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;public.digital&#x2F;&quot;&gt;public digital&lt;&#x2F;a&gt;?&lt;&#x2F;h2&gt;
&lt;p&gt;Public Digital https:&#x2F;&#x2F;public.digital&#x2F; are a business founded by the founding members of GDS, and are off transforming other governments and organisations from scratch. That&#x27;s a lofty goal and I wish them well! My goals are more modest, simply to provide the capacity, processes and skills pool for government deliver on the vision and habit of delivery left in the wake of these powerhouses of change. I hope I can make even a thousandth the impact they have made.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-get-there-from-here&quot;&gt;How to get there from here&lt;&#x2F;h2&gt;
&lt;p&gt;Currently I&#x27;m contracting, I like the idea of slowly growing a team from here to there. I&#x27;m not in a position to just drop everything and gamble everything on success, but perhaps there can be a smoother transition. For now I just want to have as many conversations as possible, so &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;get in touch&lt;&#x2F;a&gt; and let me know how you feel about the whole idea. Love it? Hate it? I want to know.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;get-involved&quot;&gt;Get involved&lt;&#x2F;h2&gt;
&lt;p&gt;Drop me an email: &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;tim@timwise.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sign up to the mailing list: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eepurl.com&#x2F;dLU4Rs&quot;&gt;http:&#x2F;&#x2F;eepurl.com&#x2F;dLU4Rs&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Always add braces</title>
        <published>2018-08-28T12:14:02+01:00</published>
        <updated>2018-08-28T12:14:02+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/08/28/always-add-braces/"/>
        <id>https://0x5.uk/2018/08/28/always-add-braces/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/08/28/always-add-braces/">&lt;p&gt;Small matter of code style that I keep coming across.&lt;&#x2F;p&gt;
&lt;p&gt;Whether to write&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;thing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt; Action&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;or&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;thing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;  Action&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;or&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#859900, #859900);&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;thing&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;	Action&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We should always use the braces to avoid introducing bugs when modifying the code manually or through merge tools.&lt;&#x2F;p&gt;
&lt;p&gt;For the reasons behind this, read the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2005&#x2F;05&#x2F;11&#x2F;making-wrong-code-look-wrong&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2005&#x2F;05&#x2F;11&#x2F;making-wrong-code-look-wrong&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dzone.com&#x2F;articles&#x2F;omitting-braces-not-just-a-mat&quot;&gt;https:&#x2F;&#x2F;dzone.com&#x2F;articles&#x2F;omitting-braces-not-just-a-mat&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20220406111833&#x2F;https:&#x2F;&#x2F;nakedsecurity.sophos.com&#x2F;2014&#x2F;02&#x2F;24&#x2F;anatomy-of-a-goto-fail-apples-ssl-bug-explained-plus-an-unofficial-patch&#x2F;&quot;&gt;Anatomy of a “goto fail” – Apple’s SSL bug explained, plus an unofficial patch for OS X!&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>5 ways to make your database better - by Tim Abell</title>
        <published>2018-07-10T00:00:00+00:00</published>
        <updated>2018-07-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/07/10/5-ways-to-make-your-database-better/"/>
        <id>https://0x5.uk/2018/07/10/5-ways-to-make-your-database-better/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/07/10/5-ways-to-make-your-database-better/">&lt;h2 id=&quot;1-documentation&quot;&gt;[1] Documentation&lt;&#x2F;h2&gt;
&lt;p&gt;Shoot me okay, but maintenance of software is [insert large number here] times
the cost of creation, especially with relational databases. You are a pro
working for a client, you owe it to them to make it possible for them to have
future staff (and yourself!) be as effective as possible. You put all that
effort into figuring out why a column should exist and have that name, now
share that knowledge before you move on to the next greenfield project&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;products&#x2F;sql-development&#x2F;sql-doc&#x2F;&quot;&gt;Redgate SqlDoc&lt;&#x2F;a&gt;
is great for rapidly adding missing documentation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaspy.org&#x2F;&quot;&gt;SchemaSpy&lt;&#x2F;a&gt; generates static html sites making it easy
to see what documentation there is (or isn&#x27;t!) and share it with the team.
It&#x27;s free &amp;amp; open source (although a bit fiddly to set up and run). It has
particularly nice clickable diagrams.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dataedo.com&#x2F;tutorials&#x2F;getting-started&#x2F;generating-database-documentation&quot;&gt;Dataedo generates static html sites &amp;amp;
pdfs&lt;&#x2F;a&gt;
as well, and is commercial and slicker than SchemaSpy&lt;&#x2F;li&gt;
&lt;li&gt;This &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;6fbd85431925b5724d2f&quot;&gt;gist for source-controlling ms_description
attributes&lt;&#x2F;a&gt; gives you
a two-way source-controllable &#x2F; editable list of your documentation in SQL
Server&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&quot;&gt;SQL Schema Explorer&lt;&#x2F;a&gt; generates dynamic html sites
making it easy to see what documentation there is and share it with the team.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-refactor-your-database&quot;&gt;[2] Refactor your database&lt;&#x2F;h2&gt;
&lt;p&gt;Migrations are a thing now. Use them. You refactor your code, why wouldn&#x27;t you
refactor your database? Stop leaving landmines for future people - misleading
names, bad structures etc. Use the redgate tools (ready-roll etc), use your
orm’s tools (EF migrations, active record migrations). Yes you have to deal
with data, but it’s the exception not the rule that it’s going to take hours to
run because of data volumes.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;products&#x2F;sql-development&#x2F;sql-change-automation&#x2F;&quot;&gt;Redgate&#x27;s SQL Change
Automation&lt;&#x2F;a&gt;
(formerly
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;blog&#x2F;working&#x2F;from-release-engineer-to-readyroll-founder-and-redgate-product-manager&quot;&gt;ReadyRoll&lt;&#x2F;a&gt;)
is an opinionated tool for creating and running database migrations, it even
generates Database Administrator (DBA) friendly pure-sql deployment packages.
Very impressive!&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;documentation.red-gate.com&#x2F;soc6&#x2F;common-tasks&#x2F;working-with-migration-scripts&quot;&gt;Redgate&#x27;s SQL Source Control supports
migrations&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve been using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;ef&#x2F;core&#x2F;managing-schemas&#x2F;migrations&#x2F;&quot;&gt;EF Core
migrations&lt;&#x2F;a&gt;
recently and they work well. There are equivalents for all the major
platforms.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;3-enforce-data-integrity&quot;&gt;[3] Enforce data integrity&lt;&#x2F;h2&gt;
&lt;p&gt;Does your app fall over if the data is bad? Databases have many powerful ways
of enforcing the rules your code relies on: nullability, foreign keys, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3schools.com&#x2F;SQL&#x2F;sql_check.asp&quot;&gt;check
constraints&lt;&#x2F;a&gt;, unique constraints.
Stop the bad data before it even gets in there. Now your database is enforcing
these rules your code doesn&#x27;t have to handle violations of them when reading
data because they&#x27;ll never happen&lt;&#x2F;p&gt;
&lt;h2 id=&quot;4-integration-testing&quot;&gt;[4] Integration testing&lt;&#x2F;h2&gt;
&lt;p&gt;You have an ORM. Great. You have unit tests. Great. But where the rubber hits
the road and your code sends SQL to a real database it breaks at runtime more
often than you’d like to admit because the generated sql didn&#x27;t jive with the
real database structure or data in some obscure fashion. Automate the
creation&#x2F;test&#x2F;destruction of your db and run full end to end integration tests.
I suggest automating from the layer below the UI to keep the tests fast. There
are many techniques for keeping the tests quick but still realistic: do end to
end smoke tests instead of individual pieces, use an in-memory database, use
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;3164291#file-create-snapshot-sql&quot;&gt;database
snapshots&lt;&#x2F;a&gt;
or the fancy &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;products&#x2F;dba&#x2F;sql-clone&#x2F;index&quot;&gt;sql-clone&lt;&#x2F;a&gt;
tool from Redgate to make creation &#x2F; rollback virtually instant. Can you pull
realistic (anonymised) data from production? Better still, now you’ll catch a
whole new class of bugs before they hit prod.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Here&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;simple-talk&#x2F;sql&#x2F;sql-tools&#x2F;continuous-integration-for-databases-using-red-gate-tools&#x2F;&quot;&gt;a guide from Redgate detailing one way to do continuous integration
testing with
databases&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;5-make-it-visible&quot;&gt;[5] Make it visible&lt;&#x2F;h2&gt;
&lt;p&gt;Are the only people that can see the database structures the coders and DBAs?
do the business owners, support people, Quality Assurance (QA) people find it a
mystery? You should be just as proud of your database as you are of your code,
by shining a light on this dark corner of your digital estate you can make it
as good as it should be, not an embarrassing backwater. By sharing the database
in an accessible form to the non-coders in your team you can help them be more
effective in their jobs.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The html generated by &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaspy.org&#x2F;&quot;&gt;SchemaSpy&lt;&#x2F;a&gt; can be shared on any
webserver to let your whole team see your schema structures&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&quot;&gt;SQL Schema Explorer&lt;&#x2F;a&gt; can be run on your network
or cloud hosting (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;timabell&#x2F;sdv&#x2F;&quot;&gt;schema explorer is
dockerized&lt;&#x2F;a&gt;!) to give your team easy
access to both the schema and data within the database.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Combine these tools with a continuous integration system and you have easy
access to the bleeding edge of your databases development.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;take-action-now&quot;&gt;Take action now!&lt;&#x2F;h2&gt;
&lt;p&gt;1.Make a start on at least one of these improvements today.
2.Share this article with your team - get everyone motivated to improve.
3.Share this article on social media - help spread the word that our
databases deserve better!&lt;&#x2F;p&gt;
&lt;p&gt;I hope this has inspired you to make an improvement in the often unloved
underbelly of your applications.&lt;&#x2F;p&gt;
&lt;p&gt;What do you think needs improving in the way we deal with databases? What
change did you make because of this? [Let me
know!](mailto:articles@timwise.co.uk?subject=making better databases)&lt;&#x2F;p&gt;
&lt;p&gt;Originally posted at
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;blog&#x2F;2018&#x2F;07&#x2F;10&#x2F;5-ways-to-make-your-database-better.html&quot;&gt;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;blog&#x2F;2018&#x2F;07&#x2F;10&#x2F;5-ways-to-make-your-database-better.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building on my own just for you and your database</title>
        <published>2018-06-26T00:22:08+01:00</published>
        <updated>2018-06-26T00:22:08+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/06/26/building-on-my-own-just-for-you-and-your-database/"/>
        <id>https://0x5.uk/2018/06/26/building-on-my-own-just-for-you-and-your-database/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/06/26/building-on-my-own-just-for-you-and-your-database/">&lt;p&gt;I&#x27;m not a big company, in fact it&#x27;s just me. I haven&#x27;t even paid anyone to do anything other than my accountants. I&#x27;m not against the idea of paying people, I just want to know I really need to first.&lt;&#x2F;p&gt;
&lt;p&gt;I see a gap in the tools available to database people; it&#x27;s bothered me for years (decades actually, I built an in-house variation of this in Classic ASP in the year 2000, yeah I&#x27;m getting old, thanks for pointing that out). I&#x27;m not the only one who recognises this gap, someone I showed schema explorer to said &quot;oh I knew someone who built something like that&quot;, this is great as it means I&#x27;m not delusional about there being a problem to solve. I find it hard to explain to people what this thing is, as there&#x27;s nothing quite like it out there. I&#x27;m still not really sure who it&#x27;s for (other than previous visions of myself). I want to put the time and effort in to make something that&#x27;s so valuable that people are happy to pay for it, and the money that brings will in turn allow my work to continue on the tool, bringing benefit to more people.&lt;&#x2F;p&gt;
&lt;p&gt;The core of the idea was navigating data across foreign keys, after talking to people it&#x27;s evolved into an all-round schema (and data) exploration tool (hence the addition of diagrams). My vision is to keep it a general-purpose database-centric tool, avoiding temptation to solve niche problems with it where it could take away from that well-formed-tool experience. I think I now have a piece of downloadable software that&#x27;s basically useful as it stands; but that there&#x27;s something (or many things) between where it&#x27;s at now, and people starting to get value from it by using it with their own databases. I don&#x27;t know yet what that is and I hope to find out through more conversations with database people. I certainly have plenty of ideas what it could be, but need to collect evidence rather than trying to fix non-problems on the off-chance. Especially with my even more limited time now that we&#x27;ve just had our second baby boy.&lt;&#x2F;p&gt;
&lt;p&gt;This is my current story, I hope you found it more interesting than the world cup ⚽.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;?utm_source=blog&amp;amp;utm_campaign=just4u&quot;&gt;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building a Windows 10 Development VM from scratch</title>
        <published>2018-04-01T20:10:54+01:00</published>
        <updated>2018-04-01T20:10:54+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/04/01/building-a-windows-10-development-vm-from-scratch/"/>
        <id>https://0x5.uk/2018/04/01/building-a-windows-10-development-vm-from-scratch/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/04/01/building-a-windows-10-development-vm-from-scratch/">&lt;p&gt;Rebuilding windows dev VM from scratch, reminds me why people put up an old build for so long. What a painful process!&lt;&#x2F;p&gt;
&lt;p&gt;I did wonder if I could get away with mssql on linux, and tried the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Microsoft&#x2F;mssql-docker&#x2F;issues&#x2F;284&quot;&gt;mssql docker image, which hosed my linux kernel&lt;&#x2F;a&gt;. That&#x27;s too many yaks for one morning.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;windows-install&quot;&gt;Windows Install&lt;&#x2F;h2&gt;
&lt;p&gt;Download a virtualbox image from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.microsoft.com&#x2F;en-us&#x2F;windows&#x2F;downloads&#x2F;virtual-machines&#x2F;&quot;&gt;https:&#x2F;&#x2F;developer.microsoft.com&#x2F;en-us&#x2F;windows&#x2F;downloads&#x2F;virtual-machines&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Attach the vm disk in virtualbox&lt;&#x2F;li&gt;
&lt;li&gt;Fire up and run updates&lt;&#x2F;li&gt;
&lt;li&gt;Install Rider via jetbrains toolbox&lt;&#x2F;li&gt;
&lt;li&gt;Shut down the VM&lt;&#x2F;li&gt;
&lt;li&gt;Take a virtualbox snapshot&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;backing-up-a-vm&quot;&gt;backing up a vm&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd VirtualBox\ VMs&#x2F;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;base=.  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src=win10-2018  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ls -lh $src  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;du -sh $src  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df -h .  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tar -cpC $base $src -P | pv -s $(du -sb $base&#x2F;$src | awk &amp;#39;{print $1}&amp;#39;) | lz4 &amp;gt;&amp;gt; $src.tar.lz4  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# 8.79GiB 0:00:43 [ 205MiB&#x2F;s] [=====================================================================&amp;gt; ] 99%  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;68d112d66623d9a4a3643c86a93debee#file-backup-sh-L21&quot;&gt;Gist for backing up with lz4&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;updates-updates-updates&quot;&gt;Updates! Updates! Updates!&lt;&#x2F;h2&gt;
&lt;p&gt;(as Ballmer once said?)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;poke &lt;strong&gt;windows updates&lt;&#x2F;strong&gt; until it finally decides there&#x27;s no more&lt;&#x2F;li&gt;
&lt;li&gt;reboot&lt;&#x2F;li&gt;
&lt;li&gt;poke windows updates until it finally decides there&#x27;s no more&lt;&#x2F;li&gt;
&lt;li&gt;reboot&lt;&#x2F;li&gt;
&lt;li&gt;poke windows updates until it finally decides there&#x27;s no more&lt;&#x2F;li&gt;
&lt;li&gt;reboot&lt;&#x2F;li&gt;
&lt;li&gt;Install &lt;strong&gt;virtualbox guest additions 5.1.34&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;reboot&lt;&#x2F;li&gt;
&lt;li&gt;shutdown&lt;&#x2F;li&gt;
&lt;li&gt;backup again&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;38944561440&#x2F;&quot;
target=&quot;_blank&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;4798&#x2F;38944561440_829d76ac80.jpg&quot;
style=&quot;max-height: 375px&quot; alt=&quot;Photo of a lit pool at night&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;the-snapshot-trials&quot;&gt;The Snapshot Trials&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.howtogeek.com&#x2F;150258&#x2F;how-to-save-time-by-using-snapshots-in-virtualbox&#x2F;&quot;&gt;VirtualBox has a neat snapshot feature&lt;&#x2F;a&gt;, so you can try out a whole tree of attempts at installs then squash them into the final image or roll them back.&lt;&#x2F;p&gt;
&lt;p&gt;Take a snapshot as a starting point for trying out the eternally broken boxstarter script.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;boxstarter&quot;&gt;Boxstarter&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;608fb680bfc920f372ac&quot;&gt;Boxstarter script, mostly working in win 10&lt;&#x2F;a&gt; now, but so much more to do on top that, including &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;tree&#x2F;windows&quot;&gt;windows branch of dotfiles&lt;&#x2F;a&gt; (always needs work). Read the script to see what it configures and installs.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll want to watch this vid at at least 2x playback speed:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;Hiz9_i67B3o&quot;&gt;https:&#x2F;&#x2F;youtu.be&#x2F;Hiz9_i67B3o&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;annoyances-setup-grab-reg-keys&quot;&gt;annoyances &#x2F; setup - grab reg keys&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;disable screensaver&lt;&#x2F;li&gt;
&lt;li&gt;hide task manager when minimized
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HKCU\Software\Microsoft\Windows\CurrentVersion\TaskManager\Preferences&lt;&#x2F;code&gt; - binary. sigh.settings &amp;gt; m&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;multitasking &amp;gt; snap (these have been rolled in to my boxstarter, but not tested there).
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\SnapAssist&lt;&#x2F;code&gt; - 0&lt;br &#x2F;&gt;
&lt;code&gt;HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\JointResize&lt;&#x2F;code&gt; - 0&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;all sounds off - generates 100s of reg keys, one for each event&lt;&#x2F;li&gt;
&lt;li&gt;mute&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;get-ready-for-dev&quot;&gt;get ready for dev&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;vs sign-in&lt;&#x2F;li&gt;
&lt;li&gt;extension updates
&lt;ul&gt;
&lt;li&gt;ssdt - external download popup, installs sql server 2016 localdb, takes forever, requires reboot&lt;&#x2F;li&gt;
&lt;li&gt;azure - leave for now, also external&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;jetbrains toolbox (sign in)
&lt;ul&gt;
&lt;li&gt;resharper&lt;&#x2F;li&gt;
&lt;li&gt;datagrip&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;vs-extensions&quot;&gt;VS Extensions&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;cinst editorconfig.vs vsvim ihateregions -y&lt;&#x2F;code&gt; - bit-rotten, didn&#x27;t work - I should contact the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chocolatey.org&#x2F;packages&#x2F;vsvim&quot;&gt;VsVim package maintainer&lt;&#x2F;a&gt;. Oh never mind that would be me then.&lt;&#x2F;p&gt;
&lt;p&gt;Extensions to install manually:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=JaredParMSFT.VsVim&quot;&gt;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=JaredParMSFT.VsVim&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=ZoltanKlinger.RelativeLineNumbers&quot;&gt;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=ZoltanKlinger.RelativeLineNumbers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=MadsKristensen.MarkdownEditor&quot;&gt;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=MadsKristensen.MarkdownEditor&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=VisualStudioProductTeam.VisualStudio2015ColorThemeEditor&quot;&gt;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=VisualStudioProductTeam.VisualStudio2015ColorThemeEditor&lt;&#x2F;a&gt; - to get solarized colours&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Something to look in to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chocolatey.org&#x2F;packages&#x2F;batch-install-vsix&quot;&gt;https:&#x2F;&#x2F;chocolatey.org&#x2F;packages&#x2F;batch-install-vsix&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;git-setup&quot;&gt;Git setup&lt;&#x2F;h2&gt;
&lt;p&gt;GitExtensions defaults to the program files putty, but the chocolatey one is newer and github deprecated the comms the old one uses.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;desktop&#x2F;desktop&#x2F;issues&#x2F;4105&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;desktop&#x2F;desktop&#x2F;issues&#x2F;4105&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.github.com&#x2F;2018-02-23-weak-cryptographic-standards-removed&#x2F;&quot;&gt;https:&#x2F;&#x2F;blog.github.com&#x2F;2018-02-23-weak-cryptographic-standards-removed&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Change all the putty paths in git extensions to start with &lt;code&gt;C:\ProgramData\chocolatey\bin\...&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;![Workspace 1_193]({{ site.baseurl }}&#x2F;assets&#x2F;workspace-1_193.png)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git-extensions-documentation.readthedocs.io&#x2F;en&#x2F;latest&#x2F;settings.html&quot;&gt;https:&#x2F;&#x2F;git-extensions-documentation.readthedocs.io&#x2F;en&#x2F;latest&#x2F;settings.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Settings that are specific to Git Extensions and apply globally will be stored in a file called &lt;code&gt;GitExtensions.settings&lt;&#x2F;code&gt; either in the user’s application data path or with the program. The location is dependant on the IsPortable setting in the &lt;code&gt;GitExtensions.exe.config&lt;&#x2F;code&gt; file that is with the program.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;i.e .&lt;code&gt;C:\Users\tim\AppData\Roaming\GitExtensions\GitExtensions&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-setup&quot;&gt;Key Setup&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Map a read-write folder to outside the VM to keep the putty keys in (this avoids regenerating the key if the VM is regenerated &#x2F; rolled back, and also means keys aren&#x27;t copied around with the VM image which makes them a bit easier to keep track of&lt;&#x2F;li&gt;
&lt;li&gt;git extensions &amp;gt; tools &amp;gt; putty &amp;gt; generate&lt;&#x2F;li&gt;
&lt;li&gt;set passphrase&lt;&#x2F;li&gt;
&lt;li&gt;save pub &amp;amp; private keys to shared folder&lt;&#x2F;li&gt;
&lt;li&gt;grab the public key from the generator, paste into github &amp;amp; bitbucket website account ssh configs&lt;&#x2F;li&gt;
&lt;li&gt;git extensions &amp;gt; tools &amp;gt; putty &amp;gt; start agent &amp;gt; add keys&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;dotmatrix&quot;&gt;DotMatrix&lt;&#x2F;h3&gt;
&lt;p&gt;Start git bash from git extensions, not the start menu (to get ssh set up right).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &#x2F;c&#x2F;repo &amp;amp;&amp;amp; mkdir tim &amp;amp;&amp;amp; cd tim  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git clone git@github.com:timabell&#x2F;dotmatrix.git  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd dotmatrix&#x2F;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git checkout windows  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bin&#x2F;install  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git st  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;vs-settings&quot;&gt;VS Settings&lt;&#x2F;h2&gt;
&lt;p&gt;![Workspace 1_194]({{ site.baseurl }}&#x2F;assets&#x2F;workspace-1_194.png)&lt;&#x2F;p&gt;
&lt;p&gt;VS &amp;gt; Options &amp;gt; Environment &amp;gt; Import&#x2F;export &amp;gt; set the path to the dotmatrix copy&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resharper-settings&quot;&gt;resharper settings&lt;&#x2F;h2&gt;
&lt;p&gt;![Workspace 1_195]({{ site.baseurl }}&#x2F;assets&#x2F;workspace-1_195.png)&lt;&#x2F;p&gt;
&lt;p&gt;VS &amp;gt; Resharper &amp;gt; manage options &amp;gt; right-click the gap &amp;gt; add layer &amp;gt; open settings file &amp;gt; select the one from the dotmatrix&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-settings&quot;&gt;More settings&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;VsVim settings&lt;&#x2F;li&gt;
&lt;li&gt;git config&lt;&#x2F;li&gt;
&lt;li&gt;email&#x2F;name&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;more-installs&quot;&gt;More installs&lt;&#x2F;h2&gt;
&lt;p&gt;redgate tools&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;dev bundle:
&lt;ul&gt;
&lt;li&gt;sql prompt - for VS too&lt;&#x2F;li&gt;
&lt;li&gt;compare&lt;&#x2F;li&gt;
&lt;li&gt;data compare&lt;&#x2F;li&gt;
&lt;li&gt;doc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;toolbelt bundle
&lt;ul&gt;
&lt;li&gt;readyroll&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;firefox&quot;&gt;firefox&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;sign-in&lt;&#x2F;li&gt;
&lt;li&gt;ghostery settings - disable annoying purple dot&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My Screencasting Setup</title>
        <published>2018-03-17T18:56:12+00:00</published>
        <updated>2018-03-17T18:56:12+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/03/17/screencasting-setup/"/>
        <id>https://0x5.uk/2018/03/17/screencasting-setup/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/03/17/screencasting-setup/">&lt;p&gt;I just made a video to demo schema explorer.&lt;&#x2F;p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;cqStb6M-Q90&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;I did this in one take with no post-production work. I figure practice will improve my selection and delivery of the content.&lt;&#x2F;p&gt;
&lt;p&gt;Behind the scenes I used the following:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hardware&quot;&gt;Hardware&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Dell XPS 13 - (9350 model), using the built-in webcam (up-nose view, camera in bottom left of lid for some reason), good enough for tiny pic in corner.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;amzn.to&#x2F;2FGWsQQ&quot;&gt;Snowball usb mic&lt;&#x2F;a&gt; (great sound quality, no worrying about analogue stuff), sat on a folded towel on my desk to deaden vibrations through the mini-tripod. The snowball has 3 settings on a switch at the back, had it on 3 - omni directional, I tested &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;-3rbPaJgTWA?t=1m59s&quot;&gt;all three modes&lt;&#x2F;a&gt; beforehand.&lt;&#x2F;li&gt;
&lt;li&gt;Supplied stand didn&#x27;t actually fit properly, so bought an &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;amzn.to&#x2F;2pkYEmg&quot;&gt;ammoon mini tripod&lt;&#x2F;a&gt; instead which is lovely (importantly it has the right screw thread for the mic).&lt;&#x2F;li&gt;
&lt;li&gt;A quiet room after everyone is in bed to avoid &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;Mh4f9AYRCZY&quot;&gt;interruptions&lt;&#x2F;a&gt;, and did the recording between rain storms!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;software&quot;&gt;Software&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linuxmint.com&#x2F;&quot;&gt;Linux Mint&lt;&#x2F;a&gt; 18.3 Cinnamon&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;linuxecke.volkoh.de&#x2F;vokoscreen&#x2F;vokoscreen.html&quot;&gt;Vokoscreen&lt;&#x2F;a&gt; 2.4.0 - this handles screen recording &amp;amp; the picture-in-picture from the webcam&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I recorded the entire screen at 1920x1080 (seeing as even phones are HD now). and uploaded it to youtube. (drag-n-drop, simplez!)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;settings&quot;&gt;Settings&lt;&#x2F;h2&gt;
&lt;p&gt;Control panel &amp;gt; sound &amp;gt; input &amp;gt; snowball &amp;gt; about 130% input volume&lt;&#x2F;p&gt;
&lt;p&gt;![Sound_183.png]({{ site.baseurl }}&#x2F;assets&#x2F;sound_183.png)&lt;&#x2F;p&gt;
&lt;p&gt;fullscreen capture, display 2, 1920x1080&lt;&#x2F;p&gt;
&lt;p&gt;![Screenshot from 2018-03-17 18-27-39.png]({{ site.baseurl }}&#x2F;assets&#x2F;screenshot-from-2018-03-17-18-27-39.png)&lt;&#x2F;p&gt;
&lt;p&gt;pulse &#x2F; blue-snowball selected&lt;&#x2F;p&gt;
&lt;p&gt;![Screenshot from 2018-03-17 18-27-55.png]({{ site.baseurl }}&#x2F;assets&#x2F;screenshot-from-2018-03-17-18-27-55.png)&lt;&#x2F;p&gt;
&lt;p&gt;mpeg4, mp3, avi, 25fps&lt;&#x2F;p&gt;
&lt;p&gt;![vokoscreen 2.4.0_180]({{ site.baseurl }}&#x2F;assets&#x2F;vokoscreen-2-4-0_180.png)&lt;&#x2F;p&gt;
&lt;p&gt;Default config apart from save path &quot;videopath&quot;&lt;&#x2F;p&gt;
&lt;p&gt;![vokoscreen 2.4.0_181.png]({{ site.baseurl }}&#x2F;assets&#x2F;vokoscreen-2-4-0_181.png)&lt;&#x2F;p&gt;
&lt;p&gt;Webcam switched on&lt;&#x2F;p&gt;
&lt;p&gt;![vokoscreen 2.4.0_182.png]({{ site.baseurl }}&#x2F;assets&#x2F;vokoscreen-2-4-0_182.png)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-attempts&quot;&gt;Other attempts&lt;&#x2F;h2&gt;
&lt;p&gt;I spent ages finding the right software and doing test takes to get sound levels etc right.&lt;&#x2F;p&gt;
&lt;p&gt;I started off with Kazaam for recording and mplayer for the webcam onscreen video.&lt;&#x2F;p&gt;
&lt;p&gt;I got mplayer to show a borderless webcam video picture on screen that I could then use with any screen recorder, but had problems with dual screen behaviour so even though I could zoom in better I gave up on that once I&#x27;d discovered vokoscreen.&lt;&#x2F;p&gt;
&lt;p&gt;You might also want to look at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wistia.com&#x2F;soapbox&quot;&gt;https:&#x2F;&#x2F;wistia.com&#x2F;soapbox&lt;&#x2F;a&gt; which I hear is very good.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Regression Tests for ASP.NET &#x2F; SQL Projects</title>
        <published>2018-03-13T15:25:46+00:00</published>
        <updated>2018-03-13T15:25:46+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/03/13/regression-tests-for-asp-net-sql-projects/"/>
        <id>https://0x5.uk/2018/03/13/regression-tests-for-asp-net-sql-projects/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/03/13/regression-tests-for-asp-net-sql-projects/">&lt;p&gt;I&#x27;ve had the opportunity to attempt many variations of regression testing on many projects.&lt;&#x2F;p&gt;
&lt;p&gt;Many of the systems I&#x27;ve worked on have at least some level of workflow, meaning a user has to move through many steps as the system progresses something towards a final state.&lt;&#x2F;p&gt;
&lt;p&gt;As systems become more and more complex it becomes harder to not accidentally break an area of the system you weren&#x27;t currently looking at and didn&#x27;t re-test manually before shipping. Hence the search for the holy grail of the perfect regression test suite. It turns out that none of the approaches available (unit tests, UI drivers etc.) provide a single solution to the problem, and instead we have to use all these approaches in balance to give reasonable protection against regressions.&lt;&#x2F;p&gt;
&lt;p&gt;Here I lay out my current thinking on the best way to use testing to avoid regressions in a standard ASP.NET MVC + SQL Server project. I would like to introduce to you the idea of &quot;business logic tests&quot; which are an integration test suite starting below the UI layer, continuing through to a real database. I believe this gives an ideal balance of the trade-offs we have to make when choosing how to design out full regression test suite for a system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;system-layers&quot;&gt;System layers&lt;&#x2F;h2&gt;
&lt;p&gt;The layers of such a system are ideally something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Database (largely just used for CRUD storage)&lt;&#x2F;li&gt;
&lt;li&gt;ORM - EF or similar library&lt;&#x2F;li&gt;
&lt;li&gt;Model - C# classes&lt;&#x2F;li&gt;
&lt;li&gt;Business logic layer - pure C# - (often missing in real projects, with business logic scattered across the other layers)&lt;&#x2F;li&gt;
&lt;li&gt;UI layer - Controller classes written in C#, views in razor .cshtml files, html, css, javascript etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;recommended-test-layers&quot;&gt;Recommended test layers&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unit tests&lt;&#x2F;strong&gt; - test small pieces of C# code&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Business logic tests&lt;&#x2F;strong&gt; - test the business logic layer down through to a real SQL Server database.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;UI Smoke tests&lt;&#x2F;strong&gt; - non-exhaustive test of a few common user journey&#x27;s through, running against a real database, driven with Selenium Web Driver or similar.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There should be only a few smoke tests, there should be many business logic tests covering all business functions that need to stay working, and finally developer discretion on the amount of unit testing to apply at the lowest level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-do-the-business-logic-tests-look-like&quot;&gt;What do the business logic tests look like?&lt;&#x2F;h2&gt;
&lt;p&gt;These could be pure code driven through something like NUnit, or they could be in business language through a BDD tool like specflow.&lt;&#x2F;p&gt;
&lt;p&gt;They depend on the business logic project but nothing above that (UI). They inject a real database connection as a dependency through whatever injection method you use.&lt;&#x2F;p&gt;
&lt;p&gt;These tests should make sense to the product owner &#x2F; client.&lt;&#x2F;p&gt;
&lt;p&gt;This is the layer with the broadest coverage of all of the three styles in play. Every business use-case, workflow &amp;amp; variation should be covered here. This is the suite that will alert you if any business or workflow rule is no longer being applied as designed, or if an obscure step of an obscure branch of your workflow has stopped working (perhaps due to an odd interaction with a database constraint).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;handling-the-database&quot;&gt;Handling the database&lt;&#x2F;h2&gt;
&lt;p&gt;SQL Sever has a very useful snapshot feature that means you can very rapidly roll back to a clean state after each test run. (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;3164291#file-create-snapshot-sql&quot;&gt;Snapshot setup script&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;For each business logic test run:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;3164291#file-reset-to-snapshot-sql&quot;&gt;Reset to the production snapshot&lt;&#x2F;a&gt; (or production equivalent build if you can&#x27;t actually grab a production backup)&lt;&#x2F;li&gt;
&lt;li&gt;Run outstanding migrations for this version of the code (you are using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;documentation.red-gate.com&#x2F;rr1&#x2F;deployment&#x2F;octopus-deploy&quot;&gt;Octopus + ReadyRoll&lt;&#x2F;a&gt; aren&#x27;t you?)&lt;&#x2F;li&gt;
&lt;li&gt;Run the Business logic tests.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;why-not-test-all-the-business-functions-through-the-ui&quot;&gt;Why not test all the business functions through the UI?&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;UI tests are prone to reliability problems, you can end up with 98% pass rates being normal, so then you don&#x27;t notice when a critical test fails.&lt;&#x2F;li&gt;
&lt;li&gt;UI tests are slow - this can add an extra overhead to developer productivity.&lt;&#x2F;li&gt;
&lt;li&gt;UI tests cause unwarranted resistance to change - once you have UI tests the UI becomes extremely hard to change, particularly for sweeping site-wide redesigns without spending a prohibitively long time fixing up the test suite. And you aren&#x27;t fixing the test suite because you changed the logic, this is busywork.&lt;&#x2F;li&gt;
&lt;li&gt;The UI isn&#x27;t sufficiently fragile to warrant this level of testing - when you are working on a page you are unlikely to break unrelated pages without realising.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I have seen first-hand a team of excellent programmers get bogged down in problems with a full regression test suite driven entirely from the UI.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-not-test-all-layers-separately&quot;&gt;Why not test all layers separately?&lt;&#x2F;h2&gt;
&lt;p&gt;In my experience a major point of fragility when a system is modified is the interaction between the code and the database. As such it&#x27;s important that this fault-line is covered thoroughly by all regression tests that focus on business functions that need to remain functional.&lt;&#x2F;p&gt;
&lt;p&gt;A test suite that isolates the business logic layer from the database layer provides very little value, usually just fulfilling a &quot;&lt;em&gt;though shalt unit test all classes&lt;&#x2F;em&gt;&quot; declaration.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-get-there&quot;&gt;How to get there&lt;&#x2F;h2&gt;
&lt;p&gt;If you don&#x27;t have a solid business logic layer then you will need to refactor your way to that goal. This has other benefits for reliability beyond the ability to test. Clean code with an obvious layer for all the business logic is easier to modify and keep defect-free.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-free-test-data&quot;&gt;Bonus - free test data&lt;&#x2F;h2&gt;
&lt;p&gt;The tests that you write to drive the business logic layer will be generating real data in a real copy of your database as it runs through the many steps in a workflow. You can use this test driver to generate useful test data for every step in a workflow, e.g. if a workflow had four steps you could do the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Test account A - drive business logic to step 1&lt;&#x2F;li&gt;
&lt;li&gt;Test account B - drive business logic to step 2&lt;&#x2F;li&gt;
&lt;li&gt;Test account C - drive business logic to step 3&lt;&#x2F;li&gt;
&lt;li&gt;Test account D - drive business logic to step 4&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This is extremely quick to run, and now you have an account in every state of your workflow. This is useful for easily:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Demoing your system from any starting point with multiple test accounts.&lt;&#x2F;li&gt;
&lt;li&gt;Having the data in the right state to do development work on state 4 without having to manually set it up.&lt;&#x2F;li&gt;
&lt;li&gt;Give your manual testers all the test accounts they need in many interesting states.&lt;&#x2F;li&gt;
&lt;li&gt;Testing out your reporting systems and anything else that consumes data from your database.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Having realised you can do this, why would you ever do it manually again?&lt;&#x2F;p&gt;
&lt;p&gt;Because the code that generates this data is a core part of your regression test suite it will be maintained as part of normal development activities and so you&#x27;ll never again have to deal with test data that no longer works with your latest version of the system.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;If you want me to help you get to this ideal then drop me a line - &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;tim@timwise.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Developers, Love Your SQL Database</title>
        <published>2018-03-12T19:30:15+00:00</published>
        <updated>2018-03-12T19:30:15+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/03/12/developers-love-your-sql-database/"/>
        <id>https://0x5.uk/2018/03/12/developers-love-your-sql-database/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/03/12/developers-love-your-sql-database/">&lt;p&gt;Developers, don&#x27;t be afraid of your SQL database, don&#x27;t try and ignore it, try and make it the best it can be just like you do for your code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-wrong-today&quot;&gt;What&#x27;s wrong today&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve noticed that a lot of projects that have SQL databases don&#x27;t apply the high standards that they have for their codebase (refactoring, clean code, documentation, etc.) to the SQL part of their projects.&lt;&#x2F;p&gt;
&lt;p&gt;Dealing with relational databases is harder than code:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The tooling that I see teams using to manage their relational databases is crap.&lt;&#x2F;li&gt;
&lt;li&gt;Having to handle live data makes refactoring harder (but not impossible).&lt;&#x2F;li&gt;
&lt;li&gt;SQL is a language from the stone-age of software.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But that&#x27;s no excuse for not doing the best you can for the problem at hand.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;there-are-answers-to-these-problems&quot;&gt;There are answers to these problems&lt;&#x2F;h2&gt;
&lt;p&gt;Some of the answer is just accepting that it&#x27;s harder and learning to be effective. For example I find &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=JaredParMSFT.VsVim&quot;&gt;VsVim&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;products&#x2F;sql-development&#x2F;sql-prompt&#x2F;&quot;&gt;SQL Prompt&lt;&#x2F;a&gt; to be great for editing SQL.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;&quot;&gt;Redgate&lt;&#x2F;a&gt; have a great suite of tools for managing the full lifecycle of a database. Use them. I particularly like the way &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.red-gate.com&#x2F;products&#x2F;sql-development&#x2F;readyroll&#x2F;&quot;&gt;ReadyRoll&lt;&#x2F;a&gt; handles migrations. RedGate tooling has excellent &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;octopus.com&#x2F;blog&#x2F;database-deployments-with-octopus-and-redgate-sql-release&quot;&gt;integrations with Octopus deploy&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So if you&#x27;re in the situation I&#x27;ve seen with a database you virtually can&#x27;t change and nothing but a visual studio database project in place that may or may not be in place with production, then try the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Throw away the database project.&lt;&#x2F;li&gt;
&lt;li&gt;Set up ReadyRoll in your visual studio project.&lt;&#x2F;li&gt;
&lt;li&gt;Grab your production schema, and use that as a base in your ReadyRoll migrations. (It has a neat feature for a first &quot;migration&quot; that will only be run on a new database build, so it can build you a dev database from scratch, but it won&#x27;t attempt to recreate production).&lt;&#x2F;li&gt;
&lt;li&gt;Configure ready-roll to use branch folders.&lt;&#x2F;li&gt;
&lt;li&gt;Start creating migrations in feature branches.&lt;&#x2F;li&gt;
&lt;li&gt;Set up CI &#x2F; test &#x2F; QA &#x2F; pre-prod environments (or whatever you call them in your team) to drop and rebuild the database with every build. You can make this faster by using SQL Server snapshots.&lt;&#x2F;li&gt;
&lt;li&gt;Each environment then runs the database migrations that match the version of the codebase that was released to that environment.&lt;&#x2F;li&gt;
&lt;li&gt;Push changes up through the environments until those migration scripts have been run so many times you are no longer afraid to run them.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Now you can refactor your database with confidence just like you can with the code, and it can stop being something you pretend isn&#x27;t there and start being something you are proud to show off.&lt;&#x2F;p&gt;
&lt;p&gt;There are many potential complications, such as re-indexing tables with lots of data in production, but these are not things that an intelligent well-functioning DevOps team can&#x27;t handle well once the basic process is in place.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;6fbd85431925b5724d2f&quot;&gt;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;6fbd85431925b5724d2f&lt;&#x2F;a&gt; - source control your schema documentation (ms_description attributes)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dba.stackexchange.com&#x2F;q&#x2F;515&#x2F;33693&quot;&gt;https:&#x2F;&#x2F;dba.stackexchange.com&#x2F;questions&#x2F;515&#x2F;how-do-you-document-your-databases&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;If you like this, you might appreciate the tool I&#x27;m working on to shed further light on the dark corners of your SQL database, check it out at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;?utm_source=blog.timwise&amp;amp;utm_medium=web&amp;amp;utm_campaign=love-db&quot;&gt;http:&#x2F;&#x2F;schemaexplorer.io&#x2F;&lt;&#x2F;a&gt; and be sure to sign up to the waiting list.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My approach to my work</title>
        <published>2018-03-10T00:00:00+00:00</published>
        <updated>2018-03-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/03/10/my-approach-to-my-work/"/>
        <id>https://0x5.uk/2018/03/10/my-approach-to-my-work/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/03/10/my-approach-to-my-work/">&lt;p&gt;I&#x27;ve realised that something that sets me apart from other developers with similar buzzwords on their CV is the way I think about things and the principles I think are important. But I&#x27;ve never put them on my CV or tried to express them in writing before. I&#x27;m not perfect and may fall short sometimes but these are the perfection I strive for.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tell-the-truth-even-if-it-s-hard&quot;&gt;Tell the Truth, Even if it&#x27;s Hard&lt;&#x2F;h2&gt;
&lt;p&gt;I don&#x27;t believe in selling good news only and robbing people I work with of the negative information that could be critical to making good decisions. E.g is this project going as well as expected?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;No. - opportunity to take corrective action by those with the authority to make sweeping changes&lt;&#x2F;li&gt;
&lt;li&gt;Yes (a lie) - temporary happiness followed by reality catching up and being in an even worse situation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Great episode on the matter: The Startup Chat with Steli and Hiten: 288: Startup Lies &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thestartupchat.com&#x2F;ep288&#x2F;&quot;&gt;https:&#x2F;&#x2F;thestartupchat.com&#x2F;ep288&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;strong-opinions-weakly-held&quot;&gt;Strong Opinions, Weakly Held&lt;&#x2F;h2&gt;
&lt;p&gt;Which means I have strong opinions about what the right thing to do is based on my experience and the information available at the time, but that if I am presented with new information then I am open minded to changing my opinion. I first heard about this while on contract with GDS, an organisation with an amazing culture for doing the right thing and getting things done. Here&#x27;s a small example: I spent many many years preferring the C# style of skipping curly-braces for one-line &lt;code&gt;if&lt;&#x2F;code&gt; blocks, based on the understanding that the less boiler-plate there is the easier it is to read the code. And then a fellow dev argued that it was better to always include them for the sake of reliability. I was initially unconvinced, but I always appreciate hearing a contrarian view and I proceeded to research extensively the pros and cons. Given the constant problems with indentation (spaces&#x2F;tabs) in many projects that can make an if block look like something it isn&#x27;t if you aren&#x27;t paying close attention, and the automatic merge present in many source control systems, I was persuaded to change my view and &lt;a href=&quot;&#x2F;2018&#x2F;08&#x2F;28&#x2F;always-add-braces&#x2F;&quot;&gt;will now argue just as strongly for the new stance&lt;&#x2F;a&gt;. For an excellent example of a serious security problem that might have been avoided by always having braces, read the &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nakedsecurity.sophos.com&#x2F;2014&#x2F;02&#x2F;24&#x2F;anatomy-of-a-goto-fail-apples-ssl-bug-explained-plus-an-unofficial-patch&#x2F;&quot;&gt;explanation of Apple&#x27;s goto fail SSL bug&lt;&#x2F;a&gt;&quot;, a coding error which has the hallmarks of an unfortunate choice made by a merge algorithm.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;communicate-to-be-understood&quot;&gt;Communicate to be understood&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve had feedback that my communication with stakeholders is good, and that I can explain complex technical issues clear to less technical people. I think it&#x27;s important that those around a project such as senior stakeholders, users, related support people and collaborating suppliers all have the best understanding of the state of a project and any issues. Without clear information in a language they are comfortable with then they are left unable to help the project succeed. I think it&#x27;s important not to dumb things down as that results in losing important details, but instead take the time to help people understand the details they need to and why they might be important. As the technical experts it&#x27;s up to us to make sure that others have the knowledge they need to do their jobs the best they can.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;help-others&quot;&gt;Help others&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve also had feedback that one of my strengths is mentoring and sharing knowledge with other team members, technical and non-technical. It&#x27;s certainly true that I do love helping others improve their own skills and knowledge where I can, and sharing what I&#x27;ve learnt over the years (ahem, decades). This is partly just because I love what we can do with technology and want everyone to gain the maximum benefit from it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;continuous-personal-improvement&quot;&gt;Continuous Personal Improvement&lt;&#x2F;h2&gt;
&lt;p&gt;I read the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;amzn.to&#x2F;2FBTBJc&quot;&gt;7 habits of highly effective people&lt;&#x2F;a&gt; by Covey many years ago, and it is truly life changing because it changes your thinking from fatalistic &quot;this is how I am&quot; to &quot;I can become a better person&quot;, and gives you some great mental tools for doing so. I have practised this consciously ever since. I particularly liked the quote I heard recently &quot;&lt;em&gt;What would you tell your younger self? Nothing, they wouldn&#x27;t be able to understand what I know now, I&#x27;m a different person&lt;&#x2F;em&gt;&quot; (or words to that effect).&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;40044785284&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;4786&#x2F;40044785284_22f105fa2d.jpg&quot; alt=&quot;IMG_20171229_114959&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;follow-programming-best-practice&quot;&gt;Follow Programming Best Practice&lt;&#x2F;h2&gt;
&lt;p&gt;Our industry has learnt a lot over the last 50-odd years about what&#x27;s effective. A lot of best practice has been captured in books, internet articles, and importantly libraries and frameworks. Strive to stand on the shoulders of the giants.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;elegance-practicality-and-definitely-no-dogmatism&quot;&gt;Elegance, Practicality, and Definitely No Dogmatism&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s easy to get drawn in to the latest hip thing and apply it to everything you do no matter how inappropriate. Every situation should be assessed for the trade-offs that will be appropriate. One of the challenges of defining best practice in programming is the variety of problems it is used to solve. Should we use the same rules to produce a life-support system with no ability to push updates out as we should for a startup SaaS with no users yet? Clearly not, yet you&#x27;d wonder given some of the views presented; usually of the form &quot;&lt;em&gt;This worked on my project so you MUST now use it in ALL YOUR CODE!!!&lt;&#x2F;em&gt;&quot; (This is the way Test Driven Development was introduced to me, and eventually I realised this is probably because it came largely from the dynamic language Ruby that lacks all the compile time checks I&#x27;m used to in C#, and as such complex systems have more failure modes as the codebase changes over time, resulting in a greater value of extensive unit testing.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;emergent-architecture&quot;&gt;Emergent Architecture&lt;&#x2F;h2&gt;
&lt;p&gt;Planning is good, don&#x27;t get me wrong. But don&#x27;t restrict your options until you need to. The idea of emergent architecture is do the simplest thing that will work (following the You Aren&#x27;t Going to Need It principle, aka YAGNI), and then as it becomes apparent you have a need for a particular abstraction or pattern that&#x27;s when you apply it, through the magic of refactoring. I&#x27;ve seen too many projects that have been made many times more expensive than necessary because at an early point in the project a developer who had previously been burned by a lack of some structure or other made damn sure it was in their next project, regardless of whether it was actually necessary for the problem at hand. Another classic is learning of a pattern and applying it without it actually being needed. A common example of this I&#x27;ve seen is adding a &quot;repository&quot; layer to a codebase on top of entity framework, not realizing that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;a&#x2F;220126&#x2F;48240&quot;&gt;entity framework already implements the repository pattern&lt;&#x2F;a&gt; (along with the unit-of-work pattern). I spent years learning about the various approaches to the architecture of software projects. Initially I thought I need to apply all of this best-practice to every project, but was troubled by how long that would take and found myself guiltily doing just enough to get the job done.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;technical-debt-and-refactoring&quot;&gt;Technical Debt and Refactoring&lt;&#x2F;h2&gt;
&lt;p&gt;Refactor problematic things as they cause you problems. Simple. I really can&#x27;t say it better than this: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ronjeffries.com&#x2F;xprog&#x2F;articles&#x2F;refactoring-not-on-the-backlog&#x2F;&quot;&gt;https:&#x2F;&#x2F;ronjeffries.com&#x2F;xprog&#x2F;articles&#x2F;refactoring-not-on-the-backlog&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-agile-thing&quot;&gt;The Agile Thing&lt;&#x2F;h2&gt;
&lt;p&gt;I learned about eXtreme Programming (XP), scrum &amp;amp; kanban (I&#x27;ve actually worked in a real factory that used kanban). I&#x27;ve worked in many teams at various levels of competence on the whole &quot;agile&quot; thing and to me it seems to be down to good people making the best use of the available ideas for the problems at hand. Got no process at all, or something horribly like a waterfall? Add some elements of scrum and get better. Nailed scrum and feeling constrained? Do some more reading up, decide where to go next. I don&#x27;t pretend to be an expert in &quot;agile&quot;, but I love working in effective teams making use of the best methods available, and I love helping teams improve where I can. I&#x27;m not particularly interested in climbing the management-track ladder, I&#x27;m happy to work as a member of great teams. You can&#x27;t do it all, and I don&#x27;t want to get too far from my coding skills.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;&#x2F;h2&gt;
&lt;p&gt;These are things I&#x27;ve read that have guided my thinking towards where it is today (along with my personal experiences).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;books&quot;&gt;Books&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;amzn.to&#x2F;2IoECzU&quot;&gt;Mythical Man Month&lt;&#x2F;a&gt; - a timeless classic&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;refactoring-and-technical-debt&quot;&gt;Refactoring and technical debt&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ronjeffries.com&#x2F;xprog&#x2F;articles&#x2F;refactoring-not-on-the-backlog&#x2F;&quot;&gt;https:&#x2F;&#x2F;ronjeffries.com&#x2F;xprog&#x2F;articles&#x2F;refactoring-not-on-the-backlog&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;laughingmeme.org&#x2F;2016&#x2F;01&#x2F;10&#x2F;towards-an-understanding-of-technical-debt&#x2F;&quot;&gt;http:&#x2F;&#x2F;laughingmeme.org&#x2F;2016&#x2F;01&#x2F;10&#x2F;towards-an-understanding-of-technical-debt&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;compassion&quot;&gt;Compassion&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jml.io&#x2F;pages&#x2F;your-code-sucks-and-i-hate-you.html&quot;&gt;https:&#x2F;&#x2F;jml.io&#x2F;pages&#x2F;your-code-sucks-and-i-hate-you.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;technical-details&quot;&gt;Technical details&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;endoflineblog.com&#x2F;gitflow-considered-harmful&#x2F;&quot;&gt;http:&#x2F;&#x2F;endoflineblog.com&#x2F;gitflow-considered-harmful&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;new-thinking&quot;&gt;New thinking&lt;&#x2F;h3&gt;
&lt;p&gt;Things that I&#x27;ve recently come across that I wish to share &#x2F; promote&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;simpleprogrammer.com&#x2F;agile-is-dead-code-review&#x2F;&quot;&gt;https:&#x2F;&#x2F;simpleprogrammer.com&#x2F;agile-is-dead-code-review&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;get-in-touch&quot;&gt;Get In Touch&lt;&#x2F;h2&gt;
&lt;p&gt;If you need someone who you can rely on to bring more than just a list of keywords to your project then get in touch: &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;tim@timwise.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Contract developer to entrepreneur - resources</title>
        <published>2018-02-16T22:31:38+00:00</published>
        <updated>2018-02-16T22:31:38+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2018/02/16/contract-developer-to-entrepreneur-resources/"/>
        <id>https://0x5.uk/2018/02/16/contract-developer-to-entrepreneur-resources/</id>
        
        <content type="html" xml:base="https://0x5.uk/2018/02/16/contract-developer-to-entrepreneur-resources/">&lt;p&gt;I&#x27;m not there yet so I&#x27;m no authority, but here&#x27;s some things that I think are fab resources on my journey. They are helping me change my thought patterns and behaviour to make success more likely.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;books-roughly-in-order-of-my-journey&quot;&gt;Books (roughly in order of my journey)&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;81948.The_E_Myth_Revisited?ac=1&amp;amp;from_search=true&quot;&gt;The e-myth (revisited)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Better-Mousetrap-business-invention&#x2F;dp&#x2F;0951385607&quot;&gt;A better mousetrap - the business of invention&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;22835624-the-art-of-the-start-2-0&quot;&gt;The Art of the Start&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;23353984-key-person-of-influence-revised-edition?from_search=true&quot;&gt;Key person of influence&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;15789193-so-good-they-can-t-ignore-you&quot;&gt;So good they can&#x27;t ignore you&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;More books over on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;user&#x2F;show&#x2F;50628592-tim-abell&quot;&gt;my goodreads profile&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Some &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cocoon.life&#x2F;blog&#x2F;6-must-read-business-books&#x2F;&quot;&gt;more suggestions on the cocoon blog&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inspiration&quot;&gt;Inspiration&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.softwarebyrob.com&#x2F;2015&#x2F;03&#x2F;26&#x2F;the-stairstep-approach-to-bootstrapping&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.softwarebyrob.com&#x2F;2015&#x2F;03&#x2F;26&#x2F;the-stairstep-approach-to-bootstrapping&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;podcasts&quot;&gt;Podcasts&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Bootstrapped Web [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;bootstrappedweb.com&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;bootstrappedweb.com&#x2F;feed&#x2F;podcast&#x2F;&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;Marketing for Developers [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;devmarketing.xyz&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;el2.convertkit-mail.com&#x2F;c&#x2F;68udv830zfouw6v3n&#x2F;opfkhq&#x2F;aHR0cDovL3NpbXBsZWNhc3QuY29tL3BvZGNhc3RzLzE0NDYvcnNz&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;Noah Kagan Presents [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;okdork.com&#x2F;podcast&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;noahkagan.libsyn.com&#x2F;rss&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;Rogue Startups Podcast [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;roguestartups.com&#x2F;&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;roguestartups.com&#x2F;feed&#x2F;podcast&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;Startup Chat [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wpcurve.com&#x2F;category&#x2F;podcast&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;feeds.feedburner.com&#x2F;StartupChat&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;Startups For the Rest of Us [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.startupsfortherestofus.com&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.startupsfortherestofus.com&#x2F;feed&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;The Art of Product [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;artofproductpodcast.com&#x2F;&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;artofproductpodcast.com&#x2F;rss&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;The Indie Hackers Podcast: How Developers are Bootstrapping, Marketing, and Growing Their Online Businesses [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;indiehackers.com&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;feeds.backtracks.fm&#x2F;feeds&#x2F;indiehackers&#x2F;indiehackers&#x2F;feed.xml&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;The Startup Chat with Steli and Hiten [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thestartupchat.com&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thestartupchat.com&#x2F;feed&#x2F;podcast&#x2F;&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;The Tim Ferriss Show [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;art19.com&#x2F;shows&#x2F;tim-ferriss-show&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rss.art19.com&#x2F;tim-ferriss-show&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;Tropical MBA - Entrepreneurship, Travel, and Lifestyle [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.tropicalmba.com&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.tropicalmba.com&#x2F;feed&#x2F;podcast&#x2F;&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;li&gt;Zen Founder: Startup. Family. Life. [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zenfounder.com&quot;&gt;Website&lt;&#x2F;a&gt;] [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zenfounder.com&#x2F;feed&#x2F;podcast&#x2F;&quot;&gt;Feed&lt;&#x2F;a&gt;]&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.dropbox.com&#x2F;sh&#x2F;hamw2d24w4vk062&#x2F;AACyN1-AfzYpGIoNMl4d9xjOa?dl=0&quot;&gt;My feed list&lt;&#x2F;a&gt; exported from AntennaPod&lt;&#x2F;p&gt;
&lt;h2 id=&quot;products&quot;&gt;Products&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pages.github.com&#x2F;&quot;&gt;github-pages&lt;&#x2F;a&gt; - for hosting landing pages etc&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;logojoy.com&quot;&gt;logojoy.com&lt;&#x2F;a&gt; - $65 automated and very good logo generator&lt;&#x2F;li&gt;
&lt;li&gt;godaddy - for domains&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;education&quot;&gt;Education&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;tinymarketingwins.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;tinymarketingwins.com&#x2F;&lt;&#x2F;a&gt; - learn marketing even before you have anything to sell&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;designacademy.io&#x2F;&quot;&gt;https:&#x2F;&#x2F;designacademy.io&#x2F;&lt;&#x2F;a&gt; - design for developers&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ditchinghourly.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.ditchinghourly.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;startupclass.samaltman.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;startupclass.samaltman.com&#x2F;&lt;&#x2F;a&gt; - also on youtube &amp;amp; as a podcast:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=CBYhVcO4WgI&amp;amp;list=PL5q_lef6zVkaTY_cT1k7qFNF2TidHCe-1&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=CBYhVcO4WgI&amp;amp;list=PL5q_lef6zVkaTY_cT1k7qFNF2TidHCe-1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;community&quot;&gt;Community&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.indiehackers.com&#x2F;&quot;&gt;Indie Hackers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;people&quot;&gt;People&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;okdork.com&#x2F;&quot;&gt;Noah Kagan&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timferriss.com&#x2F;&quot;&gt;Tim Ferris&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Courtland (Indie Hackers)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;laurium&quot;&gt;Laura Elizabeth&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Jonathan Stark (Ditching Hourly)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Down with SDV! long live SSE!</title>
        <published>2017-12-29T02:59:54+00:00</published>
        <updated>2017-12-29T02:59:54+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/12/29/down-with-sdv-long-live-sse/"/>
        <id>https://0x5.uk/2017/12/29/down-with-sdv-long-live-sse/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/12/29/down-with-sdv-long-live-sse/">&lt;p&gt;I can&#x27;t keep up with myself on this startup journey, but I hope I can give you a peek into my journey as I go. I&#x27;ve had couple of revelations recently which I&#x27;ll explain here:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;discovering-your-needs&quot;&gt;Discovering your needs&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve managed to talk to more people about what problems I could solve and have started to learn more about what value this tool might provide (solution-to-problem instead of the usual solution-looking-for-problem).&lt;&#x2F;p&gt;
&lt;p&gt;I had originally thought of this tool as something for viewing data, but I&#x27;ve had several people express an interest in the ability to visualize relationships. This was surprising to me as personally I&#x27;ve been using &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;timabell.github.io&#x2F;sqlHawk&#x2F;&quot;&gt;SqlHawk&lt;&#x2F;a&gt; (my fork of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaspy.org&#x2F;&quot;&gt;SchemaSpy&lt;&#x2F;a&gt;) to get to grips with database relationships, but I hadn&#x27;t considered that they don&#x27;t get widespread use in the circles I move in; presumably due to a mix of awareness and what a pain they are to set up (Java, shudder).&lt;&#x2F;p&gt;
&lt;p&gt;Having explained my vision for the tool to my friend and ex-colleague Ben, I managed to ask him to say in his own words how he might hypothetically describe it to others, and he uttered the magical words: &quot;well it&#x27;s kind of a schema explorer&quot;. And suddenly I understood that the real value of the tool I&#x27;m creating is not in the ability to poke around the data per-se, it&#x27;s actually the ability to come to an unfamiliar relational database and be able to much more quickly understand how it hangs together. (It&#x27;ll have value in familiar databases too, but I like this focus, it feels higher-value.)&lt;&#x2F;p&gt;
&lt;p&gt;As a result &quot;diagrams&quot; is now the top-priority feature being added to SDV.&lt;&#x2F;p&gt;
&lt;p&gt;It also gives me a new name for Sql Data Viewer...&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;24405997637&#x2F;&quot; title=&quot;IMG_20171219_160643&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;4731&#x2F;24405997637_bda2d45a93.jpg&quot; width=&quot;500&quot; height=&quot;276&quot; alt=&quot;IMG_20171219_160643&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;new-name-new-domain&quot;&gt;New name, new domain&lt;&#x2F;h2&gt;
&lt;p&gt;The product has been renamed to &lt;strong&gt;Sql Schema Explorer&lt;&#x2F;strong&gt;, which can now be found on the shiny new domain &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&quot;&gt;schemaexplorer.io&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For the new website:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I&#x27;ve given up on all the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.timwise.co.uk&#x2F;2017&#x2F;10&#x2F;22&#x2F;choosing-wordpress-hosting-for-a-new-idea&#x2F;&quot;&gt;fancy wordpress designs and hosting&lt;&#x2F;a&gt; I was using for the old domain and have gone for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pages.github.com&#x2F;&quot;&gt;github pages&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;All the bloated css and javascript is gone, leaving nothing but a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sdv-website&#x2F;blob&#x2F;master&#x2F;index.html&quot;&gt;hand-crafted flat html&lt;&#x2F;a&gt; file that should load beautifully on any connection thanks to being under 1kb of content in total with no trackers or external resources.&lt;&#x2F;li&gt;
&lt;li&gt;It should reliably render on most devices with minimal CPU load or delay thanks to the lack of bloated and fragile javascript &#x2F; device detection etc.&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve ditched the fancy drip sign-up form in favour of a simple email link (why solve the volume problem when I don&#x27;t have it yet?).&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve ditched the google analytics tracker because it&#x27;s a vanity metric if it&#x27;s not money in the bank; and these trackers have hidden costs (page load time, leaking your customer&#x27;s data to google etc). If I get a sudden influx I can just ask them how they found me rather than reading between the digital lines.&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve stripped the content back to almost the bare minimum to try and drive focus towards email signups so that I can then engage in-depth through that. I need enough that I can point people at it in conversation to get them signed up. I only need a dozen early customers to help me shape the product so I don&#x27;t need to optimize for complete strangers who&#x27;ve never heard of me yet.&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve created my own personal style of  design that favours minimalistic css and markup to keep page load fast and complexity down whilst still giving structure to the message and a little bit of easiness on the eye (e.g. off-white&#x2F;black, read the css if you like). I&#x27;ll be continuing to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;designacademy.io&#x2F;&quot;&gt;improve my design skills&lt;&#x2F;a&gt; as I work on this project, though I&#x27;m not against outsourcing when I need to.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;money-money-money&quot;&gt;Money, money, money&lt;&#x2F;h2&gt;
&lt;p&gt;You may remember I wrote about &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.timwise.co.uk&#x2F;2017&#x2F;11&#x2F;17&#x2F;why-sdv-could-be-a-billion-dollar-business&#x2F;&quot;&gt;making SDV free&lt;&#x2F;a&gt; not too long ago. With the above new understanding about the value that the product can provide and what it will take to build a full-featured product for that market I am no longer concerned about being immediately copied, and think it has sufficient value to be a viable product in its own right. As such I will be charging for it after all.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll be following the great advice from the episode of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thestartupchat.com&#x2F;ep268&#x2F;&quot;&gt;Startup Chat - 268: Encore Episode – How to Get Your First 10 Customers&lt;&#x2F;a&gt; that I heard recently (highly recommend this if you&#x27;re also thinking of getting a startup &#x2F; side-project off the ground).&lt;&#x2F;p&gt;
&lt;p&gt;The starting price point will be £150 per single user&#x2F;machine. This is based on the &quot;3x the first number you think of&quot; formula because I think  they are right that first instinct is off; after-all I have to make this a viable business otherwise development will stop and no-one wins.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll be offering the recommended money-back guarantee for my first customers; that way I can prove that there is real value in what I&#x27;m creating whilst maintaining my high ethical standards for fairness in business.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;still-here&quot;&gt;Still here?&lt;&#x2F;h2&gt;
&lt;p&gt;Great! Thanks so much for reading this. If you&#x27;re interested in keeping up to date or being involved in the early life of this new product then head over to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;schemaexplorer.io&quot;&gt;schemaexplorer.io&lt;&#x2F;a&gt; and sign up!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>From contractor to entrepreneur - motivations</title>
        <published>2017-11-19T23:01:08+00:00</published>
        <updated>2017-11-19T23:01:08+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/11/19/from-contractor-to-entrepreneur-motivations/"/>
        <id>https://0x5.uk/2017/11/19/from-contractor-to-entrepreneur-motivations/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/11/19/from-contractor-to-entrepreneur-motivations/">&lt;p&gt;I&#x27;m not sure what changed but I used to be happy publishing open source code on github and thinking I&#x27;d done the world a mighty favour. But slowly I started to become uneasy. How much good have I really done if I publish something that only a couple of people find, let alone benefit from? I also started to find it harder to find any time to spend on software to give away for free in between the day job and my growing family. I think that might be why I now find myself pursuing for-profit side projects. It&#x27;s not everything but revenue is some measure of the value I am creating for others. Revenue is also a way of spending more time creating that value; every pound I earn from my creations is a pound I don&#x27;t have to earn from the day job, and because I&#x27;m a contractor I have the luxury of being able to adjust my work levels. If I achieve any success with my own projects that would allow me to invest more of my time in them and generate yet more value without sacrificing family life.&lt;&#x2F;p&gt;
&lt;p&gt;Ever since I entered the world of work I&#x27;ve wanted to create things that help people in some way. I think one of the reasons I still love software development is the joy of watching someone realise I&#x27;ve made one small piece of their life or job better, easier or faster in some meaningful way. Creating my own products that gain wide adoption is the ultimate expression of that for me.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve already had some fantastic unexpected benefits of starting on this journey. It&#x27;s reminded me to be humble, and given me even greater respect for anyone who has created a business. It&#x27;s pushed me to read and listen to many things I wouldn&#x27;t have thought of before, and reading with a goal in mind seems to be a much deeper learning experience. It&#x27;s enabled me to have fascinating conversations with people I otherwise wouldn&#x27;t have had a reason to talk to, such as the lovely generous people at grow@greenpark.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve discovered huge holes in my skills that I was oblivious to in my cosy enterprise-developer role, such as marketing, and I am now super-motivated to learn more.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe I can build something that you would find useful? What&#x27;s the biggest hole in your digital life?&lt;&#x2F;p&gt;
&lt;p&gt;Please &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.timwise.co.uk&#x2F;mailing-list&#x2F;&quot;&gt;sign up for my mailing list&lt;&#x2F;a&gt; so we can follow this journey together.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Looking for beta-testers for my new Free Sql Data Viewer tool</title>
        <published>2017-11-18T01:28:08+00:00</published>
        <updated>2017-11-18T01:28:08+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/11/18/looking-for-beta-testers-for-my-new-free-sql-data-viewer-tool/"/>
        <id>https://0x5.uk/2017/11/18/looking-for-beta-testers-for-my-new-free-sql-data-viewer-tool/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/11/18/looking-for-beta-testers-for-my-new-free-sql-data-viewer-tool/">&lt;p&gt;Hi, my name&#x27;s Tim and I&#x27;m a UK based developer trying to build my first startup.  I&#x27;m working on a data-browsing tool for Sql Server etc. that I really believe can help people do their jobs.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m reaching out to the online communities to try and find people who will find it useful and who are prepared to help me shape the early product.&lt;&#x2F;p&gt;
&lt;p&gt;Please take a look at my offering on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqldataviewer.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;sqldataviewer.com&#x2F;&lt;&#x2F;a&gt; ... and if you like the look of it then please sign up to my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdrip.com&#x2F;forms&#x2F;70504364&#x2F;submissions&#x2F;new&quot;&gt;waiting list&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for your precious time!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;timabell&#x2F;&quot;&gt;Tim Abell&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why SDV could be a billion dollar business</title>
        <published>2017-11-17T23:10:48+00:00</published>
        <updated>2017-11-17T23:10:48+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/11/17/why-sdv-could-be-a-billion-dollar-business/"/>
        <id>https://0x5.uk/2017/11/17/why-sdv-could-be-a-billion-dollar-business/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/11/17/why-sdv-could-be-a-billion-dollar-business/">&lt;p&gt;Okay maybe a billion is a long shot, but I read the Hiten Shah article on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;producthabits.com&#x2F;why-trello-failed-to-build-a-1-billion-business&#x2F;&quot;&gt;how Trello could have been a $1B business&lt;&#x2F;a&gt; (via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thestartupchat.com&#x2F;ep258&#x2F;&quot;&gt;startup chat&lt;&#x2F;a&gt;) and was surprised to discover there are lessons for how I can turn &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqldataviewer.com&#x2F;&quot;&gt;Sql Data Viewer&lt;&#x2F;a&gt; into a sustainable business.&lt;&#x2F;p&gt;
&lt;p&gt;What trello and SDV have in common:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Mass (horizontal) appeal&lt;&#x2F;li&gt;
&lt;li&gt;Easily copied&lt;&#x2F;li&gt;
&lt;li&gt;Difficult to sell premium versions of the general purpose product (&quot;stickers&quot; anyone?)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I was going to just sell SDV for £100 and be done with it, but this article showed me a better way.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Give the general purpose tool away for free (as Trello does)&lt;&#x2F;li&gt;
&lt;li&gt;Collect contact information in exchange for the value provided by the free tool.&lt;&#x2F;li&gt;
&lt;li&gt;Use the contact list to have conversations with businesses that use it in order to...&lt;&#x2F;li&gt;
&lt;li&gt;Find out how integrating tightly with their business could provide real value over and above the general purpose tool.&lt;&#x2F;li&gt;
&lt;li&gt;Build vertical-specific integrations, stickyness &amp;amp; marketing.&lt;&#x2F;li&gt;
&lt;li&gt;Profit! (No underpants required. Or gnomes.)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;What do you think? Drop me a line: &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;tim@timwise.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git for TFS users</title>
        <published>2017-10-27T20:44:06+01:00</published>
        <updated>2017-10-27T20:44:06+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/10/27/git-for-tfs-users/"/>
        <id>https://0x5.uk/2017/10/27/git-for-tfs-users/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/10/27/git-for-tfs-users/">&lt;p&gt;I&#x27;m considering creating a 30 minute video to help teams transition from Team Foundation Server source control to git (hosted with TFS or Visual Studio Team Services - aka VSTS).&lt;&#x2F;p&gt;
&lt;p&gt;Please &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eepurl.com&#x2F;c9imrH&quot;&gt;register your interest&lt;&#x2F;a&gt;. If I get enough interest in this then I&#x27;ll do the work to put it together and launch it.&lt;&#x2F;p&gt;
&lt;p&gt;![tfs-to-git-terminal]({{ site.baseurl }}&#x2F;assets&#x2F;tfs-to-git-terminal.png)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Choosing wordpress hosting for a new idea</title>
        <published>2017-10-22T11:32:08+01:00</published>
        <updated>2017-10-22T11:32:08+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/10/22/choosing-wordpress-hosting-for-a-new-idea/"/>
        <id>https://0x5.uk/2017/10/22/choosing-wordpress-hosting-for-a-new-idea/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/10/22/choosing-wordpress-hosting-for-a-new-idea/">&lt;p&gt;I need somewhere to keep the marketing site&#x2F;content for my new &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqldataviewer.com&#x2F;&quot;&gt;Sql Data Viewer&lt;&#x2F;a&gt; product. (Since renamed to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;timabell.github.io&#x2F;schema-explorer&#x2F;&quot;&gt;SQL Schema Explorer&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I could use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pages.github.com&#x2F;&quot;&gt;github pages&lt;&#x2F;a&gt; or something similar, but I&#x27;ve found the overhead of needing a dev environment to make any change puts me off getting things done. I&#x27;ve been using wordpress.com for this blog and am pretty happy, especially having a mobile app. I&#x27;ve also heard using wordpress makes it easier to outsource content&#x2F;design if you have enough success to make that worthwhile.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t fancy maintenance, security patching and backup, so the marketing site is currently on &lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wordpress.com&#x2F;&quot;&gt;wordpress.com&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; where I&#x27;ve paid for the &quot;personal&quot; plan at &lt;strong&gt;£3&#x2F;month&lt;&#x2F;strong&gt; to remove ads and the &lt;strong&gt;£0.92&#x2F;month&lt;&#x2F;strong&gt; for mapping a domain. Affordable for contactor running a shot-in-the-dark startup side-project that may never make a penny. Note that you only get their built in analytics, you can&#x27;t add google analytics, and you can&#x27;t install plugins on that plan.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;To get google analytics you need &quot;premium&quot; at £7&#x2F;month&lt;&#x2F;li&gt;
&lt;li&gt;To be able to add plugins you need &quot;business&quot; at £20&#x2F;month&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is on top of the &lt;strong&gt;£1.15&#x2F;month&lt;&#x2F;strong&gt; for domain registration and &lt;strong&gt;£10&#x2F;month&lt;&#x2F;strong&gt; for a VPS (virtual private server) to run my demo site from, both from the excellent &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bytemark.co.uk&#x2F;&quot;&gt;bytemark&lt;&#x2F;a&gt; hosting company, who&#x27;ve been fab on support from day one.&lt;&#x2F;p&gt;
&lt;p&gt;Just for completeness: the demo site connects to sql azure instances are easily within the $40&#x2F;month included with my MSDN Professional subscription that I use for contracting. Handy.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been listening to lots of startup podcasts (&lt;a href=&quot;mailto:tim@timwise.co.uk?subject=startup-podcasts&amp;amp;body=send-me-your-opml!&quot;&gt;email me&lt;&#x2F;a&gt; if you want the list), and have discovered the mighty &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;justinjackson.ca&#x2F;&quot;&gt;Justin Jackson&lt;&#x2F;a&gt; and his excellent &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devmarketing.xyz&#x2F;&quot;&gt;Marketing for Developers&lt;&#x2F;a&gt; content - I recommend you buy it if you&#x27;re a developer thinking of selling a product &#x2F; service. I&#x27;m now working through trying to apply the lessons in the book to my own product. I got to the analytics bit and hit a wall. Wordpress.com (the wordpress hosting site, not the software itself) force you to upgrade to the business plan at &lt;strong&gt;£20.83&#x2F;month&lt;&#x2F;strong&gt;. Given I don&#x27;t know how long this is going to take me I&#x27;m not keen to start ramping up costs to that extent with no obvious route to a return on the investment.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve looked at the three recommended in Justin&#x27;s book (plus more added more recently), and the starting prices are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.siteground.co.uk&#x2F;wordpress-hosting.htm&quot;&gt;Siteground&lt;&#x2F;a&gt;: Startup plan (like it!) &lt;strong&gt;£2.75&#x2F;month&lt;&#x2F;strong&gt; - looks like this might be a winner then! Oh wait, that&#x27;s a sign-up discount, it&#x27;s actually &lt;strong&gt;£6.95&#x2F;month&lt;&#x2F;strong&gt;. Hrumph.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;krystal.uk&#x2F;wordpress-hosting&quot;&gt;Krystal&lt;&#x2F;a&gt;: Personal &lt;strong&gt;£18&#x2F;month&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wpengine.com&#x2F;plans&#x2F;&quot;&gt;WPEngine&lt;&#x2F;a&gt;: Personal $29&#x2F;month - about &lt;strong&gt;£22&#x2F;month&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pagely.com&#x2F;plans-pricing&#x2F;&quot;&gt;Pagely&lt;&#x2F;a&gt;: VPS-1 $499&#x2F;month - about &lt;strong&gt;£380&#x2F;month&lt;&#x2F;strong&gt; - ouch! I don&#x27;t think I&#x27;m their target market. I wonder if they repriced, perhaps Justin should drop this one from the book.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And that&#x27;s where I&#x27;m at right now. Maybe I&#x27;ll just shove a docker wordpress image on the VPS, it&#x27;s already a docker host. I need to figure out hosting multiple sites on one IP for the demos anyway. But then again, I don&#x27;t want to be a wordpress sys-admin. Or maybe I&#x27;ll rethink the static site thing.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Home server docker-compose</title>
        <published>2017-08-29T21:26:28+01:00</published>
        <updated>2017-08-29T21:26:28+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/08/29/home-server-docker-compose/"/>
        <id>https://0x5.uk/2017/08/29/home-server-docker-compose/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/08/29/home-server-docker-compose/">&lt;p&gt;Another step in making a throw-away home server: docker-compose.&lt;&#x2F;p&gt;
&lt;p&gt;Find my compose file and setup script at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;home-server-docker-compose&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;home-server-docker-compose&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I learned how to use docker-compose while working on reverse-proxying sdv, find out more: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sdv-docker&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;sdv-docker&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Home server backups</title>
        <published>2017-08-29T20:31:08+01:00</published>
        <updated>2017-08-29T20:31:08+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/08/29/home-server-backups/"/>
        <id>https://0x5.uk/2017/08/29/home-server-backups/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/08/29/home-server-backups/">&lt;p&gt;The setup&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu server domU xen host
&lt;ul&gt;
&lt;li&gt;Ubuntu server xen VM with LUKS full disk encryption
&lt;ul&gt;
&lt;li&gt;docker-compose
&lt;ul&gt;
&lt;li&gt;syncthing with built-in &quot;Staggered File Versioning&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Plan&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Plug in usb external hdd, with full disk encryption (i.e. a LUKS partition taking up almost all the space, plus a little fat32 with a text file in case anyone finds it and wants to return it).&lt;&#x2F;li&gt;
&lt;li&gt;Use LUKS key chaining to be able to unlock the disk without entering a password&lt;&#x2F;li&gt;
&lt;li&gt;Use autofs to automatically mount&#x2F;unmount so that it&#x27;s safe to unplug when a backup isn&#x27;t running.&lt;&#x2F;li&gt;
&lt;li&gt;Use rsync to push all the files from the syncthing data directory onto the usb disk.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Somehow need to make the disk accessible to the VM.&lt;&#x2F;p&gt;
&lt;p&gt;Finding the luks partition when plugged into the host:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@spot:~$ sudo fdisk -l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Disk &#x2F;dev&#x2F;sdc: 931.5 GiB, 1000170586112 bytes, 1953458176 sectors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Units: sectors of 1 * 512 = 512 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sector size (logical&#x2F;physical): 512 bytes &#x2F; 512 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;I&#x2F;O size (minimum&#x2F;optimal): 512 bytes &#x2F; 512 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Disklabel type: dos&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Disk identifier: 0x6380ad37&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Device Boot Start End Sectors Size Id Type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;sdc1 63 21579 21517 10.5M c W95 FAT32 (LBA)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**&#x2F;dev&#x2F;sdc2 21580 1953147527 1953125948 931.3G 83 Linux**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@spot:~$ ll &#x2F;dev&#x2F;disk&#x2F;by-uuid&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 10 Aug 29 21:51 **6ca09b72-8c9b-4571-8943-9f1d520671ab -&amp;gt; ..&#x2F;..&#x2F;sdc2**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Confirm it&#x27;s the luks partition:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@spot:~$ sudo cryptsetup luksDump &#x2F;dev&#x2F;disk&#x2F;by-uuid&#x2F;6ca09b72-8c9b-4571-8943-9f1d520671ab&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LUKS header information for &#x2F;dev&#x2F;disk&#x2F;by-uuid&#x2F;6ca09b72-8c9b-4571-8943-9f1d520671abVersion: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cipher name: aes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cipher mode: xts-plain64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Hash spec: sha1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;ll update this post with any details as I progress. Don&#x27;t hold your breath though!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running sdv in docker</title>
        <published>2017-08-13T20:35:14+01:00</published>
        <updated>2017-08-13T20:35:14+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/08/13/running-sdv-in-docker/"/>
        <id>https://0x5.uk/2017/08/13/running-sdv-in-docker/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/08/13/running-sdv-in-docker/">&lt;p&gt;Just bought a shared server with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bytemark.co.uk&#x2F;&quot;&gt;bytemark&lt;&#x2F;a&gt;. (£10&#x2F;month), Installed vanilla ubuntu 16.04LTS server using the control panel (virtually one-click).&lt;&#x2F;p&gt;
&lt;p&gt;![Servers - Bytemark Manager - Mozilla Firefox_143]({{ site.baseurl }}&#x2F;assets&#x2F;servers-bytemark-manager-mozilla-firefox_143.png)&lt;&#x2F;p&gt;
&lt;p&gt;(Love the cancel button text!)&lt;&#x2F;p&gt;
&lt;p&gt;Ssh&#x27;d in, created my own user to use with sudo instead of root. Ran the following, and immediately had a copy of sdv listening on the internet.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo apt install tmux docker docker-compose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo adduser tim docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# logout &amp;amp; reconnect to get new group to take effect&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wget https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;timabell&#x2F;sdv-docker&#x2F;master&#x2F;docker-compose.yml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and then for the magic:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@sdvweb:~$ docker-compose up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pulling sdv (timabell&#x2F;sdv:latest)...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;latest: Pulling from timabell&#x2F;sdv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d5c6f90da05d: Pull complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1300883d87d5: Pull complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c220aa3cfc1b: Pull complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2e9398f099dc: Pull complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dc27a084064f: Pull complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eb1a4736b68c: Pull complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0706cf350247: Pull complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1d0ac78e96a5: Pull complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Digest: sha256:9003a79f019b3ee16e7c6324afd275b4535f867602e63db317e430528e2a6771&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Status: Downloaded newer image for timabell&#x2F;sdv:latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Creating tim_sdv_1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Attaching to tim_sdv_1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sdv_1 | .&#x2F;sdv-linux-x64 -listenOn 0.0.0.0 -port 8080 -driver sqlite -db &#x2F;data&#x2F;Chinook_Sqlite_AutoIncrementPKs.sqlite&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sdv_1 | 2017&#x2F;08&#x2F;13 19:14:44 Sql Data Viewer v0.4; Copyright 2015-2017 Tim Abell &amp;lt;sdv@timwise.co.uk&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sdv_1 | 2017&#x2F;08&#x2F;13 19:14:44 ## This pre-release software will expire on: 2017-10-01 00:00:00 +0000 UTC, contact sdv@timwise.co.uk for a license. ##&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sdv_1 | 2017&#x2F;08&#x2F;13 19:14:44 Starting server on http:&#x2F;&#x2F;0.0.0.0:8080&#x2F; - Press Ctrl-C to kill server.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that&#x27;s it, listening on the internet!&lt;&#x2F;p&gt;
&lt;p&gt;![Sql Data Viewer - Mozilla Firefox_144]({{ site.baseurl }}&#x2F;assets&#x2F;sql-data-viewer-mozilla-firefox_144.png)&lt;&#x2F;p&gt;
&lt;p&gt;Any changes I make will be to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;timabell&#x2F;sdv&#x2F;&quot;&gt;docker and compose files&lt;&#x2F;a&gt;, resulting in trivially easy to repeat deployments, making the server completely throwaway. Huzzah! Docker is awesome.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve also bought a domain for the product, but haven&#x27;t set much up on it yet: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sqldataviewer.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.sqldataviewer.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Next up, getting nginx reverse proxy to provide ssl. And finishing the refactor I was in the middle of to get data types to behave, and finishing the automated regression tests I&#x27;d just started (needed for reliable multi rdbms support), and finding my market, and marketing the product, and doing more features, and build the marketing automation to drive sales, etc etc. Not too much to do then! Your support would be appreciated, if you&#x27;re interested make sure you &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdrip.com&#x2F;forms&#x2F;70504364&#x2F;submissions&#x2F;new&quot;&gt;sign up to the mailing list now&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re wondering why docker matters more generally then listen to this podcast episode: Hanselminutes: Practical Containers for Developers with Aja Hammerly &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.hanselminutes.com&#x2F;default.aspx?ShowID=18514&quot;&gt;http:&#x2F;&#x2F;www.hanselminutes.com&#x2F;default.aspx?ShowID=18514&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Patreon open source funding</title>
        <published>2017-06-03T10:24:40+01:00</published>
        <updated>2017-06-03T10:24:40+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/06/03/patreon-open-source-funding/"/>
        <id>https://0x5.uk/2017/06/03/patreon-open-source-funding/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/06/03/patreon-open-source-funding/">&lt;p&gt;I&#x27;m now &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.patreon.com&#x2F;timabell&quot;&gt;on patreon&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Hopefully this will provide enough funding that I can take better care of the open source projects that I look after. Since becoming a daddy it&#x27;s become hard to find the time to do free work on these projects even though I love working on them. Combine that with the ambition to create a startup which eats up the rest of my spare time and the result is that these projects that I love are getting stale.&lt;&#x2F;p&gt;
&lt;p&gt;As a contractor my time is available for purchase. Unlike in permanent employment I can vary the amount of paid client work I take on in a year, so if I get serious funding for the open source work I can legitimately scale back my normal client work to make time for it. I&#x27;m not looking for people to buy me a pint out of gratitude here (though I wouldn&#x27;t complain!), I&#x27;m looking for serious funding from people and organisations that benefit from all the hard work put in so that we can all benefit from further improvements to the great public codebase that is open source.&lt;&#x2F;p&gt;
&lt;p&gt;As an example, my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nuget.org&#x2F;packages&#x2F;ef-enum-to-lookup&quot;&gt;ef-enum-lookup nuget package&lt;&#x2F;a&gt; has had 18k downloads to date, and I suspect this is unlikely to be used in hobby projects given the nature of EF (entity framework, an object-relational-mapper from Microsoft). So a fair number of commercial operations are benefiting from the improvements to their database that this project brings. I&#x27;ve had several requests and even some pull requests for improvements and features that I would dearly like to add, and that these businesses would benefit from; if they pooled money via Patreon then it would actually be an economical way for them all to benefit from the improvements. For example I counted six different individuals expressing an interest in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;ef-enum-to-lookup&#x2F;issues&#x2F;1&quot;&gt;custom schema support&lt;&#x2F;a&gt;. What if they or their companies all contributed?&lt;&#x2F;p&gt;
&lt;p&gt;If you want a project to not dissolve into a mess then even pull requests are not free. Although there is a probably-working improvement, it may not fit the style of the project, it may introduce other issues, it may be missing unit tests, it may be written by a less experienced programmer and need additional work and&#x2F;or support.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve had to choose monthly or per-feature on Patreon, and I&#x27;ve gone for monthly because there&#x27;s more to an open source project than just bug-fixes and features - you also have to package it, unit test it, host it, refactor it, document it, set up continuous deployment or whatever the flavour of the day is, and respond to people who are having issues or who have contributions to offer. It seems to be a better match to the nature of open source development to ask for ongoing support as once someone is using a project they are likely going to benefit from using it for some time, and even a new feature will have a long life providing value to users.&lt;&#x2F;p&gt;
&lt;p&gt;I haven&#x27;t picked a specific daily rate I&#x27;d work on this for yet, but I&#x27;d probably give some discount over my normal contract rates just because I think it&#x27;s worthwhile and I enjoy it.&lt;&#x2F;p&gt;
&lt;p&gt;Do you or your employer use any of my open source projects? Fund me to make them better! Head over to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.patreon.com&#x2F;timabell&quot;&gt;https:&#x2F;&#x2F;www.patreon.com&#x2F;timabell&lt;&#x2F;a&gt; with your boss&#x27;s credit card and then drop me a line to let me know what&#x27;s of interest to you.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Dustbin of ideas - IT Contractor Buddy</title>
        <published>2017-05-12T12:32:07+01:00</published>
        <updated>2017-05-12T12:32:07+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/05/12/dustbin-of-ideas-it-contractor-buddy/"/>
        <id>https://0x5.uk/2017/05/12/dustbin-of-ideas-it-contractor-buddy/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/05/12/dustbin-of-ideas-it-contractor-buddy/">&lt;p&gt;I&#x27;ve talked to a couple of people experienced in the recruitment industry and it appears that the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.timwise.co.uk&#x2F;2017&#x2F;05&#x2F;03&#x2F;it-contractor-buddy&#x2F;&quot;&gt;contractor buddy&lt;&#x2F;a&gt; business idea has some fatal flaws and is unlikely to succeed.&lt;&#x2F;p&gt;
&lt;p&gt;You might be surprised to hear that I consider this a success on my journey to startup success.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I&#x27;ve had a business idea (not an easy thing to do!) which is more realistic than many of my previous ideas showing that my ability to spot such opportunities is improving. (It has a clear revenue model and its fairly easy to see how it could be built.)&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve not become too attached to it to hear valid criticism.&lt;&#x2F;li&gt;
&lt;li&gt;By putting it out there and discussing it openly with anyone willing to help me out I&#x27;ve rapidly found the flaws in it without wasting valuable time or money. (Imaging if I spent two years building it to then have the same flaws sink it.)&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve managed to find contacts from a broad range of backgrounds who have helped me to crystallize my idea - this is entirely thanks to spending time at the fabulous co-working and startup community space &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;growgreenpark.spaces.nexudus.com&#x2F;en&quot;&gt;grow@greenpark&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So what sank it?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Even though the company would not be inserted into the financial transaction, they would still need to be a communication relay between employer&#x2F;agent and candidate, and the received opinion is that this just won&#x27;t fly.&lt;&#x2F;li&gt;
&lt;li&gt;The number of contractors who could find this useful could be small, with the highly in-demand people not having to put in much work to get the next contract (therefore not gaining much value from the service), and the the not-in-demand contractors are not a market the business would want to be primarily associated with as it could become a by-word for low-quality talent. This leaves the middle ground which may not be enough of a market to support the business. Before I&#x27;d talked to anyone I&#x27;d assumed that all contractors would want this (based on sample size of one - me).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;32091991176&#x2F;&quot; title=&quot;New cycle route, green park - closed at night, wtf&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;765&#x2F;32091991176_0f19b14a2f.jpg&quot; width=&quot;500&quot; height=&quot;374&quot; alt=&quot;New cycle route, green park - closed at night, wtf&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The investment required to prove&#x2F;disprove these suppositions would be significant, as I think you&#x27;d basically have to build the functioning business to see what happens in reality. So on that basis, &quot;I&#x27;m out!&quot;&lt;&#x2F;p&gt;
&lt;p&gt;So what now?&lt;&#x2F;p&gt;
&lt;p&gt;Well there&#x27;s my &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.timwise.co.uk&#x2F;sdv&#x2F;&quot;&gt;Sql Data Viewer&lt;&#x2F;a&gt; that I haven&#x27;t given up on (check it out, let me know what you think and join the mailing list).&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s also the possibility of a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.startupgrind.com&#x2F;blog&#x2F;is-pivot-the-new-fail&#x2F;&quot;&gt;pivot&lt;&#x2F;a&gt;. Maybe there&#x27;s room for something to help contractors without getting in the middle? Maybe it could send mail using their real email address and handle responses? Maybe there&#x27;s already something like that out there and I should just use it instead of trying to invent my own! Let me know in the comments if you know of anything or already have ways to ease the pain.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for listening.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>IT Contractor buddy</title>
        <published>2017-05-03T13:31:51+01:00</published>
        <updated>2017-05-03T13:31:51+01:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/05/03/it-contractor-buddy/"/>
        <id>https://0x5.uk/2017/05/03/it-contractor-buddy/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/05/03/it-contractor-buddy/">&lt;h2 id=&quot;a-new-job-hunting-assistant-for-contractors&quot;&gt;A new job-hunting assistant for contractors&lt;&#x2F;h2&gt;
&lt;p&gt;Calling all IT contractors; would you pay to have some of the pain of contract hunting taken away?&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m considering launching a business for IT contractors like myself that will do the tedious and time-consuming bits of job hunting.&lt;&#x2F;p&gt;
&lt;p&gt;If this is something you think you&#x27;d be interested in then &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eepurl.com&#x2F;cNqrrf&quot;&gt;sign up to the mailing list for early access&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;concept&quot;&gt;Concept&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Search job postings for you, letting you know when good matches come up, across multiple job boards.&lt;&#x2F;li&gt;
&lt;li&gt;Submit your CV on your behalf&lt;&#x2F;li&gt;
&lt;li&gt;Keep track your applications (when you sent your CV where for what rate).&lt;&#x2F;li&gt;
&lt;li&gt;Handle first contact from companies &#x2F; recruiters, validating it&#x27;s worth your time&lt;&#x2F;li&gt;
&lt;li&gt;A simple monthly fee, with no long-term commitment.&lt;&#x2F;li&gt;
&lt;li&gt;No cut of your contract rate and no fee per placement.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A concierge service for IT contractors.&lt;&#x2F;p&gt;
&lt;p&gt;As I know from first-hand experience the job hunt is a time-consuming slog where being on top of all your leads is critical to avoid being taken advantage of rate-wise by a sharp-eyed contingency recruiter, or having a deal ruined by duplicate CV submissions.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;33461099014&#x2F;&quot; title=&quot;IMG_20170424_121829_crop&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;4164&#x2F;33461099014_c2ce23d162.jpg&quot; width=&quot;500&quot; height=&quot;114&quot; alt=&quot;IMG_20170424_121829_crop&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;how-is-this-different-from-all-the-other-recruiters&quot;&gt;How is this different from all the other recruiters?&lt;&#x2F;h2&gt;
&lt;p&gt;In house recruiters are agents of the hiring company, and you may have to deal with many of these. We are working for you, the contractor, no matter how many companies and agencies you are talking to. They can only help you with respect to their company.&lt;&#x2F;p&gt;
&lt;p&gt;Contingency recruiters (i.e. 3rd party recruiters) are trying to insert themselves into the deal between you and a client, sometimes with the okay of that client, sometimes without. Unlike them we are not trying to skim money off your contracts, instead we are providing a service that helps you avoid the painful bits of the job hunt, for a straight-forward monthly fee that reflects the value we provide to you. Value for value. These recruiters will not help you with leads from other recruiters, in fact letting them know about other leads is a recipe for disaster.&lt;&#x2F;p&gt;
&lt;p&gt;So neither of these will help you with your overall job hunt. You still have to manage all your leads yourself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-is-this-different-from-a-talent-agent&quot;&gt;How is this different from a talent agent?&lt;&#x2F;h2&gt;
&lt;p&gt;You may have &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.newyorker.com&#x2F;magazine&#x2F;2014&#x2F;11&#x2F;24&#x2F;programmers-price&quot;&gt;read the new-yorker piece about&lt;&#x2F;a&gt; the agent &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.10xmanagement.com&#x2F;&quot;&gt;10x&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;They &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.10xmanagement.com&#x2F;faq&#x2F;&quot;&gt;charge 15% of your rate&lt;&#x2F;a&gt; (a pretty big cut imho!) whereas we charge a flat rate for the service we provide; value for value.&lt;&#x2F;li&gt;
&lt;li&gt;They are limiting themselves to the mythical 10x&#x27;er. So even though they offer a lot of the concierge I&#x27;m offering, you probably can&#x27;t get them to take you on. We however will take on even non-rocket-scientist contractors as we scale, free from BS hype about &quot;rockstars&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Our service is clearly working for you and no-one else whereas with 10x&#x27;s  percentage fee it&#x27;s not clear who they work for no matter what the marketing says.&lt;&#x2F;li&gt;
&lt;li&gt;10x are attempting to find clients directly, just like every other contingency recruiter. We don&#x27;t mind where your work comes from as we aren&#x27;t trying to insert ourselves into the deal, so you won&#x27;t be limiting your market by working with us, in fact we&#x27;ll make it easier for you to cover more of the market by doing the hard work for you.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sign-up-now&quot;&gt;Sign up now!&lt;&#x2F;h2&gt;
&lt;p&gt;If you think this is something you might use, then please &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eepurl.com&#x2F;cNqrrf&quot;&gt;sign up to the mailing list&lt;&#x2F;a&gt; so you can get first access. There will initially be limited spaces for clients so that we don&#x27;t overstretch, so &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eepurl.com&#x2F;cNqrrf&quot;&gt;sign up now&lt;&#x2F;a&gt; for first-come first-served early access.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New home server with Xen and docker</title>
        <published>2017-03-10T00:03:48+00:00</published>
        <updated>2017-03-10T00:03:48+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/03/10/new-home-server-with-xen-and-docker/"/>
        <id>https://0x5.uk/2017/03/10/new-home-server-with-xen-and-docker/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/03/10/new-home-server-with-xen-and-docker/">&lt;h2 id=&quot;no-cloud-mkay&quot;&gt;No cloud mkay?&lt;&#x2F;h2&gt;
&lt;p&gt;Going against the current received wisdom I personally am not keen to trade the convenience of the public cloud sync services such as dropbox, onedrive, google drive etc for the fact that this means that all my files traverse the public internet and live on someone else&#x27;s metal. Sure it might be encrypted, but what if my traffic is intercepted and stored, and then that encryption is later found to be flawed?&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m probably just as likely to get pwned running my own setup, but hey at least I get to learn something along the way.&lt;&#x2F;p&gt;
&lt;p&gt;Another thought is that regardless of location - home, office, cloud, vps host or data centre - it&#x27;s all just (server) software. So why shouldn&#x27;t we be able to get the amazing seamless experience when self hosting? It seems to me that it comes down to economics. Cloud hosting gives an opportunity for charging directly or worse using underhand tactics like owning your data or selling you as a product to advertisers. This means there is more funding for cloud systems, and therefore more developers are working on it. Even ethically minded software developers have to eat and live somewhere. I think just like Linux vs Windows we will get a perfectly good open source solution, but it will likely lag behind.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;disk-encryption&quot;&gt;Disk encryption&lt;&#x2F;h2&gt;
&lt;p&gt;I have a new machine to use as a server so have an opportunity for a fresh approach. I want my server encrypted at rest in case the whole machine gets stolen from the house to keep the scoundrels from having easy access to all my files.&lt;&#x2F;p&gt;
&lt;p&gt;The previous machine I installed with encrypted LVM as available with Ubuntu server&#x27;s installer; but this means going to the machine to unlock it after every reboot &#x2F; power failure &#x2F; kernel upgrade. I did have &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.nguyenvq.com&#x2F;blog&#x2F;2011&#x2F;09&#x2F;13&#x2F;remote-unlocking-luks-encrypted-lvm-using-dropbear-ssh-in-ubuntu&#x2F;&quot;&gt;remote unlock via dropbear ssh&lt;&#x2F;a&gt; set up but it&#x27;s hacky to set up and non-trivial to use.&lt;&#x2F;p&gt;
&lt;p&gt;This time I&#x27;ve gone for a different approach:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An unencrypted install of ubuntu server (DomU) with an ssh server, so no password required to boot up, which does nothing more than give access to:&lt;&#x2F;li&gt;
&lt;li&gt;A Xen VM install of Ubuntu server (Dom1), this one with LVM disk encryption. This is where all my files etc will live. Installed with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;virt-manager.org&#x2F;&quot;&gt;virt-manager&lt;&#x2F;a&gt;, which is a very convenient UI for initial setup.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So now after a reboot I can &lt;code&gt;ssh -X&lt;&#x2F;code&gt; into the DomU server, then using virt-manager I can see the Dom1 VM waiting for the disk encryption key and provide the passphrase.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xen&quot;&gt;Xen&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.ubuntu.com&#x2F;community&#x2F;Xen#Installing_Xen&quot;&gt;Setup instructions for xen on Ubuntu&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It wasn&#x27;t immediately obvious how to set up the networking. This was the network config that worked in the end (after ifdown&#x2F;ifup, also tested with full reboot):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cat &#x2F;etc&#x2F;network&#x2F;interfaces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;source &#x2F;etc&#x2F;network&#x2F;interfaces.d&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# The loopback network interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auto lo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iface lo inet loopback&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auto xenbr0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iface xenbr0 inet dhcp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  bridge_ports enp1s0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# The primary network interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auto enp1s0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iface enp1s0 inet manual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#iface enp1s0 inet dhcp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;docker&quot;&gt;Docker&lt;&#x2F;h2&gt;
&lt;p&gt;Seeing as docker is well and truly coming to windows it&#x27;s time I got better at this so, for this and also better isolation and security I&#x27;ll try and set up as many of the services I want to run as I can through docker.&lt;&#x2F;p&gt;
&lt;p&gt;First test case was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;transmissionbt.com&#x2F;&quot;&gt;transmission-bt&lt;&#x2F;a&gt; which I run to be a good citizen and help seed &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linuxmint.com&#x2F;download.php&quot;&gt;Linux Mint ISOs&lt;&#x2F;a&gt; using my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aa.net.uk&#x2F;broadband-home1.html&quot;&gt;A&amp;amp;A unmetered upload&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;search&#x2F;?isAutomated=0&amp;amp;isOfficial=0&amp;amp;page=1&amp;amp;pullCount=1&amp;amp;q=transmission&amp;amp;starCount=0&quot;&gt;Searching for transmission on docker hub&lt;&#x2F;a&gt;, I didn&#x27;t want the vpn one, I&#x27;m not pirating movies and my ISP doesn&#x27;t do stupid filtering&#x2F;shaping tricks on torrents. I chose the next most popular: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;linuxserver&#x2F;transmission&#x2F;&quot;&gt;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;linuxserver&#x2F;transmission&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To install and run it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo -i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# useradd -r -s &#x2F;sbin&#x2F;nologin transmission&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# id transmission&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;id=999(transmission) gid=999(transmission) groups=999(transmission)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cd &#x2F;var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mkdir transmission&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cd transmission&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mkdir config downloads watch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# chown transmission:transmission .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# docker create --name=transmission \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v &#x2F;var&#x2F;transmission&#x2F;config&#x2F;:&#x2F;config \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v &#x2F;var&#x2F;transmission&#x2F;downloads&#x2F;:&#x2F;downloads \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v &#x2F;var&#x2F;transmission&#x2F;watch&#x2F;:&#x2F;watch \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -e PGID=999 -e PUID=999 -e TZ=&amp;quot;Europe&#x2F;London&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -p 9091:9091 -p 51413:51413 -p 51413:51413&#x2F;udp \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  linuxserver&#x2F;transmission&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# docker start transmission&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# docker logs -f transmission&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;useradd ref: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;29359&#x2F;how-to-add-user-without-home&quot;&gt;http:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;29359&#x2F;how-to-add-user-without-home&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once that was done I could see the transmission web UI at &lt;code&gt;http:&#x2F;&#x2F;dom1vm:9091&#x2F;&lt;&#x2F;code&gt;. Hurrah.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;syncthing&quot;&gt;syncthing&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;store.docker.com&#x2F;community&#x2F;images&#x2F;linuxserver&#x2F;syncthing&quot;&gt;https:&#x2F;&#x2F;store.docker.com&#x2F;community&#x2F;images&#x2F;linuxserver&#x2F;syncthing&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Same deal with folders and users, then:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;# docker create --name=syncthing -v &#x2F;var&#x2F;syncthing&#x2F;config&#x2F;:&#x2F;config -v &#x2F;var&#x2F;syncthing&#x2F;data&#x2F;:&#x2F;data -e PGID=998 -e PUID=998 -p 8384:8384 -p 22000:22000 -p 21027:21027&#x2F;udp linuxserver&#x2F;syncthing&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;start-on-boot&quot;&gt;Start on boot&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;docker update --restart=unless-stopped transmission&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;docker update --restart=unless-stopped syncthing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;37479753&#x2F;10245&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;37479753&#x2F;10245&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;todo&quot;&gt;Todo&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nextcloud.com&#x2F;&quot;&gt;nextcloud&lt;&#x2F;a&gt; - has an iOS app that syncthing doesn&#x27;t yet, might also have better selective sync
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;store.docker.com&#x2F;community&#x2F;images&#x2F;wonderfall&#x2F;nextcloud&quot;&gt;https:&#x2F;&#x2F;store.docker.com&#x2F;community&#x2F;images&#x2F;wonderfall&#x2F;nextcloud&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;plex server
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.plex.tv&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.plex.tv&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.level1techs.com&#x2F;t&#x2F;dexter-kanes-ultra-paranoid-encrypted-nas-completed&#x2F;98340&quot;&gt;https:&#x2F;&#x2F;forum.level1techs.com&#x2F;t&#x2F;dexter-kanes-ultra-paranoid-encrypted-nas-completed&#x2F;98340&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New year new blog</title>
        <published>2017-01-17T23:36:00+00:00</published>
        <updated>2017-01-17T23:36:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/01/17/new-year-new-blog/"/>
        <id>https://0x5.uk/2017/01/17/new-year-new-blog/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/01/17/new-year-new-blog/">&lt;p&gt;So-long blogger and thanks for all the fish.&lt;&#x2F;p&gt;
&lt;p&gt;My content to date will live on here for as long as google keep the bits spinning.&lt;&#x2F;p&gt;
&lt;p&gt;Find my new blog at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.timwise.co.uk&#x2F;2017&#x2F;01&#x2F;17&#x2F;new-year-new-blog-happy-2017&#x2F;&quot;&gt;http:&#x2F;&#x2F;blog.timwise.co.uk&#x2F;2017&#x2F;01&#x2F;17&#x2F;new-year-new-blog-happy-2017&#x2F;&lt;&#x2F;a&gt; which will live for as long as I pay wordpress.com&#x27;s bills and don&#x27;t screw up my DNS config.&lt;&#x2F;p&gt;
&lt;p&gt;See y&#x27;all on the other side. Don&#x27;t forget to subscribe to the new RSS feed.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Startup competitors - Data Viewer</title>
        <published>2017-01-17T01:55:27+00:00</published>
        <updated>2017-01-17T01:55:27+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/01/17/startup-competitors-data-viewer/"/>
        <id>https://0x5.uk/2017/01/17/startup-competitors-data-viewer/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/01/17/startup-competitors-data-viewer/">&lt;p&gt;If you follow my ramblings you might know that I&#x27;ve revived my interest in
creating a commercial tool to help devs, dbas etc browse their sql databases.
I&#x27;ve done some research before and didn&#x27;t find much on a par with what I have
in mind. I&#x27;ve done a bit more, and turned up a couple:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sql-workbench.net&#x2F;fk_lookup_png.html&quot;&gt;A feature of sql
workbench&lt;&#x2F;a&gt; - I&#x27;ve seen the
product but didn&#x27;t know it could do that. Not directly competition as it&#x27;s
not nearly as smooth to use as what I&#x27;m building for this particular use
case.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sqlsmash.com&#x2F;&quot;&gt;SqlSmash&lt;&#x2F;a&gt; - Something I&#x27;d not seen before, which
has &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;Z0kdqcrYHdo?t=1m14s&quot;&gt;fk based navigation (vid)&lt;&#x2F;a&gt;
that&#x27;s basically what I&#x27;m building, albeit embedded in SSMS rather than
standalone.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This isn&#x27;t the first time I&#x27;ve had the experience of getting started before
discovering another product that basically solves the problem I&#x27;m gunning for.
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.red-gate.com&#x2F;products&#x2F;sql-development&#x2F;readyroll&#x2F;&quot;&gt;Ready-roll&lt;&#x2F;a&gt; was
the last, since bought by red-gate).&lt;&#x2F;p&gt;
&lt;p&gt;Now it&#x27;s not that I thought my idea was magic or special or a unique little
flower, but why is it after working with SQL Server databases for 15 years that
I&#x27;ve only just noticed this tool (which I would have found useful and probably
would have paid for).&lt;&#x2F;p&gt;
&lt;p&gt;If I created another would it be just as obscure? Should I still go ahead even
though it&#x27;s a solved problem? Are there any ideas left on the earth?&lt;&#x2F;p&gt;
&lt;p&gt;Something for me to consider this week. I might update this post with further
thoughts. Your thoughts are welcome.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;ul&gt;
&lt;li&gt;You might also like this post: &lt;a href=&quot;&#x2F;2019&#x2F;06&#x2F;10&#x2F;database-tools-you-didnt-know-about&#x2F;&quot;&gt;Database tools I was surprised
existed&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;I did end up building it, and it became &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;schemaexplorer.io&#x2F;&quot;&gt;https:&#x2F;&#x2F;schemaexplorer.io&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New year new blog, happy 2017</title>
        <published>2017-01-17T01:00:09+00:00</published>
        <updated>2017-01-17T01:00:09+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2017/01/17/new-year-new-blog-happy-2017/"/>
        <id>https://0x5.uk/2017/01/17/new-year-new-blog-happy-2017/</id>
        
        <content type="html" xml:base="https://0x5.uk/2017/01/17/new-year-new-blog-happy-2017/">&lt;p&gt;I&#x27;ve used blogger for years, but the layout for code has not improved for a long time. I&#x27;ve also found my domain&#x27;s website stagnating because of the hassle of updating it, so I&#x27;ve moved the whole kaboodle to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wordpress.com&#x2F;&quot;&gt;wordpress.com&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Find my old blog and all its content at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;timwise.blogspot.co.uk&#x2F;&quot;&gt;http:&#x2F;&#x2F;timwise.blogspot.co.uk&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not migrating the content from blogger because I think google will keep it online, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;Provider&#x2F;Style&#x2F;URI.html&quot;&gt;cool URIs don&#x27;t change&lt;&#x2F;a&gt;. I&#x27;ve never been convinced of the value of people lugging their blog posts from one platform to the next, it seems to break more than it fixes most of the time. Like the one where the old host didn&#x27;t need the trailing slash at the end of the URL and the new host did, breaking half the incoming links. It&#x27;s only because I&#x27;m a web dev that I guessed what the fix was.&lt;&#x2F;p&gt;
&lt;p&gt;Enough about that anyway. Happy new year :-)&lt;&#x2F;p&gt;
&lt;p&gt;Please do add my new blog to your favourite blog reading software &#x2F; rss reader etc., and do drop me a line on &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;tim@timwise.co.uk&lt;&#x2F;a&gt; just so I know you&#x27;re out there!&lt;&#x2F;p&gt;
&lt;p&gt;The original of the header is a photo I took myself which you can find on flickr: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;17111067690&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;17111067690&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>javascript dates in firefox and locales</title>
        <published>2016-09-27T07:31:00.002+00:00</published>
        <updated>2016-09-27T07:31:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2016/09/27/javascript-dates-in-firefox-and-locales/"/>
        <id>https://0x5.uk/2016/09/27/javascript-dates-in-firefox-and-locales/</id>
        
        <content type="html" xml:base="https://0x5.uk/2016/09/27/javascript-dates-in-firefox-and-locales/">&lt;p&gt;Today I learnt:&lt;&#x2F;p&gt;
&lt;p&gt;You actually have to reinstall firefox using a different download to get &lt;code&gt;new Date(dateString)&lt;&#x2F;code&gt; to use a different date format (i.e. non-US).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jqueryvalidation.org&#x2F;date-method&#x2F;&quot;&gt;https:&#x2F;&#x2F;jqueryvalidation.org&#x2F;date-method&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This method should not be used, since it relies on the &lt;code&gt;new Date&lt;&#x2F;code&gt;
constructor, which behaves very differently across browsers and locales. Use
&lt;code&gt;dateISO&lt;&#x2F;code&gt; instead or one of the locale specific methods (in localizations&#x2F;
and additional-methods.js).&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So if you&#x27;re using chocolatey or boxstarter like I am (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;608fb680bfc920f372ac&quot;&gt;my boxstarter
script&lt;&#x2F;a&gt;) you need to add
the locale flag:
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chocolatey.org&#x2F;packages&#x2F;firefox&quot;&gt;https:&#x2F;&#x2F;chocolatey.org&#x2F;packages&#x2F;firefox&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;choco install Firefox -packageParameters &quot;l=en-GB&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Reinstalling the package with &lt;code&gt;--force&lt;&#x2F;code&gt; is sufficient to change it.&lt;&#x2F;p&gt;
&lt;p&gt;It would seem chrome has no way change the format from &lt;code&gt;en-US&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To be clear the correct solution is to do as the documentation says and not use
that method, however it&#x27;s a bit mean having a pitfall like that in the API. And
sometimes you just have to work with the code you have...&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Yet another good-commit-messages post</title>
        <published>2016-03-18T15:25:00+00:00</published>
        <updated>2016-03-18T15:25:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2016/03/18/yet-another-good-commit-messages-post/"/>
        <id>https://0x5.uk/2016/03/18/yet-another-good-commit-messages-post/</id>
        
        <content type="html" xml:base="https://0x5.uk/2016/03/18/yet-another-good-commit-messages-post/">&lt;h2 id=&quot;why-you-should-care-about-writing-good-commit-messages&quot;&gt;Why you should care about writing good commit messages&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;It is extremely likely you won&#x27;t be the last person to touch this code.&lt;&#x2F;li&gt;
&lt;li&gt;You will forget the details of exactly why you did something after a few weeks&#x2F;months&#x2F;years. Be kind to your future self.&lt;&#x2F;li&gt;
&lt;li&gt;Source control systems out-last [access to] ticket trackers by many years (Jira, Github-projects, Trello boards, etc. etc., how many have you seen in your time working on code? A lot more than you&#x27;ve seen source control systems I&#x27;ll wager.) A link to a ticket is not enough. Copy the relevant context from the ticket into the commit message.&lt;&#x2F;li&gt;
&lt;li&gt;Not everything can be deduced from the code. Even with excellent variable&#x2F;function&#x2F;class&#x2F;module names, and beautiful refactoring, the circumstances that let to a particular design or change are lost. Good comments adding context help, but sometimes you don&#x27;t want to clutter code with temporally relevant comments; the source control gives you a suitable place to keep this information locked up with your patch of the day.&lt;&#x2F;li&gt;
&lt;li&gt;When someone wants to know if they can delete a line of code in the future, if they can&#x27;t fathom why it was put there then the only way to find out is to delete it and see what breaks. By adding context in a commit message they can use the source-control history to get that context, and then decide whether that context is still applicable.&lt;&#x2F;li&gt;
&lt;li&gt;You might think your code is perfect and correct and needs no explanation beyond the code itself; but what if there&#x27;s a bug? Now the only documentation is the buggy code. If I come to fix your code later how do I know what it was supposed to do without going back to first principles. What algorithm or design pattern were you trying to implement? What references did you use?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thoughtbot.com&#x2F;blog&#x2F;chestertons-fence&quot;&gt;Chesterton&#x27;s Fence&lt;&#x2F;a&gt; - understand why something is the way it is before you change it.&lt;&#x2F;li&gt;
&lt;li&gt;And finally, I have seen &lt;em&gt;first hand&lt;&#x2F;em&gt; developers being &lt;strong&gt;judged in their absence&lt;&#x2F;strong&gt;, on the quality of their git logs. For example when deciding whether to let someone go who is considered sub-standard for the team, the principal engineer and an engineering manager might go over the individual&#x27;s output in private, without that individual present, to collect some evidence and inform their final decision. Do you want that to be you? Honestly, that &quot;wip&quot; commit with your name &amp;amp; email on it that seemed so harmless at the time doesn&#x27;t look so good now it&#x27;s out of context of whatever rush &#x2F; justification there seemed to be in the moment. Worse still if you make a regular habit of lazy &#x2F; rushed &#x2F; incoherent commits.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Write every commit message like the next person who reads it is an axe-wielding maniac who knows where you live&quot; ~ unknown&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;why-the-business-owner-cares-about-good-commit-messages&quot;&gt;Why the business owner cares about good commit messages&lt;&#x2F;h2&gt;
&lt;p&gt;(Even if they don&#x27;t know it)&lt;&#x2F;p&gt;
&lt;p&gt;Developers writing high-quality commit and pull request (PR) messages provides clear context and explains the &quot;why&quot; behind changes, directly impacting the clarity and long-term value of the codebase as an asset.&lt;&#x2F;p&gt;
&lt;p&gt;Well-crafted messages ensure that future developers, including new hires, can quickly understand the rationale behind decisions, saving time, reducing the cost of onboarding and reducing the risk of misinterpretations that could lead to costly errors.&lt;&#x2F;p&gt;
&lt;p&gt;They support smoother collaboration across teams, foster accountability, and create a historical record that aids in audits, troubleshooting, and strategic decision-making.&lt;&#x2F;p&gt;
&lt;p&gt;This practice minimizes the risk of long-term inefficiencies, speeds up development, and ensures technical work aligns with broader business objectives.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-i-care-about-good-commit-messages&quot;&gt;Why I care about good commit messages&lt;&#x2F;h2&gt;
&lt;p&gt;For reasons of chance I&#x27;ve ended up more than once maintaining and extending things created by other people, many of whom had moved on from the projects and were no longer contactable.&lt;&#x2F;p&gt;
&lt;p&gt;When dealing with a piece of code that has a behaviour that is clearly causing problems for users&#x2F;customers etc. sometimes I have needed to understand &lt;em&gt;why&lt;&#x2F;em&gt; it was that way before I could know whether it could be changed without creating even bigger problems.&lt;&#x2F;p&gt;
&lt;p&gt;Another example was a buggy and complex algorithm implementation, but no clue left as to what the algorithm being implemented was, as a result a week of reverse-engineering the maths happened that could have been saved with a simple &quot;this is an implementation of ...&quot; with a hyperlink or algorithm name.&lt;&#x2F;p&gt;
&lt;p&gt;With the author of the code not available to ask I&#x27;m left only with the source code and &lt;code&gt;git blame&lt;&#x2F;code&gt; to fathom why it&#x27;s like that.&lt;&#x2F;p&gt;
&lt;p&gt;When you find the commit that added the patch and it&#x27;s one of the following then you realise the author was not taking into account future maintainers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;wip&quot;&lt;&#x2F;li&gt;
&lt;li&gt;an entire fully formed set of behaviour appears in one giant commit with no explanation (perhaps copied from somewhere else)&lt;&#x2F;li&gt;
&lt;li&gt;a mention of a ticket number from a defunct ticket tracker with no further explanation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It seems to me that it doesn&#x27;t take much additional effort to rattle out a sentence or two with some context on why something is being changed for the benefit of future maintainers. Especially when it&#x27;s a complex patch that maybe took more than a day to create.&lt;&#x2F;p&gt;
&lt;p&gt;Given that each line of code is read many more times than it is written it seems that being &quot;lazy&quot; with explanation is not delivering the highest quality output to your client&#x2F;employer&#x2F;project.&lt;&#x2F;p&gt;
&lt;p&gt;I, like many developers, also value speed of delivery, fast iteration, early prototypes that may get rewritten; but you can still move fast while taking a few minutes for each patch to explain it. And you have to think that just because you might throw this one away, you also might not, and you just don&#x27;t know yet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-good-commit-pull-requests-matter-in-commercial-delivery&quot;&gt;Why good commit &#x2F; pull-requests matter in commercial delivery&lt;&#x2F;h2&gt;
&lt;p&gt;I often run into the objection of &quot;we don&#x27;t have time for polishing git logs&quot; in the context of commercial projects where time is money.&lt;&#x2F;p&gt;
&lt;p&gt;In commercial delivery teams good commits and pull requests are every bit as important. High quality commits &amp;amp; pull requests result in faster and more effective peer review, with less risk of missing important problems.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Clear intent (i.e. &quot;why this change now&quot;) reduces review time. - Reviewers don’t have to reverse-engineer the purpose of the change, they can validate correctness quickly instead of spending time guessing.&lt;&#x2F;li&gt;
&lt;li&gt;Small, single-purpose commits isolate risk. - When refactors and behaviour changes are separated, reviewers can approve mechanical changes quickly and focus attention only where logic actually changed.&lt;&#x2F;li&gt;
&lt;li&gt;Descriptive messages enable reliable approval &#x2F; sign-off. - A reviewer can confidently understand and confirm that &quot;this change does X to solve Y&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Readable history accelerates future fixes. - When something later breaks or needs extension, engineers can locate the exact change and rationale quickly, shortening incident resolution and feature lead time.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Well-structured commits are a throughput optimization: they reduce review latency, improve the chances of catching problems early and shorten future debugging time - all of which speeds up the delivery of value rather than slowing it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pull-request-descriptions-matter-too&quot;&gt;Pull request descriptions matter too&lt;&#x2F;h2&gt;
&lt;p&gt;It is common to ensure peer review by way of &quot;pull requests&quot;. Pull request descriptions are a lot like commit messages - they are used to describe to another human the contents of change to the codebase.&lt;&#x2F;p&gt;
&lt;p&gt;As such the pull request descriptions perform largely the same function as commit messages, and should follow the same guidelines laid out here for the same reasons.&lt;&#x2F;p&gt;
&lt;p&gt;In the hierarchy of longevity and accessibility they sit between ticketing systems and git commits. Git logs will likely outlive both pull requests and tickets.&lt;&#x2F;p&gt;
&lt;p&gt;If you make an effort to make the git commits contain sufficient context for the reader of a patch then it&#x27;s often useful to copy-paste that information into the pull request description, tidy it up for the reader and a bit more context such as screenshots.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-make-them-better&quot;&gt;How to make them better&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s not much for me to add on what&#x27;s already been written, so read these articles on the specifics of writing good commit messages.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3580013&#x2F;should-i-use-past-or-present-tense-in-git-commit-messages&#x2F;3580764#3580764&quot;&gt;Use the present-tense imperative&lt;&#x2F;a&gt; (&quot;Add …&quot; not &quot;Adds&quot; or &quot;Added&quot;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vip.wordpress.com&#x2F;documentation&#x2F;commit-messages&#x2F;&quot;&gt;https:&#x2F;&#x2F;vip.wordpress.com&#x2F;documentation&#x2F;commit-messages&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;robots.thoughtbot.com&#x2F;5-useful-tips-for-a-better-commit-message&quot;&gt;https:&#x2F;&#x2F;robots.thoughtbot.com&#x2F;5-useful-tips-for-a-better-commit-message&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;chris.beams.io&#x2F;posts&#x2F;git-commit&#x2F;&quot;&gt;http:&#x2F;&#x2F;chris.beams.io&#x2F;posts&#x2F;git-commit&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gds-way.cloudapps.digital&#x2F;standards&#x2F;git.html&quot;&gt;https:&#x2F;&#x2F;gds-way.cloudapps.digital&#x2F;standards&#x2F;git.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mislav.net&#x2F;2014&#x2F;02&#x2F;hidden-documentation&#x2F;&quot;&gt;https:&#x2F;&#x2F;mislav.net&#x2F;2014&#x2F;02&#x2F;hidden-documentation&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;mikepea&#x2F;863f63d6e37281e329f8&quot;&gt;Pull Request Etiquette gist by mikepea&lt;&#x2F;a&gt; - covers pull request quality as well as individual commits&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;My personal additions to this list:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A list of highlights of changes in bullets is often nice to add, think of it as a tourist&#x27;s guide to your patch. It makes it easier to spot the key changes in a large diff, and can make code-reviews more effective.&lt;&#x2F;li&gt;
&lt;li&gt;Hard-wrapping lines shouldn&#x27;t be required, that should be an editor&#x2F;display concern but unfortunately the git tooling doesn&#x27;t agree so doesn&#x27;t wrap anything so you might have to hard-wrap.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;are-you-expecting-every-tiny-change-to-be-like-this&quot;&gt;Are you expecting every tiny change to be like this?&lt;&#x2F;h2&gt;
&lt;p&gt;No. Some patches really don&#x27;t need much explaining, e.g. re-applying default code formatting or fixing a typo; but you should always consider what context a future reader might need.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;are-your-patches-atomic-incremental-improvements&quot;&gt;Are your patches atomic incremental improvements&lt;&#x2F;h2&gt;
&lt;p&gt;If it&#x27;s hard to write a good message, it might be that you are not taking the time to craft good single-purpose commits.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;examples-of-good&quot;&gt;Examples of good&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.kernel.org&#x2F;pub&#x2F;scm&#x2F;linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git&#x2F;commit&#x2F;?id=f076ef44a44d02ed91543f820c14c2c7dff53716&quot;&gt;https:&#x2F;&#x2F;git.kernel.org&#x2F;pub&#x2F;scm&#x2F;linux&#x2F;kernel&#x2F;git&#x2F;torvalds&#x2F;linux.git&#x2F;commit&#x2F;?id=f076ef44a44d02ed91543f820c14c2c7dff53716&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;linux&#x2F;comments&#x2F;3y6st0&#x2F;funny_commit_message_in_kernel&#x2F;&quot;&gt;via reddit&lt;&#x2F;a&gt;) - what I like about this one is:
&lt;ul&gt;
&lt;li&gt;It adds &lt;strong&gt;context&lt;&#x2F;strong&gt; that you could never get from code (note some is repeatedly more briefly in code comments which is a good thing)&lt;&#x2F;li&gt;
&lt;li&gt;It explains the new behaviour &lt;strong&gt;in human terms&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s easy to read (good quality English prose)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DFE-Digital&#x2F;find-teacher-training&#x2F;pull&#x2F;159&#x2F;commits&#x2F;00e24dbc216836dd73281688491b8da355706d81&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;DFE-Digital&#x2F;find-teacher-training&#x2F;pull&#x2F;159&#x2F;commits&#x2F;00e24dbc216836dd73281688491b8da355706d81&lt;&#x2F;a&gt; - what I like about this one is:
&lt;ul&gt;
&lt;li&gt;It&#x27;s part of a PR that is also well described &amp;amp; reviewed&lt;&#x2F;li&gt;
&lt;li&gt;It adds context (about the thing that will call the endpoint added in the patch, i.e .the reason it was created)&lt;&#x2F;li&gt;
&lt;li&gt;It mentions a PR in another repo that was a source for some of the code &amp;amp; ideas, yet more context for answering the question &quot;why was this done and why is it like this?&quot;&lt;&#x2F;li&gt;
&lt;li&gt;The co-author is attributed (github shows this which is nice), this might give you someone to talk to about if they&#x27;re still around&lt;&#x2F;li&gt;
&lt;li&gt;It provides an outline of the patch so you don&#x27;t have to parse the whole diff to get a flavour of how the patch changes behaviour. When you have a lot of patches to read because you&#x27;re looking for something in the history this can be a big timesaver.&lt;&#x2F;li&gt;
&lt;li&gt;It gives insight into why certain decisions were made about the final shape of the patch (e.g. why just &#x2F;healthcheck and not &#x2F;ping as well)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;video-presentations-on-why-good-history-matters&quot;&gt;Video presentations on why good history matters&lt;&#x2F;h2&gt;
&lt;p&gt;Remember, your code and your commits can last a veeeeeery long time and you never know what poor soul will have to understand what you did and why years later... when you have time watch this video:&lt;&#x2F;p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;1NoNTqank_U&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;G45hqWNScvE&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;h2 id=&quot;adding-adrs&quot;&gt;Adding ADRs&lt;&#x2F;h2&gt;
&lt;p&gt;Documenting broader reasons can be done with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;npryce&#x2F;adr-tools&#x2F;tree&#x2F;master?tab=readme-ov-file&quot;&gt;ADR&lt;&#x2F;a&gt;s (Architecture Decision Records, i.e. why we did this and not that), &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;olzzio&#x2F;y-statements-10eb07b5a177&quot;&gt;Y-ADRs&lt;&#x2F;a&gt; (basically highly condensed one-liner ADRs), readme files etc., ideally in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;timwise.co.uk&#x2F;2023&#x2F;06&#x2F;01&#x2F;text-based-tools-the-ultimate-format-for-everything&#x2F;&quot;&gt;ascii&lt;&#x2F;a&gt;, and even more ideally in the same commit so that a &lt;code&gt;git blame&lt;&#x2F;code&gt; will lead the future reader to find the additional reasoning right there in the same patch as the change to the code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;learning-more-about-git&quot;&gt;Learning more about git&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=nr0u3R3kVrI&quot;&gt;NDC Talk: &quot;git beyond pull &amp;amp; push&quot; - Jørgen Kvalsvik - NDC TechTown 2023&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Starting up a startup</title>
        <published>2015-12-24T18:06:00.002+00:00</published>
        <updated>2015-12-24T18:06:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2015/12/24/starting-up-startup/"/>
        <id>https://0x5.uk/2015/12/24/starting-up-startup/</id>
        
        <content type="html" xml:base="https://0x5.uk/2015/12/24/starting-up-startup/">&lt;p&gt;I&#x27;ve been contracting for 3 years now, which fits nicely with my drive to have real customers and build business(es). But I still have an itch. I&#x27;ve now found something to scratch that itch (taking the metaphor too far, sorry about that).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m going to write about my latest adventure here, from the perspective of me as a coder who&#x27;s aspiring to be an entrepreneur, so if you&#x27;re interested in my personal journey on this then do add my blog to your rss reader etc. of choice. I&#x27;ll try and tag them all with startup so you can filter if you aren&#x27;t interested in my other ramblings :-)&lt;&#x2F;p&gt;
&lt;p&gt;This post tells the story how I got involved in this startup, and some of the technical choices made so far and what we have in place already.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;So here&#x27;s how it started for me:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I found out via twitter that the the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.startupbritain.org&#x2F;bus-tour&quot;&gt;startup britain bus&lt;&#x2F;a&gt; was coming to Reading, so I went to say hi. They were a friendly crowd, and whilst there I found out that there&#x27;s actually a new startup group in the area called &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.connecttvt.co.uk&#x2F;&quot;&gt;ConnectTVT&lt;&#x2F;a&gt; associated with the new co-working space called &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;growgreenpark.co.uk&#x2F;&quot;&gt;grow@greenpark&lt;&#x2F;a&gt; over in green park just off M4 J11. That beats traipsing into the big smoke for me and is just the kind of melting pot I&#x27;ve been looking for. I know plenty of tech folks given that I&#x27;m a professional coder, but it doesn&#x27;t seem sensible for me to start a business with people with the same skills and the same blindspots as me. None of my &quot;normal&quot; friends seem to have the same entrepreneurial itch that I do; I needed a broader pool. I went straight from the bus to grow to check it out and met some more lovely friendly people. A few weeks later (I think) I went back again for one of their startup grinds to see what was going on. There was a small group of interesting people with diverse interests and talents, from accountants to designers and a few tech folk. One of the people there, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;somelivingroom.blogspot.co.uk&#x2F;&quot;&gt;Richard&lt;&#x2F;a&gt;, had an elevator pitch for a new take on the property market which made some sense to me and seemed well received by the group. All the people there offered their various advice and help. Richard has had experience in the property market that&#x27;s led him to this insight and having mulled over the idea for quite some time was interested in how this concept might become something more real. Lacking the tech background to just go and build it himself he was interested in what kind of scale of task this might be and how to find people who could help. I offered to provide advice any time and passed Richard my contact details. I didn&#x27;t at that point have any plans to get further involved.&lt;&#x2F;p&gt;
&lt;p&gt;I very much enjoyed meeting everyone, and went home with a head full of ideas and inspiration. I found myself still thinking it all through in the small hours that night, regularly grabbing my phone to make yet another note on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;trello.com&#x2F;&quot;&gt;trello&lt;&#x2F;a&gt; app detailing some idea about this property thing and how it could work, how you might get over the network-effect bump etc. Clearly this wasn&#x27;t going away. So I messaged &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;louize&quot;&gt;Louize&lt;&#x2F;a&gt; who runs the meetup to get in contact with Richard and said it had been keeping me awake with ideas, and she got us in contact again.&lt;&#x2F;p&gt;
&lt;p&gt;After mulling the whole thing over for a bit longer, it occurred to me that there is no reason I couldn&#x27;t do more than just provide advice, and maybe I should offer to provide a more concrete involvement. After all, I think the idea is great, and it&#x27;s not like I&#x27;m busy making any of my other ideas I have into businesses yet. Richard would certainly be much better able to build at a much lower financial risk with a technical co-founder. So after a load more discussions around the idea, the odd trip to the pub and some discussions around practical arrangements that is now what we are doing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;How&#x27;s it going?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first thing has been to really understand Richard&#x27;s vision, this has mostly involved talking lots. I set up a trello board for the startup, and that&#x27;s been great for doing a brain dump of all the ideas and todos, and getting them into some sort of organisation, then moving them into &quot;do later&quot; or &quot;needed for launch&quot; kind of groupings. I&#x27;ve also pointed Richard at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;balsamiq.com&#x2F;products&#x2F;mockups&#x2F;&quot;&gt;balsamiq mockups&lt;&#x2F;a&gt;, which these days has a slick web based editor and presentation mode. I&#x27;ve used it in the past to great effect when helping stakeholders in other projects understand what they&#x27;re really likely to get before all the expense of building the wrong thing. In this startup it&#x27;s already been really useful for hashing out ideas of how the site might work and even for getting reactions and insight by way of putting it in front of people and seeing if they understand the concept and how you would use it if it were a real thing already. Inspiration for this process is taken from the excellent book &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Dont-Make-Think-Revisited-Usability&#x2F;dp&#x2F;0321965515&quot;&gt;Don&#x27;t Make Me Think&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Hosting choices...&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In terms of building something real, Richard bought a domain, so we have somewhere to put it. I spent forever over &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.commitstrip.com&#x2F;en&#x2F;2015&#x2F;12&#x2F;09&#x2F;this-language-sucks&#x2F;&quot;&gt;technical choices&lt;&#x2F;a&gt; because basically you &lt;em&gt;could&lt;&#x2F;em&gt; use just about any technology stack, any programming language, cloud PaaS, IaaS or private servers etc. and in fact they would all work. There&#x27;s actually nothing to completely rule out anything. Some great things have been built on top of apparently terrible technical choices (wordpress is lovely but php that it&#x27;s built with is known for being buggy and hacky). There&#x27;s much stock put in &quot;cloud&quot; these days, and it does have benefits such as infinite scalability (of your wallet), but it comes with an overhead of complexity and potentially vendor lockin (though that like everything can be mitigated). So call me a luddite but I&#x27;ve gone for an old fashioned linux VPS (virtual private server) where I can easily put a ceiling on costs till we have an income. Unlike so many modern startups that rely on farming people with free shiny stuff until they have enough they can magically make money off the back of them, burning VC cash all the while in the name of profitless growth, we&#x27;re going to provide users with value, and charge them appropriately for that value, which naturally puts the brakes on the kind of explosive growth of free users that can overwhelm an ambitious startup&#x27;s site. So I&#x27;ve made a decision at last, hunted around for a provider I could trust and bought some hosting. There&#x27;s a lot to choose from so I needed a way to narrow down the field, especially given there&#x27;s a lot of not very good and not very well supported VPS offerings out there. I thought there might be an advert in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linuxvoice.com&#x2F;&quot;&gt;Linux Voice&lt;&#x2F;a&gt; magazine, which is where I found my uber-geeky ISP &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;aa.net.uk&#x2F;&quot;&gt;A&amp;amp;A&lt;&#x2F;a&gt; (check out the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.revk.uk&#x2F;&quot;&gt;boss&#x27;s blog&lt;&#x2F;a&gt; if you want to know how far that rabbit hole goes), but there weren&#x27;t any. So I hopped on #linuxvoice on freenode irc and asked in there, and sure enough the good folks at the mag said they&#x27;d been using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bytemark.co.uk&#x2F;&quot;&gt;bytemark&lt;&#x2F;a&gt; and had been happy with their support. Sold.&lt;&#x2F;p&gt;
&lt;p&gt;So I bought bytemark&#x27;s basic VPS offering, and now have a server on the internet that I can point everything at and run everything we need on no matter how quirky the needs. While we have a manageable number of users this should suffice, we&#x27;re not planning any multi-million pound TV adverts any time soon. I expect if we&#x27;re successful we&#x27;ll have growing pains no matter what platform we&#x27;re using, it&#x27;s non-trivial to scale even if you&#x27;re on a so-called scalable platform in the first place. There&#x27;s lots of gotchas, unexpected interactions and bottlenecks in any system as it grows.&lt;&#x2F;p&gt;
&lt;p&gt;If it sounds like I&#x27;m trying to rationalise my decision that&#x27;s because I am, I&#x27;m aware that whatever technical (and even non-technical) decisions are made at this earliest of early stages have rippling effects that are hard to reverse once you build more on top of them. However equally no matter which choices you make, none of them are truly irreversible, and there are myriad ways of tackling any of the problems that come your way in time. I&#x27;ve had the privilege of seeing teams that are running decent scale operations in both .net and ruby on rails, which are two very different platforms with different cultures and different sets of problems, but interestingly the difference in the overall scale of the challenge and how easy it is to get things done in the long haul was not noticeably different as far as I could tell.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Mailing lists and landing pages:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first goal is to have a way to let interested people know when we&#x27;ve got things to show them, tell them the story, and when we need their help. That means a mailing list. Bulk email isn&#x27;t for the feint hearted these days in the modern world of aggressive spam filters, SPF (no not sunblock), domain keys and increasingly rigid legal constraints as we try to fight outright spam on the wild west of the internet so I don&#x27;t fancy doing it all myself. My go-to service for this is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;mailchimp.com&#x2F;&quot;&gt;mailchimp&lt;&#x2F;a&gt;, and I haven&#x27;t been disappointed. But for this to work we need an email address, and that means MX records and pointing it at some mailserver somewhere. I did look into gmail as a possible shared mailbox but it doesn&#x27;t seem to do what we&#x27;re after, so now I have a server running anyway I can just use that. No artificial limits, no snooping, no unwanted advertising.&lt;&#x2F;p&gt;
&lt;p&gt;It turns out that bytemark provide a very nice customised build of debian called &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;symbiosis.bytemark.co.uk&#x2F;&quot;&gt;symbiosis&lt;&#x2F;a&gt;, which has a bunch of useful services already installed, and a watchdog service that&#x27;ll restart anything that&#x27;s fallen over. Nice! It didn&#x27;t take me much fiddling to get the basic web hosting to behave and get an email account on it set up. I then used the domain control panel to point the A &amp;amp; MX records at our shiny new server (by way of a bit of chaining of CNAMES which will be slightly slower for the first lookup but will be easier to maintain). I then had to redo the web and mail hosting because I hadn&#x27;t realised that bytemark had made the server do multiple domain hosting using a neat folder based system, but that didn&#x27;t take too long and it&#x27;s all good learning time without customers breathing down one&#x27;s neck!&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve now done a rudimentary holding page for the domain, with a sign-up form for the mailing list, which was goal number one. You can see it here: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.xchain.co.uk&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.xchain.co.uk&#x2F;&lt;&#x2F;a&gt;. If you&#x27;re interested in the concept or progress then please do sign up to the mailing list. It&#x27;s easy to unsubscribe if you get bored of it ;-)&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve added &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.google.com&#x2F;analytics&#x2F;&quot;&gt;google analytics&lt;&#x2F;a&gt; to the site, which is very useful albeit slightly evil, so at least we&#x27;ll have some idea if it&#x27;s getting any traction as we start to spread the word (taking all stats on the internet as extremely approximate of course). I might switch to one of the more libre solutions at some point but that would require a bit more time and this is after-all a commercial venture and not an open source project. Much as I like working on open source for the greater good, I haven&#x27;t yet managed to make it pay the bills. I think it&#x27;s important to have metrics for a startup so you can tell if what you&#x27;re doing to spread the word is actually having any effect, and what might be putting off potential customers.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve sent out a mailing or two to the few people we&#x27;ve got signed up at this early stage (hello mum!) as much for practice as anything, and I&#x27;m impressed with mailchimp&#x27;s collaborative capabilities and previewing system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Tech stack&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You may have noticed I still haven&#x27;t entirely picked a stack, nothing I have so far has locked me in to a decision. I don&#x27;t want to be paying for or locked in to Microsoft&#x27;s world (and the associated treadmill of change), so although I do their stuff for a living I don&#x27;t want to tie my own startup to them, so that&#x27;s out. I&#x27;d prefer an open source stack as I think it matters whether you enjoy working on the platform you&#x27;ve chosen, and open source is just so much nicer to work with as a coder &#x2F; dev-ops. Currently I&#x27;m thinking a golang based server, backed with postgresql (the industry&#x27;s finest database) serving up a JSON&#x2F;REST API to an AngularJS + Foundation frontend. This gives us scope to rework the different parts as needed, and to bolt on dedicated mobile apps later.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Web design&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s no design in the current holding page as I am no designer (frustratingly, but that&#x27;s a whole other career path), and we&#x27;re still working out how to pull design talent into the whole shebang in a sustainable way. Richard has put me onto &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;webflow.com&#x2F;&quot;&gt;webflow&lt;&#x2F;a&gt;, which maybe will get us started.&lt;&#x2F;p&gt;
&lt;p&gt;My first learning of trying to find a freelance designer was that I need a &quot;web designer&quot; not just a &quot;designer&quot;, being from the web world I hadn&#x27;t appreciated the importance of the prefix and attracted all the wrong people.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Further reading...&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Having this startup has encouraged me to broaden my reading and listening habits further. Here&#x27;s some of things I&#x27;ve been catching up with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;jwG_qR6XmDQ&quot;&gt;Regret minimization vid&lt;&#x2F;a&gt; - inspiration from Bezos&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bloomberg.com&#x2F;graphics&#x2F;2015-paul-ford-what-is-code&#x2F;&quot;&gt;What is code&lt;&#x2F;a&gt; - explains what I do to the non-coders&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;hanselminutes.com&#x2F;506&#x2F;todays-startup-accelerators-john-henry-from-cofound-harlem&quot;&gt;HanselMinutes - Startup Accelerators&lt;&#x2F;a&gt; - a timely podcast show&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wpcurve.com&#x2F;startupchat&#x2F;&quot;&gt;Startup Chat podcast&lt;&#x2F;a&gt; from WPCurve&lt;&#x2F;li&gt;
&lt;li&gt;Last year&#x27;s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.entrepreneur.com&#x2F;article&#x2F;241085&quot;&gt;startup resolutions&lt;&#x2F;a&gt; via the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;workinstartups.com&#x2F;&quot;&gt;work in startups&lt;&#x2F;a&gt; mailing list&lt;&#x2F;li&gt;
&lt;li&gt;Everything in &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;leanstack.com&#x2F;blog&#x2F;&quot;&gt;LeanStack&#x27;s blog&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;--&lt;&#x2F;p&gt;
&lt;p&gt;Please do drop me a line if you found this interesting in any way. &lt;a href=&quot;mailto:tim@timwise.co.uk&quot;&gt;tim@timwise.co.uk&lt;&#x2F;a&gt; works best for me.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sql Data Viewer - preview release</title>
        <published>2015-10-27T14:45:00+00:00</published>
        <updated>2015-10-27T14:45:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2015/10/27/sql-data-viewer-preview-release/"/>
        <id>https://0x5.uk/2015/10/27/sql-data-viewer-preview-release/</id>
        
        <content type="html" xml:base="https://0x5.uk/2015/10/27/sql-data-viewer-preview-release/">&lt;p&gt;Hello dear readers,&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve started working on a data brower for relational databases that allows you to click through ids with foreign-keys to get around.&lt;&#x2F;p&gt;
&lt;p&gt;Take a look at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;sdv&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;sdv&#x2F;&lt;&#x2F;a&gt; and if you think you might be interested then please do sign up to my &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eepurl.com&#x2F;bDGPjf&quot;&gt;mailing list&lt;&#x2F;a&gt;, and let me know if you have any feedback.&lt;&#x2F;p&gt;
&lt;p&gt;This started as a holiday exercise in learning google&#x27;s go programming language, but is intended to become a fully-fledged software product available to buy.&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>100 reasons I hate ssrs</title>
        <published>2015-08-12T19:01:00.004+00:00</published>
        <updated>2015-08-12T19:01:00.004+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2015/08/12/100-reasons-i-hate-ssrs/"/>
        <id>https://0x5.uk/2015/08/12/100-reasons-i-hate-ssrs/</id>
        
        <content type="html" xml:base="https://0x5.uk/2015/08/12/100-reasons-i-hate-ssrs/">&lt;p&gt;&lt;em&gt;Originally posted at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;timwise.blogspot.com&#x2F;2015&#x2F;08&#x2F;100-reasons-i-hate-ssrs.html&quot;&gt;https:&#x2F;&#x2F;timwise.blogspot.com&#x2F;2015&#x2F;08&#x2F;100-reasons-i-hate-ssrs.html&lt;&#x2F;a&gt; which attracted some great comments.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A slightly tongue-in cheek hit-list of nasty things and vague hand-waving
opinions on what makes microsoft&#x27;s sql server reporting services (ssrs) such a
pig to work with.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t really know of anything better so this is mostly just pointless
ranting; but I&#x27;ll justify it to myself by saying at least you&#x27;ll know what
you&#x27;re getting into if you&#x27;ve read this before you start. SSRS seems to be more
&quot;death by one thousand paper cuts&quot; than completely broken, so it&#x27;s not so easy
to say &quot;it&#x27;s shit, shalln&#x27;t use it&quot; like any good prima-donna developer would.
Sorry I mean rock-star (recruiter speak). It also offers a few features that
would be pretty hard to code from hand cost-effectively in something like
asp.net mvc, such as user editing, multiple export formats, scheduled emails,
and some of the ways you can cut-and-shut the data in the reports.&lt;&#x2F;p&gt;
&lt;p&gt;I make no apologies for the colourful language, it&#x27;s a representation of the
emotional side of having to use this heap of crap.&lt;&#x2F;p&gt;
&lt;p&gt;Some of these were contributed by in the comments (on blogger) after I posted
the original article. (Thanks, that was a nice surprise, and it&#x27;s nice to know
it&#x27;s not just me!)&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.allenkinsel.com&#x2F;archive&#x2F;2013&#x2F;01&#x2F;adventures-in-ssrs&quot;&gt;http:&#x2F;&#x2F;www.allenkinsel.com&#x2F;archive&#x2F;2013&#x2F;01&#x2F;adventures-in-ssrs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;doesn&#x27;t bind to a port like a normal fukcing service
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blogs.devhorizon.com&#x2F;reza&#x2F;2008&#x2F;10&#x2F;20&#x2F;say-goodbye-to-iis-say-hello-to-httpsys&#x2F;&quot;&gt;http:&#x2F;&#x2F;blogs.devhorizon.com&#x2F;reza&#x2F;2008&#x2F;10&#x2F;20&#x2F;say-goodbye-to-iis-say-hello-to-httpsys&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.iis.net&#x2F;learn&#x2F;get-started&#x2F;introduction-to-iis&#x2F;introduction-to-iis-architecture#Hypertext&quot;&gt;http:&#x2F;&#x2F;www.iis.net&#x2F;learn&#x2F;get-started&#x2F;introduction-to-iis&#x2F;introduction-to-iis-architecture#Hypertext&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;social.technet.microsoft.com&#x2F;Forums&#x2F;sqlserver&#x2F;en-US&#x2F;f2586aca-78fe-40d6-9bcd-5151bac7136f&#x2F;role-of-httpsys-in-ssrs-2008-?forum=sqlreportingservices&quot;&gt;https:&#x2F;&#x2F;social.technet.microsoft.com&#x2F;Forums&#x2F;sqlserver&#x2F;en-US&#x2F;f2586aca-78fe-40d6-9bcd-5151bac7136f&#x2F;role-of-httpsys-in-ssrs-2008-?forum=sqlreportingservices&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blogs.technet.com&#x2F;b&#x2F;andrew&#x2F;archive&#x2F;2007&#x2F;12&#x2F;04&#x2F;sql-server-2008-reporting-services-no-longer-depends-on-iis.aspx&quot;&gt;http:&#x2F;&#x2F;blogs.technet.com&#x2F;b&#x2F;andrew&#x2F;archive&#x2F;2007&#x2F;12&#x2F;04&#x2F;sql-server-2008-reporting-services-no-longer-depends-on-iis.aspx&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;http server api (aka http.sys)
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;aa364510%28VS.85%29.aspx?f=255&amp;amp;MSPPError=-2147217396&quot;&gt;https:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;aa364510%28VS.85%29.aspx?f=255&amp;amp;MSPPError=-2147217396&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;list reservations:
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;netsh http show urlacl&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;auth in reporting &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;ms152899.aspx&quot;&gt;https:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;ms152899.aspx&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;reports in VS
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;curah.microsoft.com&#x2F;22200&#x2F;create-ssrs-reports-using-visual-studio&quot;&gt;http:&#x2F;&#x2F;curah.microsoft.com&#x2F;22200&#x2F;create-ssrs-reports-using-visual-studio&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;ms173745.aspx&quot;&gt;https:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;ms173745.aspx&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Explicity add new role assingment for the account you are using and check every box in sight&quot; ~ a.n. colleague.  lol&lt;&#x2F;li&gt;
&lt;li&gt;ignore the .rdl.data files with git.
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3424928&#x2F;in-ssrs-is-there-a-way-to-disable-the-rdl-data-file-creation#3425429&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3424928&#x2F;in-ssrs-is-there-a-way-to-disable-the-rdl-data-file-creation#3425429&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;no folders.
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;connect.microsoft.com&#x2F;SQLServer&#x2F;feedback&#x2F;details&#x2F;487106&#x2F;allow-sub-folders-in-ssrs-projects&quot;&gt;https:&#x2F;&#x2F;connect.microsoft.com&#x2F;SQLServer&#x2F;feedback&#x2F;details&#x2F;487106&#x2F;allow-sub-folders-in-ssrs-projects&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3309002&#x2F;visual-studio-for-ssrs-2008-how-to-organize-reports-into-subfolders-in-solutio&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3309002&#x2F;visual-studio-for-ssrs-2008-how-to-organize-reports-into-subfolders-in-solutio&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;renamed a dataset, nothing fucking broke!!!!!!!!!!!!!!!!!!!!!!!!!!! even though there are reports that depend on it. On editing the report&#x27;s dataset list you can see clearly &quot;not found&quot;, but yet it still runs. what in the blazes is that all about?
&lt;ol&gt;
&lt;li&gt;caching in the report editor &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;q&#x2F;3424928&#x2F;10245&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;q&#x2F;3424928&#x2F;10245&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;kill the .data cache files &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3424928&#x2F;in-ssrs-is-there-a-way-to-disable-the-rdl-data-file-creation&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3424928&#x2F;in-ssrs-is-there-a-way-to-disable-the-rdl-data-file-creation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;git clean -xfd&lt;&#x2F;li&gt;
&lt;li&gt;fuck&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;social.msdn.microsoft.com&#x2F;Forums&#x2F;sqlserver&#x2F;en-US&#x2F;0aa81692-352f-4c1f-a0e3-95fe6c0797ca&#x2F;cachedataforpreview-in-rsreportdesignerconfig-not-honored&quot;&gt;https:&#x2F;&#x2F;social.msdn.microsoft.com&#x2F;Forums&#x2F;sqlserver&#x2F;en-US&#x2F;0aa81692-352f-4c1f-a0e3-95fe6c0797ca&#x2F;cachedataforpreview-in-rsreportdesignerconfig-not-honored&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;connect.microsoft.com&#x2F;SQLServer&#x2F;feedback&#x2F;details&#x2F;468482&quot;&gt;https:&#x2F;&#x2F;connect.microsoft.com&#x2F;SQLServer&#x2F;feedback&#x2F;details&#x2F;468482&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;it&#x27;s the &lt;code&gt;bin\&lt;&#x2F;code&gt; folder, not the .data files. Still, fuckkkk.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;to get from a report to a db you go, report &amp;gt; report dataset &amp;gt; shared dataset &amp;gt; db, but db is defined in the shared dataset with another name, which can be pointed to a shared data source, which is also named. and &lt;em&gt;that&lt;&#x2F;em&gt; data source actually has a connection string&lt;&#x2F;li&gt;
&lt;li&gt;committing to tfs failed half way through because vs had locked a bunch of files I didn&#x27;t even have open&lt;&#x2F;li&gt;
&lt;li&gt;found a param with &lt;code&gt;&amp;lt;Value&amp;gt;=Microsoft.VisualBasic.Strings.Join(Parameters!Stages.Label, &quot;, &quot;)&amp;lt;&#x2F;Value&amp;gt;&lt;&#x2F;code&gt; - wtf.&lt;&#x2F;li&gt;
&lt;li&gt;function overload matching warning wouldn&#x27;t go away till I closed the sln&lt;&#x2F;li&gt;
&lt;li&gt;localisation is a bitch
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;10953629&#x2F;how-to-change-ssrs-2008-locale&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;10953629&#x2F;how-to-change-ssrs-2008-locale&lt;&#x2F;a&gt; etc&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.ponytailbob.com&#x2F;2007&#x2F;10&#x2F;multi-language-tips-in-ssrs.html&quot;&gt;http:&#x2F;&#x2F;blog.ponytailbob.com&#x2F;2007&#x2F;10&#x2F;multi-language-tips-in-ssrs.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blogs.msdn.com&#x2F;b&#x2F;sriram_reddy1&#x2F;archive&#x2F;2012&#x2F;01&#x2F;09&#x2F;localization-in-ssrs-reports.aspx&quot;&gt;http:&#x2F;&#x2F;blogs.msdn.com&#x2F;b&#x2F;sriram_reddy1&#x2F;archive&#x2F;2012&#x2F;01&#x2F;09&#x2F;localization-in-ssrs-reports.aspx&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;support.microsoft.com&#x2F;en-gb&#x2F;kb&#x2F;919153&quot;&gt;https:&#x2F;&#x2F;support.microsoft.com&#x2F;en-gb&#x2F;kb&#x2F;919153&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.keepitsimpleandfast.com&#x2F;2011&#x2F;09&#x2F;localization-of-your-ssrs-reports.html&quot;&gt;http:&#x2F;&#x2F;www.keepitsimpleandfast.com&#x2F;2011&#x2F;09&#x2F;localization-of-your-ssrs-reports.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;why you no use User!Language??&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Visual Studio 2013 crashed. hard. while cancelling new report param&lt;&#x2F;li&gt;
&lt;li&gt;adds 00:00:00 to date fields from sql server. duuuuuuuuuuuuh (goes via .net datetime internally, but even so, not friendly)&lt;&#x2F;li&gt;
&lt;li&gt;changed date format, looks fine in VS, but no change in report server. wuh? deploy all&lt;&#x2F;li&gt;
&lt;li&gt;no auto-sizing of cols &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;7851045&#x2F;ssrs-tablix-column-cangrow-property-for-width&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;7851045&#x2F;ssrs-tablix-column-cangrow-property-for-width&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;no nulls in multi-value &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.keepitsimpleandfast.com&#x2F;2012&#x2F;03&#x2F;how-to-pass-null-value-to-multi-value.html&quot;&gt;http:&#x2F;&#x2F;www.keepitsimpleandfast.com&#x2F;2012&#x2F;03&#x2F;how-to-pass-null-value-to-multi-value.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;need dirty hack to show &quot;all&quot; rather than full list
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.mssqltips.com&#x2F;sqlservertip&#x2F;2844&#x2F;working-with-multiselect-parameters-for-ssrs-reports&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.mssqltips.com&#x2F;sqlservertip&#x2F;2844&#x2F;working-with-multiselect-parameters-for-ssrs-reports&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;12917261&#x2F;optional-multi-valued-parameters-in-ssrs&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;12917261&#x2F;optional-multi-valued-parameters-in-ssrs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bi-rootdata.com&#x2F;2012&#x2F;09&#x2F;efficient-way-of-using-all-as-parameter.html&quot;&gt;http:&#x2F;&#x2F;www.bi-rootdata.com&#x2F;2012&#x2F;09&#x2F;efficient-way-of-using-all-as-parameter.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.ponytailbob.com&#x2F;2007&#x2F;10&#x2F;2-shortcomings-of-multi-valued.html&quot;&gt;http:&#x2F;&#x2F;blog.ponytailbob.com&#x2F;2007&#x2F;10&#x2F;2-shortcomings-of-multi-valued.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;some fucking horror I&#x27;ve yet to encounter (querystrings) &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;512105&#x2F;passing-multiple-values-for-a-single-parameter-in-reporting-services&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;512105&#x2F;passing-multiple-values-for-a-single-parameter-in-reporting-services&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;it has a fucking canvas size that will push over to 2 pages&lt;&#x2F;li&gt;
&lt;li&gt;the font kerning on a print is massively different to on web &#x2F; design view&lt;&#x2F;li&gt;
&lt;li&gt;sorting
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;9254604&#x2F;why-does-my-sql-server-reporting-service-ssrs-report-appear-to-re-sort-the-d&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;9254604&#x2F;why-does-my-sql-server-reporting-service-ssrs-report-appear-to-re-sort-the-d&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index &quot; from editing xml. thanks for the error info. fuckkkkkers&lt;&#x2F;li&gt;
&lt;li&gt;the ssrs gui editor is a flaky piece of shit
&lt;ol&gt;
&lt;li&gt;doesn&#x27;t select the right fucking textbox in the props window&lt;&#x2F;li&gt;
&lt;li&gt;had to restart visual fuckigjn studio&lt;&#x2F;li&gt;
&lt;li&gt;grrr&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;the underlying xml is fucking horrific&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;rd:Selected&amp;gt;true&amp;lt;&#x2F;rd:Selected&amp;gt;&lt;&#x2F;code&gt; ----- what in the fucking blazes is that doing in there?&lt;&#x2F;li&gt;
&lt;li&gt;how do you deploy without connecting visual studio to production server? you fucking don&#x27;t hahahahahaa&lt;&#x2F;li&gt;
&lt;li&gt;powerhell &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;7e3019bd2de802f0b259&quot;&gt;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;7e3019bd2de802f0b259&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;ssbi install croaked - h&lt;a href=&quot;ttps:&#x2F;&#x2F;support.microsoft.com&#x2F;en-us&#x2F;kb&#x2F;2800050?wa=wsignin1.0&quot;&gt;ttps:&#x2F;&#x2F;support.microsoft.com&#x2F;en-us&#x2F;kb&#x2F;2800050?wa=wsignin1.0&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;[09:44:53] john doe: Tim can I have a &lt;code&gt;.bak&lt;&#x2F;code&gt; file of &lt;code&gt;ReportServer$MSSQL2012TempDB&lt;&#x2F;code&gt; which the stupid software seems to be unable to operate without even though it has &lt;strong&gt;Temp&lt;&#x2F;strong&gt; in the database name implying it will rebuild itself (at least that&#x27;s what it implies to me)
&lt;ol&gt;
&lt;li&gt;[09:47:48] Tim Abell: (facepalm)&lt;&#x2F;li&gt;
&lt;li&gt;[09:47:49] Tim Abell: sure&lt;&#x2F;li&gt;
&lt;li&gt;[09:48:08] Tim Abell: I did wonder, and then I thought, no they couldn&#x27;t possibly need that&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;dropdown doesn&#x27;t work in firefox&lt;&#x2F;li&gt;
&lt;li&gt;no debugging &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;14068447&#x2F;10245&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;14068447&#x2F;10245&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Warning : The text box ‘appliedFilters’ and the image ‘urLogo’ overlap. Overlapping report items are not supported in all renderers.&lt;&#x2F;li&gt;
&lt;li&gt;the only options for DRY in reports suck balls &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.3pillarglobal.com&#x2F;insights&#x2F;tips-tricks-ensure-consistency-sql-server-reporting-services-reports&quot;&gt;http:&#x2F;&#x2F;www.3pillarglobal.com&#x2F;insights&#x2F;tips-tricks-ensure-consistency-sql-server-reporting-services-reports&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;harmful.cat-v.org&#x2F;software&#x2F;xml&#x2F;&quot;&gt;http:&#x2F;&#x2F;harmful.cat-v.org&#x2F;software&#x2F;xml&#x2F;&lt;&#x2F;a&gt; xml is a terrible format anyway&lt;&#x2F;li&gt;
&lt;li&gt;layout is in inches&lt;&#x2F;li&gt;
&lt;li&gt;you can change the layout to cm&lt;&#x2F;li&gt;
&lt;li&gt;it stores different metrics (cm&#x2F;in) for each element, wtf, pick a unit&lt;&#x2F;li&gt;
&lt;li&gt;reflowing nicely is impossible&lt;&#x2F;li&gt;
&lt;li&gt;layout engine is as intelligent as a piece of paper and a pen. x,y is all you get.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.webapplicationsuk.com&#x2F;2010&#x2F;07&#x2F;word-html-renderer-ndash-the-road-to-hellhellip&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.webapplicationsuk.com&#x2F;2010&#x2F;07&#x2F;word-html-renderer-ndash-the-road-to-hellhellip&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;connect.microsoft.com&#x2F;SQLServer&#x2F;feedback&#x2F;details&#x2F;540183&#x2F;supported-rdl-object-model-rdlom&quot;&gt;https:&#x2F;&#x2F;connect.microsoft.com&#x2F;SQLServer&#x2F;feedback&#x2F;details&#x2F;540183&#x2F;supported-rdl-object-model-rdlom&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;this is the kind of bullshit that counts for helpful content on the net &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;social.msdn.microsoft.com&#x2F;Forums&#x2F;en-US&#x2F;86205ca4-13d0-4ca6-84f1-79797616f0f4&#x2F;exclude-null-values-from-sum-and-avg-calculation?forum=sqlreportingservices&quot;&gt;https:&#x2F;&#x2F;social.msdn.microsoft.com&#x2F;Forums&#x2F;en-US&#x2F;86205ca4-13d0-4ca6-84f1-79797616f0f4&#x2F;exclude-null-values-from-sum-and-avg-calculation?forum=sqlreportingservices&lt;&#x2F;a&gt; - &lt;code&gt;=sum(forum_format * quality_of_community)&lt;&#x2F;code&gt; = errorrrrrrrrr&lt;&#x2F;li&gt;
&lt;li&gt;multiple rdl xml schema in the same fucking project, completely different xml structure
&lt;ol&gt;
&lt;li&gt;2005 generated with &quot;new report wizard&quot; in VS 20-fucking-13: &lt;code&gt;&amp;lt;Report xmlns=&quot;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;sqlserver&#x2F;reporting&#x2F;2005&#x2F;01&#x2F;reportdefinition&quot; xmlns:rd=&quot;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;SQLServer&#x2F;reporting&#x2F;reportdesigner&quot;&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;2008 &lt;code&gt;&amp;lt;Report xmlns=&quot;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;sqlserver&#x2F;reporting&#x2F;2008&#x2F;01&#x2F;reportdefinition&quot; xmlns:rd=&quot;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;SQLServer&#x2F;reporting&#x2F;reportdesigner&quot;&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;2009 from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;technet.microsoft.com&#x2F;en-us&#x2F;library&#x2F;cc627465%28v=sql.105%29.aspx&quot;&gt;https:&#x2F;&#x2F;technet.microsoft.com&#x2F;en-us&#x2F;library&#x2F;cc627465%28v=sql.105%29.aspx&lt;&#x2F;a&gt; - &lt;code&gt;&amp;lt;Report xmlns:rd=http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;SQLServer&#x2F;reporting&#x2F;reportdesigner xmlns=&quot;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;sqlserver&#x2F;reporting&#x2F;2009&#x2F;01&#x2F;reportdefinition&quot;&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;2010 &lt;code&gt;&amp;lt;Report xmlns:rd=&quot;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;SQLServer&#x2F;reporting&#x2F;reportdesigner&quot; xmlns:cl=&quot;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;sqlserver&#x2F;reporting&#x2F;2010&#x2F;01&#x2F;componentdefinition&quot; xmlns=&quot;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;sqlserver&#x2F;reporting&#x2F;2010&#x2F;01&#x2F;reportdefinition&quot;&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;how many fucking versions??!&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;15539859&#x2F;what-is-the-difference-between-rdl-2008-schema-and-rdl-2010-schema-feature-wise&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;15539859&#x2F;what-is-the-difference-between-rdl-2008-schema-and-rdl-2010-schema-feature-wise&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;9974179&#x2F;is-there-a-new-version-of-rdl-schema-for-sql-server-2012-denali&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;9974179&#x2F;is-there-a-new-version-of-rdl-schema-for-sql-server-2012-denali&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;29951653&#x2F;ssrs-2008r2-visual-studio-2008-and-2008-and-2010-schemas&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;29951653&#x2F;ssrs-2008r2-visual-studio-2008-and-2008-and-2010-schemas&lt;&#x2F;a&gt; - how to not end up with old schema?!&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;social.msdn.microsoft.com&#x2F;Forums&#x2F;sqlserver&#x2F;en-US&#x2F;f4d14548-c592-4d8d-8185-ca683c421649&#x2F;2010-schema-with-visual-studio-2010?forum=sqlreportingservices&quot;&gt;https:&#x2F;&#x2F;social.msdn.microsoft.com&#x2F;Forums&#x2F;sqlserver&#x2F;en-US&#x2F;f4d14548-c592-4d8d-8185-ca683c421649&#x2F;2010-schema-with-visual-studio-2010?forum=sqlreportingservices&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;how do you upgrade a report schema? install a massive chunk of fucking sql server &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;13170608&#x2F;upgrade-my-rdlc-schema-from-2008-01-to-2010-01&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;13170608&#x2F;upgrade-my-rdlc-schema-from-2008-01-to-2010-01&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;[17:54:48] john doe: Btw have you noticed that in Print Layout view the header doesn&#x27;t expand if any of the textboxes have auto-grown? [17:55:14] Tim Abell: that&#x27;s because ssrs is a piece of shit from 1990 [17:55:28] Tim Abell: and it thinks A4 is the ultimate display format [17:55:47] Tim Abell: you just have to guess how much space you&#x27;ll need&lt;&#x2F;li&gt;
&lt;li&gt;the ordering of the xml in the proj file is unstable causing diff noise&lt;&#x2F;li&gt;
&lt;li&gt;subreports, icky &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;bhushan.extreme-advice.com&#x2F;subreport-in-ssrs&#x2F;&quot;&gt;http:&#x2F;&#x2F;bhushan.extreme-advice.com&#x2F;subreport-in-ssrs&#x2F;&lt;&#x2F;a&gt;
&lt;ol&gt;
&lt;li&gt;or nested tables &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;11335655&#x2F;filtering-nested-data-regions-in-ssrs&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;11335655&#x2F;filtering-nested-data-regions-in-ssrs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;some things can only be achieved with subreports, and they have to be deployed separately from the main report, meaning they can get out of sync. enjoy the fear of not knowing if you&#x27;ll break something else when you upload your new version of the subreport you depend on&lt;&#x2F;li&gt;
&lt;li&gt;no support for &quot;time&quot; data type &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3846378&#x2F;displaying-time-in-reporting-services-2008&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3846378&#x2F;displaying-time-in-reporting-services-2008&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The &quot;View Report&quot; button next to the parameters when running a report in VS is &lt;em&gt;always&lt;&#x2F;em&gt; greyed-out, even though it actually works.&lt;&#x2F;li&gt;
&lt;li&gt;wow that&#x27;s mental, hidden reports show in details view and not in tile view in the ssrs web ui&lt;&#x2F;li&gt;
&lt;li&gt;the report editor has a copy option for report items, but no paste, so you can&#x27;t duplicate reports
&lt;ol&gt;
&lt;li&gt;actually you can, but only if you know the keyboard shortcuts. 0_o - ctrl-c ctrl-v&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;duplicating a report on the filesystem, and then using &quot;add existing item&quot; to include it puts it at the end of the list... until you rename it and then it&#x27;s moved into alphabetical order causing a spurious diff. should have put in the right place in the first place. grr.&lt;&#x2F;li&gt;
&lt;li&gt;using the cursor keys to move textboxes around is so laggy that I overshoot every single time&lt;&#x2F;li&gt;
&lt;li&gt;the editor popups in visual studio are modal, so you can&#x27;t refer to anything else&lt;&#x2F;li&gt;
&lt;li&gt;and there&#x27;s no maximise button so you have to drag the fiddly border to make it bigger&lt;&#x2F;li&gt;
&lt;li&gt;the report editor hasn&#x27;t heard of ctrl-c or ctrl-v, have to use ctrl-Ins &#x2F; shift-Ins instead&lt;&#x2F;li&gt;
&lt;li&gt;border rendering &#x2F; precedence is a fucking mess. set some borders, your report will look like a two-year-old coloured it in, and how it looks changes depending on the zoom level.&lt;&#x2F;li&gt;
&lt;li&gt;you have to use VB to do alternate row colours - &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;44376&#x2F;add-alternating-row-color-to-sql-server-reporting-services-report&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;44376&#x2F;add-alternating-row-color-to-sql-server-reporting-services-report&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;if anything goes wrong with an expression all you get is &quot;#Error&quot;. Helpful. E.g. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;q&#x2F;9144312&#x2F;10245&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;q&#x2F;9144312&#x2F;10245&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;this one time, at band camp, I edited a report definition in VS and it refused to save the new definition to disk (ctrl-shift-s, ctrl-shift-s!!). wtf. Restarted VS and all the changes were gone.&lt;&#x2F;li&gt;
&lt;li&gt;report editor silently adds new parameters to the report when you add new parameters to the sql. seriously. fuck off.&lt;&#x2F;li&gt;
&lt;li&gt;RSI-inducing UI for editing the reports. click click click clickity click&lt;&#x2F;li&gt;
&lt;li&gt;the sql editor has only a single undo. like ye olde notepad.&lt;&#x2F;li&gt;
&lt;li&gt;in the editor, you can right-click copy, you can&#x27;t right-click paste. wtf. ctrl-v does paste though. wtf again. I know, I already said it, but it&#x27;s reaaaaaly shit&lt;&#x2F;li&gt;
&lt;li&gt;the field list on a dataset is ordinal, allowing you to mismatch the select in the sql from the list of fields in the dataset and not notice&lt;&#x2F;li&gt;
&lt;li&gt;how do you align a textbox on the page?&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Top&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;0.82546cm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Top&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Left&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;0.07309cm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Left&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Height&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;0.88964cm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Height&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Width&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;2.3025cm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Width&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;fuck you!!!!&lt;&#x2F;li&gt;
&lt;li&gt;one goddam cell in the underlying format:&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TablixCell&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;CellContents&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Textbox&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; Name&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;qty&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;CanGrow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;CanGrow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;KeepTogether&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;KeepTogether&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Paragraphs&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Paragraph&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TextRuns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;            &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TextRun&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;              &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;=Sum(Fields!qty.Value)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;              &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Style&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;            &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TextRun&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;          &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TextRuns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Style&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;        &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Paragraph&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;      &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Paragraphs&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;rd&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;DefaultName&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;qty&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;rd&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;DefaultName&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Style&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Border&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Color&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;LightGrey&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Color&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Style&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;None&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Style&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;        &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Border&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PaddingLeft&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;2pt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PaddingLeft&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PaddingRight&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;2pt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PaddingRight&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PaddingTop&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;2pt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PaddingTop&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PaddingBottom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;2pt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;PaddingBottom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;      &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Style&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Textbox&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;  &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;CellContents&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;TablixCell&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Report width limited to 455in (even if I&#x27;m hiding columns using parameters against the Visibility column filter).&lt;&#x2F;li&gt;
&lt;li&gt;NO DYNAMIC COLUMN CREATION (ridiculous!)&lt;&#x2F;li&gt;
&lt;li&gt;Selection of multiple columns and setting attributes is ridiculously flaky. This is because I wanted to reduce the column width and font to comply with Point 71 (max report width)!!&lt;&#x2F;li&gt;
&lt;li&gt;We have to restart Reporting Server services frequently or our charts won&#x27;t show up. Eh?&lt;&#x2F;li&gt;
&lt;li&gt;Cut and paste columns? Nope!&lt;&#x2F;li&gt;
&lt;li&gt;Disappearing &quot;Report Data&quot; menu: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;28883272&#x2F;10245&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;28883272&#x2F;1024&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;SSDT for VS2015 upgrades reports to 2016 schema as soon as they&#x27;re opened (WAT?!)  and ignores the TargetServerVersion being set to &amp;lt;=2014 &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;37816216&#x2F;deploy-of-a-report-with-ssdt-2016-generates-error&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;37816216&#x2F;deploy-of-a-report-with-ssdt-2016-generates-error&lt;&#x2F;a&gt; what if we haven&#x27;t upgraded our production server, hmmm?&lt;&#x2F;li&gt;
&lt;li&gt;Okay so when you run a build, VS2015 then &lt;strong&gt;downgrades&lt;&#x2F;strong&gt; the rdl to the right schema to match the project&#x27;s target server version before putting it in the build folder. What could possssssibly go wrong. 0_o   Complexity++&lt;&#x2F;li&gt;
&lt;li&gt;Install SSRS in only 41 easy steps &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thecodeattic.wordpress.com&#x2F;category&#x2F;ssrs&#x2F;&quot;&gt;https:&#x2F;&#x2F;thecodeattic.wordpress.com&#x2F;category&#x2F;ssrs&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Build &amp;gt; &quot;Skipping &#x27;SomeReport.rdl&#x27;. Item is up to date.&quot; - No it isn&#x27;t, I&#x27;ve deleted it from the friggin bin folder. So clearly it has some stupid cache of what&#x27;s it thinks is on disk rather than, oh I don&#x27;t know fucking checking the disk. Sheesh. If it&#x27;s that optimized why is everything still so damn slow?!&lt;&#x2F;li&gt;
&lt;li&gt;Building a project with lots of reports is slow. Even if nothing changed.&lt;&#x2F;li&gt;
&lt;li&gt;Intermittently get &lt;em&gt;&quot;[rsInvalidReportDefinition] The definition of this report is not valid or supported by this version of Reporting Services. The report definition may have been created with a later version of Reporting Services, or contain content that is not well-formed or not valid based on Reporting Services schemas. Details: Data at the root level is invalid.&quot;&lt;&#x2F;em&gt; - I am not alone. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;connect.microsoft.com&#x2F;SQLServer&#x2F;feedback&#x2F;details&#x2F;2988044&#x2F;randomly-get-rsinvalidreportdefinition-when-previewing-report&quot;&gt;https:&#x2F;&#x2F;connect.microsoft.com&#x2F;SQLServer&#x2F;feedback&#x2F;details&#x2F;2988044&#x2F;randomly-get-rsinvalidreportdefinition-when-previewing-report&lt;&#x2F;a&gt; - A rebuild fixes it for me, for a while at least.&lt;&#x2F;li&gt;
&lt;li&gt;Sometimes when you edit an embedded dataset it completely fails to persist any of your changes to disk. And when you close the report they are lost. Handy. Thanks fuck for git.&lt;&#x2F;li&gt;
&lt;li&gt;Assumes you&#x27;ve never heard of source control and creates numbered backups of report files (notably on auto-upgrade). Also has messages like &quot;&lt;em&gt;delete will permanently delete this thing&lt;&#x2F;em&gt;&quot; - no it won&#x27;t I have source control; I wonder if the SSRS know what that is.&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve never managed to crash VS2015 so many times in one day. Omg you didn&#x27;t click there did you? I wasn&#x27;t ready! &lt;em&gt;crash&lt;&#x2F;em&gt; ... &lt;em&gt;again&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Change the files on disk and the preview window often doesn&#x27;t notice&lt;&#x2F;li&gt;
&lt;li&gt;Preview window silently fires a &#x27;build&#x27; of the reports. Sometimes.&lt;&#x2F;li&gt;
&lt;li&gt;Generates broken Shared-datasets &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;38753141&#x2F;10245&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;38753141&#x2F;10245&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;If you break the xml of a shared-dataset the &lt;em&gt;entire project&lt;&#x2F;em&gt; will fail to load. w-t-f.&lt;&#x2F;li&gt;
&lt;li&gt;Renaming datasets etc just breaks everything rather than updating references.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;.rptproj&lt;&#x2F;code&gt; file has a &lt;code&gt;&amp;lt;state&amp;gt;&lt;&#x2F;code&gt; tag at the top which is base64 encoded xml (WAT?! xml in xml. eerrrrr), which is information about source control (&lt;em&gt;arse-about-face or what! source code that controls the &lt;em&gt;source-control&lt;&#x2F;em&gt; [that controls the source, that controls the source-control that controls the source...]; even the words are circular!!&lt;&#x2F;em&gt;). In the base64 you&#x27;ll find a &lt;code&gt;&amp;lt;SourceControlInfo&amp;gt;&lt;&#x2F;code&gt; tag.&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Project&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;xsi&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;2001&#x2F;XMLSchema-instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;xsd&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;2001&#x2F;XMLSchema&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; ToolsVersion&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;State&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;$base64$PFNvdXJjZUNvbnRyb2xJbmZvIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOmRkbDI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDAzL2VuZ2luZS8yIiB4bWxuczpkZGwyXzI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDAzL2VuZ2luZS8yLzIiIHhtbG5zOmRkbDEwMF8xMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDA4L2VuZ2luZS8xMDAvMTAwIiB4bWxuczpkZGwyMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEwL2VuZ2luZS8yMDAiIHhtbG5zOmRkbDIwMF8yMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEwL2VuZ2luZS8yMDAvMjAwIiB4bWxuczpkZGwzMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDExL2VuZ2luZS8zMDAiIHhtbG5zOmRkbDMwMF8zMDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDExL2VuZ2luZS8zMDAvMzAwIiB4bWxuczpkZGw0MDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEyL2VuZ2luZS80MDAiIHhtbG5zOmRkbDQwMF80MDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEyL2VuZ2luZS80MDAvNDAwIiB4bWxuczpkZGw1MDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEzL2VuZ2luZS81MDAiIHhtbG5zOmRkbDUwMF81MDA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYW5hbHlzaXNzZXJ2aWNlcy8yMDEzL2VuZ2luZS81MDAvNTAwIiB4bWxuczpkd2Q9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vRGF0YVdhcmVob3VzZS9EZXNpZ25lci8xLjAiPg0KICA8RW5hYmxlZD50cnVlPC9FbmFibGVkPg0KICA8UHJvamVjdE5hbWU+U0FLPC9Qcm9qZWN0TmFtZT4NCiAgPEF1eFBhdGg+U0FLPC9BdXhQYXRoPg0KICA8TG9jYWxQYXRoPlNBSzwvTG9jYWxQYXRoPg0KICA8UHJvdmlkZXI+U0FLPC9Qcm92aWRlcj4NCjwvU291cmNlQ29udHJvbEluZm8+&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;State&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;decoded &quot;state&quot; contents:&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;SourceControlInfo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;xsd&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;2001&#x2F;XMLSchema&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;xsi&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;2001&#x2F;XMLSchema-instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl2&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2003&#x2F;engine&#x2F;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl2_2&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2003&#x2F;engine&#x2F;2&#x2F;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl100_100&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2008&#x2F;engine&#x2F;100&#x2F;100&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl200&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2010&#x2F;engine&#x2F;200&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl200_200&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2010&#x2F;engine&#x2F;200&#x2F;200&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl300&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2011&#x2F;engine&#x2F;300&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl300_300&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2011&#x2F;engine&#x2F;300&#x2F;300&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl400&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2012&#x2F;engine&#x2F;400&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl400_400&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2012&#x2F;engine&#x2F;400&#x2F;400&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl500&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2013&#x2F;engine&#x2F;500&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;ddl500_500&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;analysisservices&#x2F;2013&#x2F;engine&#x2F;500&#x2F;500&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #93A1A1);&quot;&gt;dwd&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;http:&#x2F;&#x2F;schemas.microsoft.com&#x2F;DataWarehouse&#x2F;Designer&#x2F;1.0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#2AA198, #2AA198);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;ProjectName&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;SAK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;ProjectName&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;AuxPath&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;SAK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;AuxPath&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;LocalPath&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;SAK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;LocalPath&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;SAK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;Provider&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#268BD2, #268BD2);&quot;&gt;SourceControlInfo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#93A1A1, #586E75);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;Enough xml namespaces for you?&lt;&#x2F;li&gt;
&lt;li&gt;The state base64 changes all the time causing diff noise.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I know I can&#x27;t count, but if ssrs is going to make so little effort I don&#x27;t see why I should. And to be honest &quot;100&quot; seemed a lot more like comic exaggeration when I titled my tomboy note which only had 5 or 6 grumblings in it, I wasn&#x27;t actually expecting to get within spitting distance of the original number!&lt;&#x2F;p&gt;
&lt;p&gt;Doesn&#x27;t mean I won&#x27;t use it again mind, just don&#x27;t promise to like it.&lt;&#x2F;p&gt;
&lt;p&gt;If you liked this, you might also like the ssrs deployment tool I sometimes look after: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;ssrs-powershell-deploy&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;ssrs-powershell-deploy&lt;&#x2F;a&gt; (mostly not my work, just pulled together a bunch of contributions).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>LibreOffice mail merge - &quot;data source &#x27;SOURCE&#x27; was not found&quot;</title>
        <published>2015-01-12T22:31:00.002+00:00</published>
        <updated>2015-01-12T22:31:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2015/01/12/libreoffice-mail-merge-data-source/"/>
        <id>https://0x5.uk/2015/01/12/libreoffice-mail-merge-data-source/</id>
        
        <content type="html" xml:base="https://0x5.uk/2015/01/12/libreoffice-mail-merge-data-source/">&lt;p&gt;So another year on, LibreOffice 4.2.7.2 (via Linux Mint 17.1) still has a dog&#x27;s breakfast of a mail merge feature, hey ho, hopefully it might actually get fixed following the fork from OpenOffice and the change in contribution methods.&lt;&#x2F;p&gt;
&lt;p&gt;Anyways&lt;&#x2F;p&gt;
&lt;p&gt;So I&#x27;ve moved machines, copied my files across and for some reason my mail merge has soiled itself and now bleats &lt;em&gt;&quot;data source &#x27;SOURCE&#x27; was not found&quot;&lt;&#x2F;em&gt; which is as unhelpful as it is infuriating, especially given that the &quot;check connections&quot; button is exactly the wrong place to look for an answer.&lt;&#x2F;p&gt;
&lt;p&gt;Turns out you actually get this if even just a single field in your document is &#x27;broken&#x27;. How do you tell which ones are broken? Well you have to change them all to just be sure. Sigh.&lt;&#x2F;p&gt;
&lt;p&gt;The fix for me today was as follows (though with such a messy feature there&#x27;s unlimited ways it can break):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Hit F4 and check that your connection to the spreadsheet actually exists and works, and unbreak anything you find therein. While you&#x27;re in there you can marvel at how it requires a whole other file (.odb) just to remember how to get to a spreadsheet. (See below for fixing this)&lt;&#x2F;li&gt;
&lt;li&gt;Turn on the field names so you can see what the f*** is actually going on with &quot;&lt;em&gt;View &amp;gt; Field Names (ctrl+f9)&lt;&#x2F;em&gt;&quot; which will show you the fully qualified field name, which might even be completely wrong. You can now see that for whatever reason (insanity?) it embeds more than just the field name at the field place-holder.&lt;&#x2F;li&gt;
&lt;li&gt;And finally the way you actually fix the broken fields it&#x27;s failing to tell you about actually lies under the menu item &quot;&lt;em&gt;Edit &amp;gt; Fields&lt;&#x2F;em&gt;&quot;, where you can change all the broken references one at a time to the correct place.&lt;&#x2F;li&gt;
&lt;li&gt;For bonus points, if it the field looks right but is silently broken somehow then you have to change the field to something else, hit okay, and then change it back again for anything to actually change, which is annoying if you have a lot of fields.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Fragile much?&lt;&#x2F;p&gt;
&lt;p&gt;Another fix I&#x27;ve just discovered is you can rename your data source to match the name defined in the fields (assuming they&#x27;re all the same) and it&#x27;ll start working again.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;fixing-the-odb-file&quot;&gt;Fixing the .odb file&lt;&#x2F;h4&gt;
&lt;p&gt;If you&#x27;re stuck on point 1, here&#x27;s how you fix it, also completely non-obvious and full of apparent dead-ends and dubious information.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Give up on trying to do this in writer, it doesn&#x27;t seem possible, in spite of false hope from the data sources tool, it only allows you to select .odb (database) files, not spreadsheets.&lt;&#x2F;li&gt;
&lt;li&gt;Open up &quot;libreoffice base&quot;, which pops open the database wizard&lt;&#x2F;li&gt;
&lt;li&gt;Choose &quot;connect to an existing database&quot;&lt;&#x2F;li&gt;
&lt;li&gt;In the dropdown choose &quot;Spreadsheet&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Next&lt;&#x2F;li&gt;
&lt;li&gt;Browse for your spreadsheet&lt;&#x2F;li&gt;
&lt;li&gt;Next&lt;&#x2F;li&gt;
&lt;li&gt;Leave &quot;register database for me&quot; selected&lt;&#x2F;li&gt;
&lt;li&gt;Leave &quot;open the database for editing&quot; checked&lt;&#x2F;li&gt;
&lt;li&gt;Finish&lt;&#x2F;li&gt;
&lt;li&gt;It prompts to save the new database (.odb), I suggest saving it in the same folder as the spreadsheet to save future confusion.&lt;&#x2F;li&gt;
&lt;li&gt;You now have the database open in &quot;base&quot;, you should see your spreadsheet sheets listed as tables&lt;&#x2F;li&gt;
&lt;li&gt;Open a table (i.e. a sheet) and check you can see the spreadsheet contents&lt;&#x2F;li&gt;
&lt;li&gt;Close &quot;base&quot;, saving changes&lt;&#x2F;li&gt;
&lt;li&gt;Return to your writer document&lt;&#x2F;li&gt;
&lt;li&gt;Open the data sources again (F4), you should now be able to browse your spreadsheet via your newly created database.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Simpler than getting planning permission out of a vogon. :-&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;Hope that helps some other poor open source die-hard who has work to do.&lt;&#x2F;p&gt;
&lt;p&gt;Useful refs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;davidmburke.com&#x2F;2011&#x2F;08&#x2F;10&#x2F;mail-merge-in-libreoffice&#x2F;&quot;&gt;http:&#x2F;&#x2F;davidmburke.com&#x2F;2011&#x2F;08&#x2F;10&#x2F;mail-merge-in-libreoffice&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.openoffice.org&#x2F;en&#x2F;forum&#x2F;viewtopic.php?f=30&amp;amp;t=29708&quot;&gt;https:&#x2F;&#x2F;forum.openoffice.org&#x2F;en&#x2F;forum&#x2F;viewtopic.php?f=30&amp;amp;t=29708&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.libreoffice.org&#x2F;bugzilla&#x2F;buglist.cgi?quicksearch=mailmerge&quot;&gt;https:&#x2F;&#x2F;www.libreoffice.org&#x2F;bugzilla&#x2F;buglist.cgi?quicksearch=mailmerge&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;ask.libreoffice.org&#x2F;en&#x2F;question&#x2F;19590&#x2F;can-you-import-a-libreoffice-calc-spreadsheet-into-a-libreoffice-database&#x2F;&quot;&gt;http:&#x2F;&#x2F;ask.libreoffice.org&#x2F;en&#x2F;question&#x2F;19590&#x2F;can-you-import-a-libreoffice-calc-spreadsheet-into-a-libreoffice-database&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>throw vs throw ex vs wrap and throw in c-sharp</title>
        <published>2014-05-10T10:23:00+00:00</published>
        <updated>2014-05-10T10:23:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2014/05/10/throw-vs-throw-ex-vs-wrap-and-throw-in/"/>
        <id>https://0x5.uk/2014/05/10/throw-vs-throw-ex-vs-wrap-and-throw-in/</id>
        
        <content type="html" xml:base="https://0x5.uk/2014/05/10/throw-vs-throw-ex-vs-wrap-and-throw-in/">&lt;p&gt;I&#x27;ve come across the &lt;code&gt;throw&lt;&#x2F;code&gt; vs &lt;code&gt;throw ex&lt;&#x2F;code&gt; &#x27;debate&#x27; a few times, even as an
interview question, and it&#x27;s always bugged me because it&#x27;s never something I&#x27;ve
worried about in my own c# code.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;background&quot;&gt;Background&lt;&#x2F;h1&gt;
&lt;p&gt;So here&#x27;s a typical example of the throw vs throw ex thing:
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;730250&#x2F;is-there-a-difference-between-throw-and-throw-ex&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;730250&#x2F;is-there-a-difference-between-throw-and-throw-ex&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Basically it revolves around either messing up the line numbers in your stack
trace (&lt;code&gt;throw ex;&lt;&#x2F;code&gt;) or losing a chunk of your stack entirely (&lt;code&gt;throw;&lt;&#x2F;code&gt;) -
exception1 and 2 respectively in this nice clear answer:
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;776756&#x2F;10245&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;776756&#x2F;10245&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a data-flickr-embed=&quot;true&quot;
href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;13910043519&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;7193&#x2F;13910043519_348f641fe1_k.jpg&quot;
alt=&quot;Smiley face in a coffee stain&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;h1 id=&quot;the-third-option&quot;&gt;The third option&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;ve just figured out why it&#x27;s never been an issue for me.&lt;&#x2F;p&gt;
&lt;p&gt;Because in my own code, whenever I catch and re-throw I &lt;em&gt;always&lt;&#x2F;em&gt; wrap another
exception to add more context before rethrowing, and this means you don&#x27;t have
either of the above problems. For example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;private static void ThrowException3() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    try {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        DivByZero(); &#x2F;&#x2F; line 43&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } catch (Exception ex) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        throw new Exception(&amp;quot;doh&amp;quot;, ex); &#x2F;&#x2F; line 45&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Exception 3:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;System.Exception: doh ---&amp;gt; System.DivideByZeroException: Division by zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  at puke.DivByZero () [0x00002] in &#x2F;home&#x2F;tim&#x2F;repo&#x2F;puker&#x2F;puke.cs:51&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  at puke.ThrowException3 () [0x00000] in &#x2F;home&#x2F;tim&#x2F;repo&#x2F;puker&#x2F;puke.cs:43&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  --- End of inner exception stack trace ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  at puke.ThrowException3 () [0x0000b] in &#x2F;home&#x2F;tim&#x2F;repo&#x2F;puker&#x2F;puke.cs:45&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  at puke.Main (System.String[] args) [0x00040] in &#x2F;home&#x2F;tim&#x2F;repo&#x2F;puker&#x2F;puke.cs:18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Obviously &#x27;doh&#x27; would be something meaningful about the state of that function
&lt;code&gt;ThrowException3()&lt;&#x2F;code&gt; in the real world.&lt;&#x2F;p&gt;
&lt;p&gt;Full example with output at
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;78610f588961bd0a0b95&quot;&gt;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;78610f588961bd0a0b95&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This makes life much easier when tracking down bugs &#x2F; state problems later on.
Particularly if you &lt;code&gt;string.Format()&lt;&#x2F;code&gt; the new message and add some useful state
info.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why publish open source when you are commercial?</title>
        <published>2014-03-08T19:07:00+00:00</published>
        <updated>2014-03-08T19:07:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2014/03/08/why-publish-open-source-when-you-are/"/>
        <id>https://0x5.uk/2014/03/08/why-publish-open-source-when-you-are/</id>
        
        <content type="html" xml:base="https://0x5.uk/2014/03/08/why-publish-open-source-when-you-are/">&lt;p&gt;Why open source your commercial projects?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Forces you to decouple them from other internal systems.&lt;&#x2F;li&gt;
&lt;li&gt;Encourages thinking in terms of reusable modules, which is better for
internal reuse just as much as public reuse.&lt;&#x2F;li&gt;
&lt;li&gt;Possibility of contributions to systems useful to your business by others.&lt;&#x2F;li&gt;
&lt;li&gt;Easier reuse within your organisation (the public internet is a better
search and sharing system than any internal systems).&lt;&#x2F;li&gt;
&lt;li&gt;Reputation advantages, the best coders often like to work in open and
forward-thinking companies, and having public shared code is a great sign
of such an organisation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Do it early&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Preferably push your very first commit straight to github.&lt;&#x2F;li&gt;
&lt;li&gt;Do it before it has a chance to be tightly coupled to internal systems,
otherwise you&#x27;ll have to unpick it and it will be less decoupled from day
one, and inertia might mean that in spite of the best intentions you then
never publish it.&lt;&#x2F;li&gt;
&lt;li&gt;You&#x27;ll have it in mind that every commit is public from day one, avoiding
adding internal config etc and forcing you to factor it out into config
which is all round a good thing.&lt;&#x2F;li&gt;
&lt;li&gt;Don&#x27;t wait for your code to be perfect, there are compromises in all code
and sharing something imperfect is better than sharing nothing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;12293521763&#x2F;in&#x2F;photostream&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;3756&#x2F;12293521763_39d7704c73_k.jpg&quot;
alt=&quot;People on the beach with a clifftop&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Worried about the brand?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Commit under personal email addresses and push to personal github accounts.
You can always setup a corporate github account later when you are feeling
more confident.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Of course I&#x27;m not saying you should open source everything, for example your
core product&#x27;s codebase should probably not go on github if you are a product
company!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Be brave, be open.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Props to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;tomskitomski&quot;&gt;Tom Loosemoore&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bash command line editing cheat sheet</title>
        <published>2014-02-10T18:33:00+00:00</published>
        <updated>2014-02-10T18:33:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2014/02/10/bash-command-line-editing-cheat-sheet/"/>
        <id>https://0x5.uk/2014/02/10/bash-command-line-editing-cheat-sheet/</id>
        
        <content type="html" xml:base="https://0x5.uk/2014/02/10/bash-command-line-editing-cheat-sheet/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;bash&#x2F;manual&#x2F;bashref.html#Readline-Interaction&quot;&gt;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;bash&#x2F;manual&#x2F;bashref.html#Readline-Interaction&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ctrl-a&#x2F;e&lt;&#x2F;strong&gt; start&#x2F;end of line&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;alt-f&#x2F;b&lt;&#x2F;strong&gt; forward&#x2F;back a word&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ctrl-w&#x2F;alt-d&lt;&#x2F;strong&gt; delete to start&#x2F;end of word&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;alt-.&lt;&#x2F;strong&gt; add argument from previous command (repeat to cycle) - love this one&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ctrl-shift-_&lt;&#x2F;strong&gt; undo (i.e. ctrl-underscore)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ctrl-y&lt;&#x2F;strong&gt; paste (yank) deleted text&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;alt-y&lt;&#x2F;strong&gt; paste older deleted text instead&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;prefix with &lt;strong&gt;alt+digit&lt;&#x2F;strong&gt; (0-9) to do multiple, e.g. delete two words&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;start with &lt;strong&gt;alt-minus&lt;&#x2F;strong&gt; to go backwards&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Just a few notes I threw together for my own benefit. I finally got around to learning a bit more about editing commands on the Linux shell &#x2F; terminal.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;11937840106&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;3808&#x2F;11937840106_51c5d9f170_k.jpg&quot; alt=&quot;Photo of flooded River Thames at Henley, half-submerging the benches of the Angel pub&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Converting kml to gpx with python</title>
        <published>2014-02-03T20:27:00+00:00</published>
        <updated>2014-02-03T20:27:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2014/02/03/converting-kml-to-gpx-with-python/"/>
        <id>https://0x5.uk/2014/02/03/converting-kml-to-gpx-with-python/</id>
        
        <content type="html" xml:base="https://0x5.uk/2014/02/03/converting-kml-to-gpx-with-python/">&lt;p&gt;Today I wanted to geo-code some of my photos.&lt;&#x2F;p&gt;
&lt;p&gt;I have an SLR digital camera (no gps of course), and an android phone. I
recorded a track with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;apps&#x2F;details?id=com.google.android.maps.mytracks&quot;&gt;My
Tracks&lt;&#x2F;a&gt;
from google on the phone. (Not entirely recommended but works). I then fired up
digikam to run the geo-correlation and add lat-long to the exif of the files
only to discover &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;community.kde.org&#x2F;Digikam&#x2F;GSoC2010&#x2F;ReverseGeocoding#TODO_Later_versions&quot;&gt;digikam doesn&#x27;t know how to read
kml&lt;&#x2F;a&gt;.
Fooey.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;12293521763&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;3756&#x2F;12293521763_39d7704c73_k.jpg&quot; alt=&quot;people on the beach&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I looked to gpsbabel, but it apparently can&#x27;t handle this style of kml file, as
differentiated by the coordinates being in the following style of markup:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;gx:Track&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;when&amp;gt;2014-01-25T18:00:13.955Z&amp;lt;&#x2F;when&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;gx:coord&amp;gt;-1.885348 50.769434&amp;lt;&#x2F;gx:coord&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;when&amp;gt;2014-01-25T18:00:14.565Z&amp;lt;&#x2F;when&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;gx:coord&amp;gt;-1.885193 50.769328 53.20000076293945&amp;lt;&#x2F;gx:coord&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;when&amp;gt;2014-01-25T18:00:58.566Z&amp;lt;&#x2F;when&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So I wrote a python script to munge it into gpx shape:&lt;&#x2F;p&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;timabell&#x2F;8791116.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;This can be run as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;kmlToGpx.py &amp;quot;25-01 12-48.kml&amp;quot; &amp;gt; &amp;quot;25-01 12-48.kml.gpx&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And worked a treat for me.&lt;&#x2F;p&gt;
&lt;p&gt;After I&#x27;d done this I discovered my pet tool
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;activityworkshop.net&#x2F;software&#x2F;gpsprune&#x2F;index.html&quot;&gt;gpsprune&lt;&#x2F;a&gt; can open
the new style kml. (I &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;gpsprune&quot;&gt;forked gpsprune&lt;&#x2F;a&gt; a
while ago and added a minor feature) However I&#x27;m glad to have a command-line
tool as I have hundreds of tracks I want to convert.&lt;&#x2F;p&gt;
&lt;p&gt;Incidentally the phone can automatically sync the tracks to google drive, which
is kinda handy and then you can download them from the site etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Returning to commercial ASP.NET from Ruby on Rails</title>
        <published>2014-01-07T13:17:00.002+00:00</published>
        <updated>2014-01-07T13:17:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2014/01/07/returning-to-commercial-aspnet-from/"/>
        <id>https://0x5.uk/2014/01/07/returning-to-commercial-aspnet-from/</id>
        
        <content type="html" xml:base="https://0x5.uk/2014/01/07/returning-to-commercial-aspnet-from/">&lt;p&gt;Why ASP.NET again after all the noise I made about Ruby on Rails? After a brief stint with commercial Ruby on Rails development I should explain why I&#x27;ve decided my next gig will be an ASP.NET project. In short: currently almost all the Rails work available is in London for digital agencies and start-ups, demanding on-site full time presence, and I burned out doing 3 hours a day commuting in less than half-a-year. This is not a sustainable business plan.&lt;&#x2F;p&gt;
&lt;p&gt;The emphasis on start-ups and agencies bodes well for the commercial future of Rails as many of these projects will bloom into large systems needing continuing development. But for me the market in the Reading area seems too quiet to make a business success from just Rails. The final straw was being formally offered a rare local permanent Rails job working with all my favourite open source technologies (Rails, Postgres, Linux etc) only to be handed an employment contract with less job security, rights and benefits than a contractor would have. This confirmed my growing understanding of the local market not being suitable.&lt;&#x2F;p&gt;
&lt;p&gt;So, my updated plan of action is to return to providing programming services to the vibrant .NET market in the local area.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;11677745506&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;5548&#x2F;11677745506_674ad8e0d5_k.jpg&quot; alt=&quot;Fireworks over Reading, a moody nightscape.&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;This article is for my Linked In audience, if you want to become part of my network or learn more about my professional services send me a message or invite here: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;timabell&quot;&gt;http:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;timabell&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;From a technical perspective my first-hand experience with Ruby on Rails in a mature project has shown me the that the speed boost of Ruby on Rails over ASP.NET is short-lived and once a project becomes larger and more mature the pace of development appears to my eye to be very similar.&lt;&#x2F;p&gt;
&lt;p&gt;The problems encountered are largely different, but not not biased heavily to one or other stack. For example Rails projects have issues with fragmented and dubiously maintained gems that provide important functionality (not all of them mind; lots are excellent well run projects), whereas Microsoft projects tend to just use whatever Microsoft have supplied warts-and-all; each has pros and cons.&lt;&#x2F;p&gt;
&lt;p&gt;Having learnt all this first-hand I now believe that my initial concern that Rails would take all of Microsoft&#x27;s market share in web development due to faster (i.e. cheaper) development is unfounded.&lt;&#x2F;p&gt;
&lt;p&gt;I also now understand why the Ruby crowd is so much keener on test-driven development than the C# crowd; it&#x27;s because they lack all the compile-time checks that catch many classes of programming error up front (e.g. changing a method signature and not updating usages).&lt;&#x2F;p&gt;
&lt;p&gt;The main things I missed when I switched from C# to Ruby were&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ReSharper:
&lt;ul&gt;
&lt;li&gt;Find usages &#x2F; definition.&lt;&#x2F;li&gt;
&lt;li&gt;Refactoring.&lt;&#x2F;li&gt;
&lt;li&gt;A compiler to catch mistakes sooner.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Being an expert.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting rails 4 up and running with rbenv on Ubuntu 13.10</title>
        <published>2013-12-04T23:16:00.003+00:00</published>
        <updated>2013-12-04T23:16:00.003+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2013/12/04/getting-rails-4-up-and-running-with/"/>
        <id>https://0x5.uk/2013/12/04/getting-rails-4-up-and-running-with/</id>
        
        <content type="html" xml:base="https://0x5.uk/2013/12/04/getting-rails-4-up-and-running-with/">&lt;p&gt;&lt;em&gt;Brain dump warning!&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a follow up to
&lt;a href=&quot;&#x2F;2013&#x2F;05&#x2F;13&#x2F;installing-ruby-2-rails-4-on-ubuntu&#x2F;&quot;&gt;Installing ruby 2 + Rails 4 on Ubuntu 12.04 LTS&lt;&#x2F;a&gt;
and is just a list of steps needed to get a clean install of Ubuntu up to speed
with an existing site.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Install rbenv to manage ruby versions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sj26&#x2F;rbenv-install&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;sj26&#x2F;rbenv-install&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git clone https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv.git ~&#x2F;.rbenv&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Install ruby-build to manage installation of ruby versions into rbenv&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;ruby-build&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;ruby-build&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git clone https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;ruby-build.git ~&#x2F;.rbenv&#x2F;plugins&#x2F;ruby-build&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;For convenience install dotmatrix - this will set up the rbenv environment correctly, amongst other things&lt;&#x2F;li&gt;
&lt;li&gt;clone &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;run bin&#x2F;install&lt;&#x2F;li&gt;
&lt;li&gt;restart any running terminal(s) to get rbenv&lt;&#x2F;li&gt;
&lt;li&gt;get a project (includes a .ruby-version file for rbenv, and a Gemfile for bundle)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git clone git@github.com:timabell&#x2F;symbol-library.git&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;sudo apt-get install libssl-dev libreadline-dev&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;readline is needed for rails console, and has to be installed before ruby. If you&#x27;ve already installed ruby then just re-run rbenv install and it will overwrite the existing build with a version with readline support. ref: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;vvv.tobiassjosten.net&#x2F;ruby&#x2F;readline-in-ruby-with-rbenv&#x2F;&quot;&gt;http:&#x2F;&#x2F;vvv.tobiassjosten.net&#x2F;ruby&#x2F;readline-in-ruby-with-rbenv&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;rbenv install x.x.x-xxxx&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;autocompletes, yay!&lt;&#x2F;li&gt;
&lt;li&gt;.. or better still reads from .ruby-version I think so you can just run &lt;code&gt;rbenv install&lt;&#x2F;code&gt; if you are in the project folder&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;gem install bundler&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;from the right directory so done for right ruby version
&lt;ul&gt;
&lt;li&gt;rbenv rehash&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bundle&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;will install all the gems for the project&lt;&#x2F;li&gt;
&lt;li&gt;&lt;del&gt;don&#x27;t &lt;code&gt;sudo apt-get install rbenv&lt;&#x2F;code&gt;&lt;&#x2F;del&gt; ~ doesn&#x27;t provide sufficiently up to date ruby&lt;&#x2F;li&gt;
&lt;li&gt;&lt;del&gt;don&#x27;t &lt;code&gt;gem install rails --version 4.0.2 --no-ri --no-rdoc&lt;&#x2F;code&gt;&lt;&#x2F;del&gt; ~ don&#x27;t need this when you have a gem file with rails in it, bundle will do it for you&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;sudo apt-get install nodejs&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;for javascript runtime (rails server throwing an error without this)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bundle exec rails server&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bundle exec rails console&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;needs readline (see above)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Other stuff I like in my install&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;dotmatrix bin&#x2F;vimbundles
&lt;ul&gt;
&lt;li&gt;includes vim-rails and friends&lt;&#x2F;li&gt;
&lt;li&gt;full list &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;blob&#x2F;master&#x2F;bin&#x2F;vimbundles.sh#L45&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;dotmatrix&#x2F;blob&#x2F;master&#x2F;bin&#x2F;vimbundles.sh#L45&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;console colours from bin&#x2F;solarize.sh in dotmatrix&#x2F;bin&lt;&#x2F;li&gt;
&lt;li&gt;tmux&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is mostly for my own reference but maybe it&#x27;ll help someone else out.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Unfinished hyperlinks - add a todo</title>
        <published>2013-05-25T10:03:00.001+00:00</published>
        <updated>2013-05-25T10:03:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2013/05/25/unfinished-hyperlinks-add-todo/"/>
        <id>https://0x5.uk/2013/05/25/unfinished-hyperlinks-add-todo/</id>
        
        <content type="html" xml:base="https://0x5.uk/2013/05/25/unfinished-hyperlinks-add-todo/">&lt;p&gt;Just a quick post;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;stop-doing-this&quot;&gt;Stop doing this&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;href=&amp;quot;#&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;start-doing-this&quot;&gt;Start doing this&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;href=&amp;quot;#todo&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;why&quot;&gt;Why?&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;d like to promote a change to the habit of using &#x27;#&#x27; as the placeholder for a the url of a new hyperlink when you don&#x27;t yet know where it&#x27;ll link to: instead set the href to &quot;#todo&quot;. This follows the &#x2F;&#x2F;todo pattern recognised for unfinished code, and means you can now search your codebase for any links you forgot to finish off.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;new link&amp;lt;&#x2F;a&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;becomes&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;a href=&amp;quot;#todo&amp;quot; onclick=&amp;quot;alert(&amp;#39;Not Implemented&amp;#39;);return false;&amp;quot;&amp;gt;new link&amp;lt;&#x2F;a&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Demo: &lt;a href=&quot;#&quot;&gt;before&lt;&#x2F;a&gt; becomes &lt;a href=&quot;#todo&quot;&gt;after&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It will also give clues to any sharp-eyed testers &#x2F; users that they should
report a bug for you as the url will change to #todo when the unfinished link
is clicked. It can often be seen in the status bar too.  This has the handy
side-effect of avoiding the annoying jump to the top of the page that is the
default behaviour when you click on a # link that&#x27;s a placeholder.&lt;&#x2F;p&gt;
&lt;p&gt;For bonus points another little trick I like is to add a click handler with an
alert to make it really obvious to any early users &#x2F; testers that this is not
done yet, and I&#x27;ve found this saves a lot of questions when you genuinely
haven&#x27;t finished, and also guarantees a quick bug report when you should have
(not that I ever forget any of course :-D)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;new link&amp;lt;&#x2F;a&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;becomes&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;a href=&amp;quot;#todo&amp;quot; onclick=&amp;quot;alert(&amp;#39;Not Implemented&amp;#39;);return false;&amp;quot;&amp;gt;new link&amp;lt;&#x2F;a&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Demo: &lt;a href=&quot;#&quot;&gt;before&lt;&#x2F;a&gt; becomes &lt;a href=&quot;#todo&quot; onclick=&quot;alert(&#x27;Not Implemented&#x27;);return false;&quot;&gt;after&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can automate giving all these links an alert with the following (cheers to
&quot;unknown&quot; in the blogger comments)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$(&amp;quot;a[href=#todo]&amp;quot;).click(function () { alert(&amp;#39;Not implemented yet.&amp;#39;) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Simple and effective.&lt;&#x2F;p&gt;
&lt;p&gt;If you agree, please help spread the word. Perhaps by retweeting &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;tim_abell&#x2F;status&#x2F;338235507203002368&quot;&gt;my tweet&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;P.S. This goes hand in hand with a technique of picking points during development at which there should be no todo&#x27;s left in your codebase with the exception of those with references to outstanding user story &#x2F; bug numbers. I suggest before marking a user story as done, and at the end of each sprint as good points to review all todos in your codebase.&lt;&#x2F;p&gt;
&lt;p&gt;Further reading:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wordaligned.org&#x2F;articles&#x2F;todo&quot;&gt;The case against TODO - wordaligned.org&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.jetbrains.com&#x2F;webide&#x2F;2012&#x2F;10&#x2F;managing-todo&#x2F;&quot;&gt;Using a JetBrains IDE to manage todos&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Installing ruby 2 + Rails 4 on Ubuntu 12.04 LTS</title>
        <published>2013-05-13T10:29:00+00:00</published>
        <updated>2013-05-13T10:29:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2013/05/13/installing-ruby-2-rails-4-on-ubuntu/"/>
        <id>https://0x5.uk/2013/05/13/installing-ruby-2-rails-4-on-ubuntu/</id>
        
        <content type="html" xml:base="https://0x5.uk/2013/05/13/installing-ruby-2-rails-4-on-ubuntu/">&lt;p&gt;Installing &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ruby-lang.org&#x2F;&quot;&gt;Ruby&lt;&#x2F;a&gt; 2 + &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;rubyonrails.org&#x2F;&quot;&gt;Rails&lt;&#x2F;a&gt; 4 on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ubuntu.com&#x2F;&quot;&gt;Ubuntu&lt;&#x2F;a&gt; 12.04 LTS&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Update Dec 2013:&lt;&#x2F;em&gt; You may also wish to read &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;benkwok.wordpress.com&#x2F;2013&#x2F;08&#x2F;15&#x2F;install-rails-on-ubuntu-12-04-lts-with-rbenv&#x2F;&quot;&gt;benkwok&#x27;s blog post on installing ruby and rails&lt;&#x2F;a&gt;. I&#x27;ve also &lt;a href=&quot;&#x2F;2013&#x2F;12&#x2F;04&#x2F;getting-rails-4-up-and-running-with&#x2F;&quot;&gt;posted my notes from installing for an existing project&lt;&#x2F;a&gt; which doesn&#x27;t entirely replace this post but reflects my more recent learnings.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s a few of these blog posts around, but here&#x27;s mine for my own benefit (I&#x27;m sure this won&#x27;t be the last time I do it!).&lt;&#x2F;p&gt;
&lt;p&gt;If you have a packaged ruby &#x2F; rails &#x2F; rvm &#x2F; rbenv etc installed, get rid of them all, eg:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ruby --versionruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]$ sudo apt-get remove ruby&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Don&#x27;t use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rvm.io&#x2F;&quot;&gt;rvm&lt;&#x2F;a&gt;; and make sure it&#x27;s been literally purged from your system. It&#x27;s a pain to remove as it gets into all sorts of places and even &lt;em&gt;apt-get purge&lt;&#x2F;em&gt; doesn&#x27;t undo changes to the profile etc. If you want to know more about the reason for not using it then read the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv&#x2F;wiki&#x2F;Why-rbenv%3F&quot;&gt;rbenv &quot;why&quot; page&lt;&#x2F;a&gt;, it&#x27;s persuasive stuff.&lt;&#x2F;p&gt;
&lt;p&gt;My recommendation from experience so far is to use &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;rbenv.org&#x2F;&quot;&gt;rbenv&lt;&#x2F;a&gt; to install the latest and greatest RoR (Ruby on Rails). Don&#x27;t bother with the ubuntu packaged version of rbenv (from apt etc) as you&#x27;ll be off the beaten track and will have to figure out the ruby-build plugin installation yourself. The local user install is painless and works well. The instructions say to make sure rvm is removed first as it&#x27;s incompatible.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Sidenote, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;rbenv.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;rbenv.org&#x2F;&lt;&#x2F;a&gt; is just a one-click link to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Direct link to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv#readme&quot;&gt;rbenv readme&lt;&#x2F;a&gt; (for your convenience)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;8734272311&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;7308&#x2F;8734272311_f49ccb1e42_k.jpg&quot; alt=&quot;Minster Church, Boscastle&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;h1 id=&quot;rbenv-installation&quot;&gt;rbenv installation&lt;&#x2F;h1&gt;
&lt;p&gt;Install rbenv into your home directory:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ git clone git:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv.git ~&#x2F;.rbenv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Set up the environment as per the (ubuntu specific) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv#installation&quot;&gt;rbenv installation instructions&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ echo &amp;#39;export PATH=&amp;quot;$HOME&#x2F;.rbenv&#x2F;bin:$PATH&amp;quot;&amp;#39; &amp;gt;&amp;gt; ~&#x2F;.profile$ echo &amp;#39;eval &amp;quot;$(rbenv init -)&amp;quot;&amp;#39; &amp;gt;&amp;gt; ~&#x2F;.profile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Unless you&#x27;ve done anything before, there is no ~&#x2F;.profile file before hand, so the contents will then be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cat ~&#x2F;.profileexport PATH=&amp;quot;$HOME&#x2F;.rbenv&#x2F;bin:$PATH&amp;quot;eval &amp;quot;$(rbenv init -)&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Restart the login shell:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ exec $SHELL -l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Check rbenv is now available:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ rbenvrbenv 0.4.0-45-g060f141Usage: rbenv &amp;lt;command&amp;gt; [&amp;lt;args&amp;gt;]...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Set up the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;ruby-build#readme&quot;&gt;ruby-build&lt;&#x2F;a&gt; plugin (as linked in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv#readme&quot;&gt;rbenv readme&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ git clone https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;ruby-build.git ~&#x2F;.rbenv&#x2F;plugins&#x2F;ruby-build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Install the necessary ssl library:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo apt-get install libssl-dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you don&#x27;t install the openssl development libraries you get this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BUILD FAILED...The Ruby openssl extension was not compiled. Missing the OpenSSL lib?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;8734303977&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;7310&#x2F;8734303977_566f96b159_k.jpg&quot; alt=&quot;Looking out of a cave on the beach&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;h1 id=&quot;ruby-installation&quot;&gt;Ruby installation&lt;&#x2F;h1&gt;
&lt;p&gt;Install the latest ruby (version name obtained from &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ruby-lang.org&#x2F;en&#x2F;news&#x2F;2013&#x2F;02&#x2F;24&#x2F;ruby-2-0-0-p0-is-released&#x2F;&quot;&gt;release info on ruby blog&lt;&#x2F;a&gt;), takes 5-10 mins&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ rbenv install 2.0.0-p0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now select the installed ruby as the default for your user (ref: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv#choosing-the-ruby-version&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;sstephenson&#x2F;rbenv#choosing-the-ruby-version&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ rbenv global 2.0.0-p0 tim@atom:~$ ruby --versionruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;rails-installation&quot;&gt;Rails installation&lt;&#x2F;h1&gt;
&lt;p&gt;Now as per the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2013&#x2F;5&#x2F;1&#x2F;Rails-4-0-release-candidate-1&#x2F;&quot;&gt;Rails 4 RC1 announcement&lt;&#x2F;a&gt; install the release candidate of Rails 4 (this was the latest at time of writing). Takes 5-10 mins.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ gem install rails --version 4.0.0.rc1 --no-ri --no-rdoc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Tell rbenv to create the new shims and see the installed rails:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ rbenv rehash$ rails --versionRails 4.0.0.rc1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;All done! That wasn&#x27;t so hard, it was all the blind alleys that took the time.&lt;&#x2F;p&gt;
&lt;p&gt;Now use &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;gembundler.com&#x2F;&quot;&gt;bundler&lt;&#x2F;a&gt; as recommended in the rbenv readme to set up an app etc.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for listening :-)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;footnote&quot;&gt;Footnote&lt;&#x2F;h1&gt;
&lt;p&gt;It pains me somewhat to have to use installations outside of the Ubuntu package manager, however it seems there are some grumblings about the packaged versions of the above software. Add into this that I wish to use the latest RoR on an LTS release of Ubuntu which seeing as the Rails community don&#x27;t seem to provide debs &#x2F; repos etc leaves a packaged version out of the question for now. I&#x27;ve learned previously the hard way the destructive effect of randomly installing everything you find outside the package management system of a distro so have tread carefully when creating the above information.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;see-also&quot;&gt;See also&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;benkwok.wordpress.com&#x2F;2013&#x2F;08&#x2F;15&#x2F;install-rails-on-ubuntu-12-04-lts-with-rbenv&#x2F;&quot;&gt;http:&#x2F;&#x2F;benkwok.wordpress.com&#x2F;2013&#x2F;08&#x2F;15&#x2F;install-rails-on-ubuntu-12-04-lts-with-rbenv&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asdf-vm&#x2F;asdf&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;asdf-vm&#x2F;asdf&lt;&#x2F;a&gt; &#x2F; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;asdf-vm.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;asdf-vm.com&#x2F;&lt;&#x2F;a&gt; - a version manager for node&#x2F;ruby&#x2F;python&#x2F;etc...&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rvm.io&#x2F;&quot;&gt;https:&#x2F;&#x2F;rvm.io&#x2F;&lt;&#x2F;a&gt; - Ruby Version Manager&lt;&#x2F;li&gt;
&lt;li&gt;Docker - properly isolate all your things - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Docker_%28software%29&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Docker_%28software%29&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Java checked and runtime exceptions and how to transition</title>
        <published>2013-04-02T21:25:00+00:00</published>
        <updated>2013-04-02T21:25:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2013/04/02/java-checked-and-runtime-exceptions-and/"/>
        <id>https://0x5.uk/2013/04/02/java-checked-and-runtime-exceptions-and/</id>
        
        <content type="html" xml:base="https://0x5.uk/2013/04/02/java-checked-and-runtime-exceptions-and/">&lt;p&gt;As primarily a C# programmer I&#x27;ve never been sold on checked exceptions, mostly seeing them as an unnecessary nuisance forcing programmers to introduce reams of boilerplate &lt;code&gt;throws&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;try-catch&lt;&#x2F;code&gt; blocks into their consuming code to propagate these exceptions up the stack.&lt;&#x2F;p&gt;
&lt;p&gt;Whilst coding on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;FreeTTS&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;FreeTTS&lt;&#x2F;a&gt; I was forced to deal with this personal demon.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve read that checked exceptions are a way of making exceptions be part of the declared API for some class or library, and that it forces client programmers to handle error conditions that the API programmer knows are likely to occur (e.g. the library relies on the filesystem internally so declares it throws a &lt;code&gt;IOException&lt;&#x2F;code&gt; when calling a relevant method.&lt;&#x2F;p&gt;
&lt;p&gt;I have some sympathy with this idea and can see how it can allow for more robust code when done well. My experience has generally been that it is not handled well and the reaction is to add a lot of meaningless code or to throw away the exception and hide the problem, causing difficulties troubleshooting later.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;8278346178&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;8337&#x2F;8278346178_3bcf551666.jpg&quot; alt=&quot;Photo of fungus on a tree&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;When I&#x27;ve been in control of the API I&#x27;ve been tempted to always throw runtime exceptions and avoid the problem entirely, however this time whilst working on someone else&#x27;s class I came across a call to an external library that threw an &lt;code&gt;IOException&lt;&#x2F;code&gt; which I couldn&#x27;t change. This made me think a bit harder about the problem. I initially thought my options were to immediately catch and rethrow as a runtime exception or to add &lt;code&gt;throws IOException&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;throws Exception&lt;&#x2F;code&gt; to every piece of the call chain.&lt;&#x2F;p&gt;
&lt;p&gt;I tried the latter approach of propagating the &lt;code&gt;throws&lt;&#x2F;code&gt; up through many layers, which although messy did work; right up until I hit a call within a &lt;code&gt;toString()&lt;&#x2F;code&gt; method, which is defined by &lt;code&gt;Object&lt;&#x2F;code&gt; and doesn&#x27;t allow you to change the API of the method (by adding a checked exception).
Incidentally I think that having &lt;code&gt;toString()&lt;&#x2F;code&gt; rely on code that could throw a file system exception like this did is a dodgy design, but that wasn&#x27;t my code and would have been a large rewrite.&lt;&#x2F;p&gt;
&lt;p&gt;So after a bit of grumbling to myself I looked more closely at the fault line between the checked exception being thrown and the rest of the codebase.
The existing code was just ignoring the error with &lt;code&gt;catch {}&lt;&#x2F;code&gt; (shudder) and returning &lt;code&gt;null&lt;&#x2F;code&gt;, making it hard to troubleshoot a failing JUnit test.&lt;&#x2F;p&gt;
&lt;p&gt;I think the answer to the conundrum is that for each method in the chain you have to decide if callers of the method could usefully handle the error condition, or whether they could add any useful information to the stack trace to assist troubleshooting. Here&#x27;s roughly the approach I&#x27;ve taken which I think should be illustrative:&lt;&#x2F;p&gt;
&lt;p&gt;Method that throws&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;String getSomething(string filename) throws IOException&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; do some file IO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return someData;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next method up. Doesn&#x27;t compile as checked exception not handled, what to do?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;String loadFoo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    String foo = getSomething(&amp;quot;this.txt&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return foo;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case I don&#x27;t think &lt;code&gt;getSomething&lt;&#x2F;code&gt; should be the last point in the chain as it doesn&#x27;t know &lt;em&gt;why&lt;&#x2F;em&gt; it was performing the operation it was. &lt;code&gt;loadFoo&lt;&#x2F;code&gt; however knows both the resource being accessed and what the intent was, so can report an exception message that should point someone troubleshooting immediately to the source of the problem and inform them what the program was trying to achieve. Having &lt;code&gt;loadFoo()&lt;&#x2F;code&gt; declare that it &lt;code&gt;throws IOException&lt;&#x2F;code&gt; doesn&#x27;t make sense as the caller shouldn&#x27;t need to know how &lt;code&gt;loadFoo&lt;&#x2F;code&gt; gets its data, it&#x27;s just the kind of noise that programmers dislike Java for. So the answer in my opinion is because &lt;code&gt;loadFoo()&lt;&#x2F;code&gt; is best placed to give all the useful information needed to fix the problem, it should catch the checked exception, wrap it in a runtime exception, add a useful message and rethrow it. This saves callers from needing to handle exceptions that they can&#x27;t usefully deal with, whilst still providing good troubleshooting information. And yet there&#x27;s still a use for the checked exceptions as &lt;code&gt;getSomething()&lt;&#x2F;code&gt; was able to declare that it knew an &lt;code&gt;IOException&lt;&#x2F;code&gt; was possible but that it wasn&#x27;t in a position to give enough useful information.&lt;&#x2F;p&gt;
&lt;p&gt;So the final code I ended up with looked something like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;String getSomething(string filename) throws IOException&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; do some file IO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return someData;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;String loadFoo()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    String filename = &amp;quot;this.txt&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    try&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        String foo = getSomething(filename);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return foo;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } catch (IOException ex) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        throw new RuntimeException(&amp;quot;Failed to read foo from &amp;#39;&amp;quot; + fileName + &amp;quot;&amp;#39;&amp;quot;, ex);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;inversion-of-control-ioc&quot;&gt;Inversion of control (IoC)&lt;&#x2F;h2&gt;
&lt;p&gt;A colleague of mine mentioned IoC as a problem for checked exceptions. This is an interesting point and does complicate things.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;613954&#x2F;the-case-against-checked-exceptions&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;613954&#x2F;the-case-against-checked-exceptions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;27578&#x2F;when-to-choose-checked-and-unchecked-exceptions&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;27578&#x2F;when-to-choose-checked-and-unchecked-exceptions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;1656376&#x2F;why-are-runtime-exceptions-unchecked-in-java&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;1656376&#x2F;why-are-runtime-exceptions-unchecked-in-java&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;4639432&#x2F;checked-vs-unchecked-exception?rq=1&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;4639432&#x2F;checked-vs-unchecked-exception?rq=1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3613422&#x2F;exception-handling-in-java?rq=1&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3613422&#x2F;exception-handling-in-java?rq=1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;docs.oracle.com&#x2F;javase&#x2F;tutorial&#x2F;essential&#x2F;exceptions&#x2F;runtime.html&quot;&gt;http:&#x2F;&#x2F;docs.oracle.com&#x2F;javase&#x2F;tutorial&#x2F;essential&#x2F;exceptions&#x2F;runtime.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Subversion to git - the pain retold</title>
        <published>2012-12-05T00:33:00+00:00</published>
        <updated>2012-12-05T00:33:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/12/05/subversion-to-git-pain-retold/"/>
        <id>https://0x5.uk/2012/12/05/subversion-to-git-pain-retold/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/12/05/subversion-to-git-pain-retold/">&lt;p&gt;I&#x27;ve spent a week reminding myself why svn sucks.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been using the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;freetts.sourceforge.net&#x2F;&quot;&gt;freetts&lt;&#x2F;a&gt; library for
speech synth in the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;communication-book.wikispaces.com&#x2F;&quot;&gt;communication
book&lt;&#x2F;a&gt; program I&#x27;ve been working on,
and have tripped over a bug in freetts running under openJdk. The freetts
source code lives in a svn repository on sourceforge. The first step in
troubleshooting is to build the library from source. In order to track any
local experimentation &#x2F; fixes I need to have some kind of local source control,
and svn sucks too much to provide this. The obvious next step is to pull the
sources down with git-svn (or svn2git as github recommends).&lt;&#x2F;p&gt;
&lt;p&gt;After a couple of aborted attempts I was reminded how the loosely defined
structure of a svn repository and the over-generalization of tags &amp;amp; branches
allows for a complete mess, which then is a pain to import cleanly.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;And they want to make snapshots of smaller subdirectories of the filesystem.
After all, it&#x27;s not so easy to remember that release 1.0 of a piece of
software is a particular subdirectory of revision 4822.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;~ &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;en&#x2F;1.7&#x2F;svn.branchmerge.tags.html&quot;&gt;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;en&#x2F;1.7&#x2F;svn.branchmerge.tags.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Argh!&lt;&#x2F;strong&gt; Terrible &quot;feature&quot;, if you&#x27;re using this feature then &lt;em&gt;you&#x27;re doing
source control wrong&lt;&#x2F;em&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;I could just grab a tarball and start from there, however there is new code
upstream since their last release (v1.2.2), and that means testing two
branches, and possibly investigating diffs. In addition if I&#x27;m going to make
the effort to import the history, I ought to do it well enough first time that
others can build on it. It&#x27;s much harder to correct a bad scm import once work
is continued, especially in the distributed world of open source.&lt;&#x2F;p&gt;
&lt;p&gt;And so, for my sins, I set about importing the history, and hacking away at it
with the excellent tools git provides to turn it into something that actually
linked together correctly and didn&#x27;t make me feel ill by including CVSROOT all
over the place (yes, it&#x27;s not the first migration this project&#x27;s been through).&lt;&#x2F;p&gt;
&lt;p&gt;On the plus side, it is fantastic that the open source license gives a user of
a library such as myself the right to go ahead and do something like this and
to share the improvement with the world, regardless of whether it&#x27;s something
the original creators &#x2F; maintainers would have done.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;8160450028&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;7271&#x2F;8160450028_af1097a2f7.jpg&quot;
alt=&quot;Photo of lake, trees and ducks at sunset&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The layout of the FreeTTS svn repo is not consistent in directory structure,
which means the svn import tools don&#x27;t behave quite as one might expect. This
is the inevitable downside to subversions poor choice of architecture around
&quot;everything&#x27;s just a directory structure&quot;. (Bitter? Me? Never!)&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a taster of how inconsistent the layout is and what a challenge is ahead
tidying it up:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@atom:~&#x2F;repo&#x2F;freetts.svn$ ls *&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;branches&#x2F;release:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;freetts:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;pre-rel1-1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;rel_1_0_5:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CVSROOT FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;rel1_1_0:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;rel1_1_2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;rel1_2_0:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CVSROOT FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;rel1_2_1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;rel1_2_2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;acknowledgments.txt build.xml demo.xml index.html license.terms overview.html RELEASE_NOTES speech.properties tests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ANNOUNCE.txt demo docs lib mbrola README.txt rtp src tools&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;rel_1_2_beta:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;rel1_2beta2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CVSROOT FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;start:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags&#x2F;sun:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;trunk&#x2F;CVSROOT:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;checkoutlist commitinfo config cvsignore cvswrappers editinfo loginfo modules notify rcsinfo syncmail taginfo verifymsg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;trunk&#x2F;FreeTTS:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;acknowledgments.txt build.xml demo.xml index.html license.terms overview.html RELEASE_NOTES speech.properties tools&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ANNOUNCE.txt demo docs lib mbrola README.txt rtp src unittests&amp;lt;&#x2F;span&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It took all my git-fu powers to sort out this mess. Below is a time shortened
sequence of how it was done, just in case I have the misfortune to need to do
it again. I ended up abandoning all the ancient tags as they were going to be
more effort than I liked to fix, and they could be added retrospectively if
anyone really cared. It took me many attempts to get to the below, and this is
what I&#x27;ve reconstructed from my fragmented history, hopefully it will provide
enough clues should you wish to do similar.&lt;&#x2F;p&gt;
&lt;p&gt;FreeTTS project urls:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Project front page &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;freetts.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;freetts.sourceforge.net&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;project site &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;freetts&#x2F;&quot;&gt;http:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;freetts&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;repo browser &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;freetts.svn.sourceforge.net&#x2F;viewvc&#x2F;freetts&#x2F;&quot;&gt;http:&#x2F;&#x2F;freetts.svn.sourceforge.net&#x2F;viewvc&#x2F;freetts&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;svn http access &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;freetts.svn.sourceforge.net&#x2F;svnroot&#x2F;freetts&#x2F;&quot;&gt;https:&#x2F;&#x2F;freetts.svn.sourceforge.net&#x2F;svnroot&#x2F;freetts&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;At time of writing the current svn revision is 582.&lt;&#x2F;p&gt;
&lt;p&gt;The latest packaged version for ubuntu:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**apt-cache show freetts**Package: freetts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Priority: optional&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section: universe&#x2F;java&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Installed-Size: 13532&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Maintainer: Ubuntu Developers &amp;lt;[ubuntu-devel-discuss@lists.ubuntu.com&amp;gt;](http:&#x2F;&#x2F;www.blogger.com&#x2F;ubuntu-devel-discuss@lists.ubuntu.com%3E)Original-Maintainer: Bdale Garbee &amp;lt;[bdale@gag.com&amp;gt;](http:&#x2F;&#x2F;www.blogger.com&#x2F;bdale@gag.com%3E)Architecture: all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**Version: 1.2.2-3**Depends: default-jre | java2-runtime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filename: pool&#x2F;universe&#x2F;f&#x2F;freetts&#x2F;freetts_1.2.2-3_all.deb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Size: 9456904&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MD5sum: 183bed09b1b8e2d8642f46b7538273f4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHA1: 8df47df82124704b890f446a1bc958d33fd273d3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHA256: 8920440eaa58c087cb268e8e2a64d44ac873fb44d49b34f180f587f9c69421a7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Description-en: speech synthesis system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FreeTTS is a speech synthesis system written entirely in the Java(TM)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;programming language. It is based upon Flite, a small run-time speech&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;synthesis engine developed at Carnegie Mellon University. Flite in turn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is derived from the Festival Speech Synthesis System from the University&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;of Edinburgh and the FestVox project from Carnegie Mellon University.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Homepage: [http:&#x2F;&#x2F;freetts.sourceforge.net](http:&#x2F;&#x2F;freetts.sourceforge.net&#x2F;)Description-md5: a346fe6dcc2c0164ec6b7c3891945e56&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Bugs: [https:&#x2F;&#x2F;bugs.launchpad.net&#x2F;ubuntu&#x2F;+filebug](https:&#x2F;&#x2F;bugs.launchpad.net&#x2F;ubuntu&#x2F;+filebug)Origin: Ubuntu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So here&#x27;s the import more or less as it happened:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir freetts.svn.git; cd freetts.svn.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn2git --verbose (https:&#x2F;&#x2F;freetts.svn.sourceforge.net&#x2F;svnroot&#x2F;freetts&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git gc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cat .git&#x2F;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; [core]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  repositoryformatversion = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  filemode = true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  bare = false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  logallrefupdates = true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; [svn-remote &amp;quot;svn&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  noMetadata = 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  url = [https:&#x2F;&#x2F;freetts.svn.sourceforge.net&#x2F;svnroot&#x2F;freetts](https:&#x2F;&#x2F;freetts.svn.sourceforge.net&#x2F;svnroot&#x2F;freetts) fetch = trunk:refs&#x2F;remotes&#x2F;svn&#x2F;trunk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  branches = branches&#x2F;*:refs&#x2F;remotes&#x2F;svn&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  tags = tags&#x2F;*:refs&#x2F;remotes&#x2F;svn&#x2F;tags&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; [branch &amp;quot;release&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  remote = .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  merge = refs&#x2F;remotes&#x2F;svn&#x2F;release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;get a copy without the svn references (which stop us seeing whether the rewritten history is free of old cruft)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git clone freetts.svn.git&#x2F; freetts.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd freetts.git&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gitk --all &amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**# The following is done while keeping an eye on and refreshing (ctrl+f5) gitk to see the effects:**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Filter out the cvs rubbish so that git can match up commits that do have it with commits that don&amp;#39;t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git filter-branch --tree-filter &amp;#39;rm -rf CVSROOT&amp;#39; --prune-empty -- --all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Remove the unnecessary top level folder (which inconsistently existed)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git filter-branch --prune-empty --subdirectory-filter FreeTTS&#x2F; -- --all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Remove the backup refs filter-branch creates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rm -rf .git&#x2F;refs&#x2F;original&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;delete all the crappy svn &quot;tags&quot;, just tag the latest&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git tag -d `git tag`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;freetts&amp;#39; (was 8d953b7)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;pre-rel1-1&amp;#39; (was d1c597f)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel1_1_0&amp;#39; (was 625abdd)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel1_1_2&amp;#39; (was b51fb71)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel1_2_0&amp;#39; (was 7a4fc18)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel1_2_1&amp;#39; (was a126a4a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel1_2_2&amp;#39; (was b3a0dcf)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel1_2_2@557&amp;#39; (was bf94dbe)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel1_2beta2&amp;#39; (was c0d90e9)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel_1_0_5&amp;#39; (was e95aff8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;rel_1_2_beta&amp;#39; (was 1723b2d)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;start&amp;#39; (was c020efe)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deleted tag &amp;#39;sun&amp;#39; (was cfadbc8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;correct commit found manually:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git tag v1.2.2 ae49425&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and finally, push to github&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git remote add origin .... (my repo details)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git push --mirror&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can find my repo at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;FreeTTS&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;FreeTTS&lt;&#x2F;a&gt;
and the intermediate copy here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;FreeTTS-svn-mirror&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;FreeTTS-svn-mirror&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;All done&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;^_^&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the reason I didn&#x27;t bother with tags in the end: I couldn&#x27;t rewrite the
tags as they had no author:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git filter-branch --tree-filter &amp;#39;rm -rf CVSROOT&amp;#39; --prune-empty --tag-name-filter cat -- --tags&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cannot create a new backup.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A previous backup already exists in refs&#x2F;original&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Force overwriting the backup with -f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@atom:~&#x2F;repo&#x2F;freetts.git$ rm -rf .git&#x2F;refs&#x2F;original&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@atom:~&#x2F;repo&#x2F;freetts.git$ git filter-branch --tree-filter &amp;#39;rm -rf CVSROOT&amp;#39; --prune-empty --tag-name-filter cat -- --tags&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Rewrite 8611e271692fc33e6160a2a217b9b3060dfbcd1d (1044&#x2F;1044)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;freetts&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING: Ref &amp;#39;refs&#x2F;tags&#x2F;pre-rel1-1&amp;#39; is unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING: Ref &amp;#39;refs&#x2F;tags&#x2F;rel1_1_0&amp;#39; is unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;rel1_1_2&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;rel1_2_0&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;rel1_2_1&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;rel1_2_2&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;rel1_2_2@557&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;rel1_2beta2&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;rel_1_0_5&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;rel_1_2_beta&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;start&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ref &amp;#39;refs&#x2F;tags&#x2F;sun&amp;#39; was rewritten&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;freetts -&amp;gt; freetts (b3a4bbf8768ade6275c91ce0e76d933e30b3ddbf -&amp;gt; 48e84e3560e765db3b33479e2e9a76fe2ccf3550)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**error: char79: malformed tagger field&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fatal: invalid tag signature file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Could not create new tag object for freetts**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git show rel_1_2_beta | head&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tag rel_1_2_beta&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**Tagger: (no author) &amp;lt;(no author)@4963320b-1a4a-0410-81c8-f0a525965860&amp;gt;**Date: Mon Dec 22 14:46:05 2003 +0000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;This commit was manufactured by cvs2svn to create tag &amp;#39;\&amp;#39;&amp;#39;rel_1_2_beta&amp;#39;\&amp;#39;&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;commit 57ed00e981585aad590c9521d7c3a0bccf6284fa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Author: (no author) &amp;lt;(no author)@4963320b-1a4a-0410-81c8-f0a525965860&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Date: Mon Dec 22 14:46:05 2003 +0000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;My advice if you are importing svn for a commercial project: Don&#x27;t! Just export, and import into your new source control tool. Leave the svn repo read only for a while just in case you need that history, and after a year of never looking back, archive it off.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>AA Gold member benefits, the real cost</title>
        <published>2012-07-10T19:13:00+00:00</published>
        <updated>2012-07-10T19:13:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/07/10/aa-gold-member-benefits-real-cost/"/>
        <id>https://0x5.uk/2012/07/10/aa-gold-member-benefits-real-cost/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/07/10/aa-gold-member-benefits-real-cost/">&lt;h1 id=&quot;breakdown-cover-maths&quot;&gt;Breakdown cover maths&lt;&#x2F;h1&gt;
&lt;p&gt;So, I&#x27;m getting rather fed up with the AA taking the michael every year with
their renewals. Yes, I gather the RAC are just as bad but I think they need to
realise their customers aren&#x27;t stupid, know exactly what they are playing at,
and can do the maths.&lt;&#x2F;p&gt;
&lt;p&gt;I want to highlight what I think is a particularly dirty trick, making
something look like a free perk when it&#x27;s anything but.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;so-here-s-some-numbers&quot;&gt;So here&#x27;s some numbers:&lt;&#x2F;h1&gt;
&lt;p&gt;This is for a single car policy covering Roadside, Home Start and Relay
starting July 2012 paying annually for a year up front. (The monthly option is
10% more expensive, go figure). Numbers rounded to pounds.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Renewal through the post: &lt;strong&gt;£135&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Matching &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.rac.co.uk&#x2F;uk-breakdown&#x2F;&quot;&gt;RAC cover&lt;&#x2F;a&gt;(checked online &amp;amp;
by phone): &lt;strong&gt;£101&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.theaa.com&#x2F;breakdown-cover&#x2F;uk-breakdown&#x2F;view-options.do?optMshp=vcon300&quot;&gt;AA online
price&lt;&#x2F;a&gt;
for new customers: &lt;strong&gt;£92&lt;&#x2F;strong&gt; -(so much for 6 years loyalty, a &lt;strong&gt;&lt;span
style=&quot;color: red;&quot;&gt;£43&lt;&#x2F;span&gt;&lt;&#x2F;strong&gt; kick in the teeth)&lt;&#x2F;li&gt;
&lt;li&gt;AA phone price: &lt;strong&gt;£116&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;AA phone price &lt;em&gt;without gold membership &quot;benefits&quot;&lt;&#x2F;em&gt;: &lt;strong&gt;£89&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That means, the AA are pricing their gold benefits at &lt;strong&gt;&lt;span style=&quot;color:
red;&quot;&gt;£27&lt;&#x2F;span&gt;&lt;&#x2F;strong&gt; even though they look like they are free on the renewal
letter! Some cheek.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;aa-renewal-letter.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I queried the details of this so called benefit and established the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&quot;Accident Management&quot;&lt;&#x2F;em&gt; - means being towed by the AA after an accident
(something you may be covered for under your car insurance policy)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;European Breakdown Cover&lt;&#x2F;em&gt; - only useful if you are going abroad
(obviously), did you really want to be paying for it?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&quot;Family Associates Cover for under 17s&quot;&lt;&#x2F;em&gt; - something about teenagers, I
don&#x27;t have any so not very useful to me&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Key Insurance&lt;&#x2F;em&gt; - this could be valuable, but £27&#x2F;year sounds like very
expensive insurance to me even though they are expensive items to replace.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Legal Advice&lt;&#x2F;em&gt; - &lt;strong&gt;Included as standard!&lt;&#x2F;strong&gt; So not a gold benefit at all.
Weasels.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Technical Advice&lt;&#x2F;em&gt; - &lt;strong&gt;Included as standard!&lt;&#x2F;strong&gt; See above. Still weasels.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So it turns out that the supposed discount of &lt;strong&gt;£44.90&lt;&#x2F;strong&gt; on the posted renewal
was actually a &lt;strong&gt;&lt;span style=&quot;color: red;&quot;&gt;£46&lt;&#x2F;span&gt;&lt;&#x2F;strong&gt; insult to my
intelligence.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m no money saving expert, but that&#x27;s outrageous.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Configuration confusion in visual studio</title>
        <published>2012-07-10T14:43:00.001+00:00</published>
        <updated>2012-07-10T14:43:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/07/10/configuration-confusion-in-visual/"/>
        <id>https://0x5.uk/2012/07/10/configuration-confusion-in-visual/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/07/10/configuration-confusion-in-visual/">&lt;p&gt;Here&#x27;s a gotcha that got me.&lt;&#x2F;p&gt;
&lt;p&gt;It is not immediately obvious, but visual studio stores in it&#x27;s sln file a set
of project configuration selections for every combination of solution
configuration and solution platform.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;visual-studio-platform-selection.PNG&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The gotcha is that by default Visual Studio (all versions 2008-2012 as far as I
know) only show one half of that combination in the standard toolbar, so you
can get in a situation where one of your developers is building something
completely different to everyone else as somehow the platform has silently been
changed.&lt;&#x2F;p&gt;
&lt;p&gt;I recommend you add Platform to your toolbar so that you can &lt;em&gt;always&lt;&#x2F;em&gt; see what
you are about to build.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;visual-studio-platform-toolbar.PNG&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;visual-studio-platform-command.PNG&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And if possible, remove any unused platform configurations from your solution
entirely.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>automatic mysql backups</title>
        <published>2012-06-14T15:10:00+00:00</published>
        <updated>2012-06-14T15:10:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/06/14/automatic-mysql-backups/"/>
        <id>https://0x5.uk/2012/06/14/automatic-mysql-backups/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/06/14/automatic-mysql-backups/">&lt;p&gt;On a debian server with mediawiki installed and running with a local mysql.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@myserver:~# apt-get install automysqlbackup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@myserver:~# crontab -e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# m  h  dom mon dow   command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  5  4  *   *   *     automysqlbackup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@myserver:~# automysqlbackup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@myserver:~# cd &#x2F;var&#x2F;lib&#x2F;automysqlbackup&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@myserver:&#x2F;var&#x2F;lib&#x2F;automysqlbackup# find .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;weekly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;weekly&#x2F;wikidb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;weekly&#x2F;information_schema&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;daily&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;daily&#x2F;wikidb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;daily&#x2F;wikidb&#x2F;wikidb_2012-06-14_16h03m.Thursday.sql.gz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;daily&#x2F;information_schema&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;daily&#x2F;information_schema&#x2F;information_schema_2012-06-14_16h03m.Thursday.sql.gz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;monthly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Result! No longer need to write a custom cron script each time.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;7255107648&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;7226&#x2F;7255107648_929530d9e0.jpg&quot; alt=&quot;Ducklings at henley-on-thames&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Project homepage:
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;automysqlbackup&#x2F;&quot;&gt;http:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;automysqlbackup&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Connecting to smb shares on a domain in gnome</title>
        <published>2012-06-11T18:17:00.001+00:00</published>
        <updated>2012-06-11T18:17:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/06/11/connecting-to-smb-shares-on-domain-in/"/>
        <id>https://0x5.uk/2012/06/11/connecting-to-smb-shares-on-domain-in/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/06/11/connecting-to-smb-shares-on-domain-in/">&lt;p&gt;The domain name has to be UPPERCASE otherwise authentication fails.&lt;&#x2F;p&gt;
&lt;p&gt;Majorly confusing.&lt;&#x2F;p&gt;
&lt;p&gt;Time lost: 3 hours.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;smb-domain.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sigh&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Debugging stored procedures in VS2010 &#x2F; SQL Express</title>
        <published>2012-05-22T16:58:00+00:00</published>
        <updated>2012-05-22T16:58:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/05/22/debugging-stored-procedures-in-vs2010/"/>
        <id>https://0x5.uk/2012/05/22/debugging-stored-procedures-in-vs2010/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/05/22/debugging-stored-procedures-in-vs2010/">&lt;p&gt;Debugging stored procs in a &lt;em&gt;local&lt;&#x2F;em&gt; SQL Express install with Visual Studio
2010.&lt;&#x2F;p&gt;
&lt;p&gt;Enable TCP&#x2F;IP - see &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;timwise.blogspot.co.uk&#x2F;2012&#x2F;05&#x2F;enabling-tcpip-in-sql-express-2008-r2.html&quot;&gt;http:&#x2F;&#x2F;timwise.blogspot.co.uk&#x2F;2012&#x2F;05&#x2F;enabling-tcpip-in-sql-express-2008-r2.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In Visual Studio, Server Explorer, Connect to your server as localhost instead
of .\SQLEXPRESS so that you connect through TCP&#x2F;IP and not shared memory (which
doesn&#x27;t allow debugging for some reason)&lt;&#x2F;p&gt;
&lt;p&gt;Find the project in your solution which actually executes the stored procedure,
right-click &amp;gt; properties &amp;gt; debug &amp;gt; &quot;Enable SQL Server debugging&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Run your project&lt;&#x2F;p&gt;
&lt;p&gt;You may need to hit &quot;stop&quot; and re-attached (debug &amp;gt; attach to process)
explicitly selecting &quot;T-SQL code&quot; in the &quot;attach to&quot; box (and optionally
managed as well). It &lt;em&gt;should&lt;&#x2F;em&gt; automatically select T-SQL but it seems to be hit
and miss.&lt;&#x2F;p&gt;
&lt;p&gt;Set a breakpoint in your stored procedure:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Server explorer,&lt;&#x2F;li&gt;
&lt;li&gt;the connection you added,&lt;&#x2F;li&gt;
&lt;li&gt;stored procs,&lt;&#x2F;li&gt;
&lt;li&gt;right-click the proc name &amp;gt; open&lt;&#x2F;li&gt;
&lt;li&gt;set a break point in the text of the stored proc&lt;&#x2F;li&gt;
&lt;li&gt;if it is not a solid red dot then something went wrong&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Run the part of your program &#x2F; website that will cause the proc to be called.&lt;&#x2F;p&gt;
&lt;p&gt;If the breakpoint isn&#x27;t hit check the type&#x27;s in the attach to process list
include T-SQL (doesn&#x27;t seem to always work).&lt;&#x2F;p&gt;
&lt;p&gt;I only got the damn thing to work once. If it doesn&#x27;t work you get no reason at
all which is just crap. The main problem I have is that the attach just quietly
drops T-SQL even if you explicitly request it. Shoddy coding from Microsoft in
my opinion.&lt;&#x2F;p&gt;
&lt;p&gt;The next best thing is to right-click the stored proc, click &quot;step into&quot; and
input the values manually. (Which also requires a tcp&#x2F;ip connection to the
local sql express and is fussy).&lt;&#x2F;p&gt;
&lt;p&gt;Another message encountered a couple of days later without changing anything at
all when attaching to the already running web dev process: &quot;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;ms241735(v=vs.100).aspx&quot;&gt;&lt;span
id=&quot;goog_211408035&quot;&gt;&lt;&#x2F;span&gt;User Could Not Execute Stored Procedure
sp_enable_sql_debug&lt;span
id=&quot;goog_211408036&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;&quot;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;4737175&#x2F;the-breakpoint-will-not-currently-be-hit-error-when-trying-to-debug-a-tsql&quot;&gt;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;4737175&#x2F;the-breakpoint-will-not-currently-be-hit-error-when-trying-to-debug-a-tsql&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;social.msdn.microsoft.com&#x2F;forums&#x2F;en-US&#x2F;vstsdb&#x2F;thread&#x2F;f5247d99-06f0-4ae3-9371-04c70f750647&#x2F;&quot;&gt;http:&#x2F;&#x2F;social.msdn.microsoft.com&#x2F;forums&#x2F;en-US&#x2F;vstsdb&#x2F;thread&#x2F;f5247d99-06f0-4ae3-9371-04c70f750647&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;support.microsoft.com&#x2F;kb&#x2F;316549&#x2F;en-us&quot;&gt;http:&#x2F;&#x2F;support.microsoft.com&#x2F;kb&#x2F;316549&#x2F;en-us&lt;&#x2F;a&gt;
(from comment below)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;screenshots&quot;&gt;Screenshots&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;debug-t-sql-attach.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;debug-t-sql-connect.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;debug-t-sql-project.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;debug-t-sql-open.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;debug-t-sql-step.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Enabling TCP&#x2F;IP in SQL Express 2008 R2</title>
        <published>2012-05-22T11:10:00.001+00:00</published>
        <updated>2012-05-22T11:10:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/05/22/enabling-tcpip-in-sql-express-2008-r2/"/>
        <id>https://0x5.uk/2012/05/22/enabling-tcpip-in-sql-express-2008-r2/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/05/22/enabling-tcpip-in-sql-express-2008-r2/">&lt;p&gt;Programs &amp;gt; .. R2 &amp;gt; SQL Server Configuration Manager
Network config &amp;gt; Protocols &amp;gt; tcp&#x2F;ip &amp;gt; enable &amp;amp; properties&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;sql-express-tcp-ip.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Clear the dynamic port under IPAll
Set the TCP Port to 1433 (which is the standard sql server port).&lt;&#x2F;p&gt;
&lt;p&gt;You can then connect to &quot;localhost&quot; (with no instance specified) in management studio.&lt;&#x2F;p&gt;
&lt;p&gt;refs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vgoes.wordpress.com&#x2F;2007&#x2F;06&#x2F;05&#x2F;jdbc-to-sql-server-express&#x2F;&quot;&gt;https:&#x2F;&#x2F;vgoes.wordpress.com&#x2F;2007&#x2F;06&#x2F;05&#x2F;jdbc-to-sql-server-express&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running IE Application Compatibility VPC under Virtual Box</title>
        <published>2012-04-18T21:59:00.005+00:00</published>
        <updated>2012-04-18T21:59:00.005+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/04/18/running-ie-application-compatibility/"/>
        <id>https://0x5.uk/2012/04/18/running-ie-application-compatibility/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/04/18/running-ie-application-compatibility/">&lt;p&gt;This post is no longer necessary as microsoft now provide official virtualbox
images, yay!
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.modern.ie&#x2F;en-us&#x2F;virtualization-tools#downloads&quot;&gt;http:&#x2F;&#x2F;www.modern.ie&#x2F;en-us&#x2F;virtualization-tools#downloads&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Microsoft provide Virtual PC images for testing your website with IE. You can
download them from
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.microsoft.com&#x2F;download&#x2F;en&#x2F;details.aspx?id=11575&quot;&gt;http:&#x2F;&#x2F;www.microsoft.com&#x2F;download&#x2F;en&#x2F;details.aspx?id=11575&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that the XP image has no expired so is no use, it will reboot immediately
after login.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to make use of the Win 7 &#x2F; IE 9 image, however Virtual PC is
unavailable on Linux. Fortunately VirtualBox can mount Virtual PC&#x27;s disk
images.&lt;&#x2F;p&gt;
&lt;p&gt;For me the image would get half way through booting windows, and then
blue-screen (BSOD). I discovered that it was possible to get past this by
removing the SATA controller the machine&#x27;s settings, and instead adding the
disk under the IDE controller. After that the machine booted successfully.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;sata-controller.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Capturing the BSOD, basically press F8 after a lot rebooting, and select
&quot;disable automatic restart on system failure&quot; (ref:
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.webtlk.com&#x2F;2009&#x2F;07&#x2F;02&#x2F;how-to-stop-windows-7-reboot-loop&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.webtlk.com&#x2F;2009&#x2F;07&#x2F;02&#x2F;how-to-stop-windows-7-reboot-loop&#x2F;&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;bsod-reboot-prevention-F8.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;bsod.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Poll svn server for changes with git clone</title>
        <published>2012-04-05T15:45:00.006+00:00</published>
        <updated>2012-04-05T15:45:00.006+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/04/05/poll-svn-server-for-changes-with-git/"/>
        <id>https://0x5.uk/2012/04/05/poll-svn-server-for-changes-with-git/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/04/05/poll-svn-server-for-changes-with-git/">&lt;p&gt;Just for convenience, paste this in a git bash window:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;while true; do date; echo &amp;quot;Polling svn server...&amp;quot;; git svn fetch;echo &amp;quot;Sleeping.&amp;quot;; sleep 300; done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;poll-svn_catch.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then just refresh your favourite git log viewer.&lt;&#x2F;p&gt;
&lt;p&gt;Get the gist: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;2353631&quot;&gt;poll-svn.sh gist&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s all folks!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Announcing the Communication Book project</title>
        <published>2012-03-21T21:04:00.004+00:00</published>
        <updated>2012-03-21T21:04:00.004+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/03/21/announcing-communication-book-project/"/>
        <id>https://0x5.uk/2012/03/21/announcing-communication-book-project/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/03/21/announcing-communication-book-project/">&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;screenshot_v0.3-r34.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been working on a piece of open source software to assist people who have
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Aphasia&quot;&gt;aphasia&lt;&#x2F;a&gt; (speech difficulties), and it
is now sufficiently functional to be worth mentioning. It&#x27;s still very rough
around the edges, but if you are on a debian based system you should be able to
easily get it up and running and see what you think. If you are on other
platforms you&#x27;ll currently need a bit (alright, a lot) of java knowledge to get
this up and running.&lt;&#x2F;p&gt;
&lt;p&gt;If you have the time to help I&#x27;d be very grateful. You don&#x27;t have to be a
coder, just letting me know if it works for you would be great.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to know more or would like to give it a try then please do head
over to the project page at
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;launchpad.net&#x2F;communication&quot;&gt;http:&#x2F;&#x2F;launchpad.net&#x2F;communication&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Quote of the day - scrum progress updates</title>
        <published>2012-02-14T10:30:00.001+00:00</published>
        <updated>2012-02-14T10:30:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/02/14/quote-scrum-progress-updates/"/>
        <id>https://0x5.uk/2012/02/14/quote-scrum-progress-updates/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/02/14/quote-scrum-progress-updates/">&lt;p&gt;Quote of the day&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.scrumalliance.org&#x2F;profiles&#x2F;14884-mikko-wilkman&quot;&gt;Mikko Wilkman&lt;&#x2F;a&gt; said
on 05 Jan 09 07:15:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;... Even a one hour task might change to an eight hour task (or multiple
tasks..) due to new information found out during that one hour that was the
original estimate. The key point is not to focus on how many hours the team
got done on the task, but how many hours really are remaining. The daily
update should never be: &quot;I worked on that for four hours, so you can take
four hours out of the estimate&quot;, but rather a real estimate on how much work
still needs to be done based on current knowledge.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;from
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.scrumalliance.org&#x2F;articles&#x2F;39-glossary-of-scrum-terms#1110&quot;&gt;http:&#x2F;&#x2F;www.scrumalliance.org&#x2F;articles&#x2F;39-glossary-of-scrum-terms#1110&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The BBC and the bouncing emails</title>
        <published>2012-01-25T21:22:00.001+00:00</published>
        <updated>2012-01-25T21:22:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/01/25/bbc-and-bouncing-emails/"/>
        <id>https://0x5.uk/2012/01/25/bbc-and-bouncing-emails/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/01/25/bbc-and-bouncing-emails/">&lt;p&gt;For the record, this is the staggering response I received from the BBC&#x27;s iPlayer support when I helpfully let them know that the email address they use as sender when responding to feedback sent through their support web form is non-deliverable.&lt;&#x2F;p&gt;
&lt;p&gt;I think it speaks for itself. You would at least think they would set the sender address to &quot;noreply-werenotlistening-lalala@bbc.co.uk&quot; so you wouldn&#x27;t waste time composing a response. And if you&#x27;ve been through the web form, you will know that filling it out once is okay, but to use it to reply? Give over!&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;-------- Original Message --------&lt;br &#x2F;&gt;
Subject: BBC iPlayer - Case number CAS-1258137-Q271CZ&lt;br &#x2F;&gt;
Date: 24 Jan 2012 10:19:09 +0000&lt;br &#x2F;&gt;
From: bbc_iplayer_website@bbc.co.uk&lt;br &#x2F;&gt;
To: tim abell&lt;&#x2F;p&gt;
&lt;p&gt;Dear Mr Abell&lt;&#x2F;p&gt;
&lt;p&gt;Reference CAS-1258137-Q271CZ&lt;&#x2F;p&gt;
&lt;p&gt;Thank you for contacting the BBC iPlayer support team.&lt;&#x2F;p&gt;
&lt;p&gt;I understand you’re unhappy that the reply email you had sent to our email bounced.&lt;&#x2F;p&gt;
&lt;p&gt;I’m afraid it is not possible to reply to our email because we deal with over a million audience contacts every year and we have to ensure they can be efficiently tracked using our handling system and therefore for every correspondence you need to fill the webform. In addition, our complaints, BBC iPlayer and general enquiries webforms ask for essential information such as channel, programme name and transmission date which means we don&#x27;t have to write back to people unnecessarily. Using a webform also guarantees we can match a return contact up with the previous contact from that person without the need to cross-check thousands of unformatted emails which would then have to be manually transferred into the tracking system.&lt;&#x2F;p&gt;
&lt;p&gt;We try to restrict public email inbox addresses where possible because we receive millions of &#x27;spam&#x27; e-mails and a return email address would attract and generate even more. Junk mail costs the BBC a considerable amount of money because every email has to be checked before we can delete them as it’s not always easy to distinguish them from a genuine email.&lt;&#x2F;p&gt;
&lt;p&gt;I appreciate this may be annoying, but we did not take this decision lightly. Our policy takes into account what is operationally efficient and avoids the need to employ additional staff to process incoming emails. I would therefore ask that you please follow the instructions in the reply you received and use our online form at www.bbc.co.uk&#x2F;complaints. Your email will then be passed to a member of our team for further investigation and reply.&lt;&#x2F;p&gt;
&lt;p&gt;Once again thank you for contacting BBC iPlayer.&lt;&#x2F;p&gt;
&lt;p&gt;Kind Regards&lt;br &#x2F;&gt;
Usha Devi Peri&lt;br &#x2F;&gt;
BBC Audience Services&lt;br &#x2F;&gt;
www.bbc.co.uk&#x2F;iplayer&lt;&#x2F;p&gt;
&lt;p&gt;NB This is sent from an outgoing account only which is not monitored. You cannot reply to this email address but if necessary please contact us via our webform quoting any case number we provided.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;And here is the bounce, so you can see why I thought they had made a mistake:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Subject: Undelivered Mail Returned to Sender&lt;br &#x2F;&gt;
Date: Sat, 21 Jan 2012 07:42:07 -0500 (EST)&lt;br &#x2F;&gt;
From: MAILER-DAEMON (Mail Delivery System)&lt;br &#x2F;&gt;
To: tim@timwise.co.uk&lt;&#x2F;p&gt;
&lt;p&gt;This is the Postfix program at host mxout-07.mxes.net. I&#x27;m sorry to have to inform you that your message could not be delivered to one or more recipients. Here is the reason why the message could not be delivered. &lt;a href=&quot;mailto:bbc_iplayer_website@bbc.co.uk&quot;&gt;bbc_iplayer_website@bbc.co.uk&lt;&#x2F;a&gt;: host cluster1.eu.messagelabs.com[195.245.231.99] said: 550-Invalid recipient &lt;a href=&quot;mailto:bbc_iplayer_website@bbc.co.uk&quot;&gt;bbc_iplayer_website@bbc.co.uk&lt;&#x2F;a&gt; 550 (#5.1.1) (in reply to RCPT TO command)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The trouble with agile is it&#x27;s a bit too good</title>
        <published>2012-01-17T03:21:00.013+00:00</published>
        <updated>2012-01-17T03:21:00.013+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/01/17/trouble-with-agile-is-its-bit-too-good/"/>
        <id>https://0x5.uk/2012/01/17/trouble-with-agile-is-its-bit-too-good/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/01/17/trouble-with-agile-is-its-bit-too-good/">&lt;p&gt;So you&#x27;ve gone &lt;strong&gt;Agile!&lt;&#x2F;strong&gt; Woo! Well done! You&#x27;ve escaped the last millennium&#x27;s
software practices at last! And boy do you feel in &lt;em&gt;control&lt;&#x2F;em&gt; at last! The
iterations are flying past, the story points are getting done at a rate you
could only have dreamt of. No longer do you wonder what your development team
are up to for months at a time, with that nagging feeling that you are pouring
money in and you&#x27;re not getting best &quot;value&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Seems like some kind of productivity utopia doesn&#x27;t it?&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;6606813059&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;7172&#x2F;6606813059_304696d41b.jpg&quot; alt=&quot;Photo of a waterfall in Wales&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;But there&#x27;s still something not quite right isn&#x27;t there? Are the technical team
&lt;em&gt;still&lt;&#x2F;em&gt; moaning (pah, that&#x27;s just technical people isn&#x27;t it? ... or is it? they
often have a point, just usually a difficult one). There&#x27;s this thing they are
always going on about, maybe it changes day to day, maybe it&#x27;s the same. Maybe
it doesn&#x27;t seem well enough defined to &lt;em&gt;deserve&lt;&#x2F;em&gt; a story. Maybe it just some
long term gripe that&#x27;s never quite as important as all those other items in the
backlog that have a priority of &quot;O.M.G. if we don&#x27;t do this by the 14th of this
month we&#x27;re all DEAD!!$$£##£!!!&quot;, so it keeps getting barely scheduled and
certainly never &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;codebetter.com&#x2F;jeremymiller&#x2F;2006&#x2F;04&#x2F;14&#x2F;code-complete-is-a-lie-done-done-done-is-the-truth&#x2F;&quot;&gt;done, done,
done&lt;&#x2F;a&gt;!
(Okay, calm down excitable agile people, saying it once is fine.) But hey
&lt;em&gt;that&#x27;s the process&lt;&#x2F;em&gt; so it must be right, if it doesn&#x27;t make it, it &lt;em&gt;can&#x27;t&lt;&#x2F;em&gt;
have been that important. Can it?&lt;&#x2F;p&gt;
&lt;p&gt;Well, it&#x27;s time for some unscientific theorizing.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;6597177893&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;7151&#x2F;6597177893_1b72a38092.jpg&quot; alt=&quot;Atomospheric photo of clouds&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I&#x27;ve been doing a bit of job hopping recently (nothing on the scale of
contracting, but I&#x27;ve seen a few different things, and a few different
approaches to project management). And I&#x27;ve noticed something in the two
examples of agile
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scrum_%28development%29&quot;&gt;SCRUM&lt;&#x2F;a&gt; specifically)
I&#x27;ve been close to that bothers me.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“When it comes to the detail of the work, the manager is relying on the
expertise of their staff.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;As a bit of background, remember that software development is a highly skilled
job. Software development is one of those funny worlds of work where the
employee inevitably knows more than the manager. The manager will likely have
more broad context (I really hope so, for that matter), but when it comes to
the detail of the work, and the &lt;em&gt;right&lt;&#x2F;em&gt; thing to do, the manager is relying on
the expertise of their staff to make detailed decisions. This is as it should
be given that the developers spend all their working hours, often more,
immersed in the detail, keeping up with the current technology, and becoming
ever more skilled at the job. Even if a manager is initially just as
knowledgeable in the field as their staff, just by virtue of spending more time
managing than doing (nothing wrong with that of course), they will inevitably
become less knowledgeable than their developers over time (whether they admit
it or not, and don&#x27;t we all know someone who still thinks they know
everything!)&lt;&#x2F;p&gt;
&lt;p&gt;Okay, I&#x27;ll get to the point already (this had better be good).&lt;&#x2F;p&gt;
&lt;p&gt;If you have moved from one of the less well controlled project management
methods (including the &quot;general panic&quot; approach), then you may or may not have
realised that &lt;strong&gt;a fundamental shift in power has occurred&lt;&#x2F;strong&gt;. The ability to
direct the way your development team spends their time has moved more into the
hands of the manager, and away from the hands of the individual developers. On
the whole I consider this a good thing, as individual developers deciding to do
things by fiat doesn&#x27;t always help a company with its immediate deadlines, and
there is a much improved ability under the new regime to pick a goal and get
there more or less on time (unless you are just paying lip service to SCRUM),
with fewer nasty surprises along the way (such as, the good old &quot;where did that
month go?&quot; experience). In the past, management could give the developers
direction one month to the next, but day to day was a bit of a mystery, and
without SCRUM in place too it was much overhead to cope with. Now, &lt;em&gt;every&lt;&#x2F;em&gt; day
is accounted for. Life is good, the company gets more of what it asks its
developers for.&lt;&#x2F;p&gt;
&lt;p&gt;Every developer I have worked with has wanted to do a good job for the company they are working for. And they have all been generally competent at both coding, and interacting with management in getting the job done. So if they are good people, and we are so much more &quot;productive&quot; now, then why were they &lt;em&gt;wasting&lt;&#x2F;em&gt; all this time before? Well, to an extent you can explain the improvements by the elimination of some of the tail chasing exercises that happen under less disciplined approaches to project management. But that&#x27;s not quite enough. There&#x27;s something else, and &lt;strong&gt;it&#x27;s a question of perceived priorities&lt;&#x2F;strong&gt; and the effect they have on what gets done.&lt;&#x2F;p&gt;
&lt;p&gt;When you have your head under the bonnet, you&#x27;ll notice all the leaks and all the frayed cables. And as anyone who&#x27;s taken their car to a garage will know, the mechanic can always find something to suck their teeth about and charge you an extra £150. But when you are just driving the car it all seems just peachy till service time. But why do you give in and pay up for that thing you&#x27;ve never heard of? Surely if the car was fine when you were driving, then it &lt;em&gt;must&lt;&#x2F;em&gt; be okay? Well, I don&#x27;t know about you, but for me it&#x27;s the fear of ending up as a pile of &lt;span style=&quot;color: rgb(153, 0, 0);&quot;&gt;tomato ketchup&lt;&#x2F;span&gt; on the inside of my windscreen when I finally find out why that thing I can&#x27;t even name was actually important. So how is this a good analogy? No-one ever died from bad software, right? Well the point is, the mechanic is skilled (&lt;em&gt;like the developer&lt;&#x2F;em&gt;), and I am not (&lt;em&gt;like the manager&lt;&#x2F;em&gt;). Like the manager, I have to decide which things to spend my money on and which things to pretend I know about and leave till the MOT fails.&lt;&#x2F;p&gt;
&lt;p&gt;Software developers, being skilled tradespeople, always have an eye on the long
term, and will always be balancing the current panic from the sales department
against what is good for the company in the long run. In the past, when you
used to lose months at a time, it was often partly because the developers were
taking some time to look after the company&#x27;s long term interests. In hindsight
it is easy to justify the long term work that was done with some glib comment,
as it&#x27;s no longer really up for discussion; you can&#x27;t get the time back after
all. But imagine if all these long term things had to be justified &lt;em&gt;before&lt;&#x2F;em&gt;
they were done, even if the manager doesn&#x27;t know what on earth the developers
are talking about. Well you know what, a lot of it wouldn&#x27;t get done, and the
developers who really care about your long term future (i.e. those you haven&#x27;t
ground down yet into despondency yet by ignoring them for years on end), would
get narked. If it&#x27;s hard to &quot;put a business case for&quot; then a lot of good
developers I know will just not bother, after all they don&#x27;t have to save
management from themselves, that wasn&#x27;t in the job specification, and people
don&#x27;t like being saved from themselves anyway. Unfortunately, this is exactly
the change that moving to SCRUM introduces. Developers can no longer &quot;just do&quot;
something that takes more than a day, no matter how much it needs doing in the
long run, as it will be blindingly obvious at the daily stand-ups that they are
not sticking to tasks, and are going to make an iteration miss its target.
After all each iteration is likely already chock full of &quot;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;MoSCoW_Method&quot;&gt;must
haves&lt;&#x2F;a&gt;&quot;, and even if a developer
puts the effort in to get a long term piece of work into an iteration, it will
always end up lower priority than user stories for customer visible deadlines,
and therefore likely still not get done (unless you are getting your velocity
right, which of course you should be).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Interlude.&lt;&#x2F;span&gt; You may now hum to
yourself for a bit before I attempt to tell you how to fix it.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;6495790775&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;7005&#x2F;6495790775_7190968d21.jpg&quot; alt=&quot;Photo of a bench carved from a tree in the woods&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;So what to do? In a way maybe it&#x27;s no different to the car analogy. Make sure
you (management) get enough long term stuff into the iterations, and give them
just as much priority as anything else. Make sure they get &lt;em&gt;done&lt;&#x2F;em&gt;! Just as if
they were a short term deadline. Then in the long run, the wheels won&#x27;t fall
off your software, at least not while you&#x27;re driving. &lt;span style=&quot;color:
rgb(102, 102, 102);font-size:85%;&quot;&gt;(This blog post contains no warranty, road
conditions my vary, any number of factors may cause the wheels to fall off your
software. Especially if driven over rough specifications.)&lt;&#x2F;span&gt; Make sure
your team of developers know that you are committed to this so that they do
actually come forward with the things they &lt;em&gt;know&lt;&#x2F;em&gt; need to be done sooner or
later. (If you don&#x27;t know about it you certainly can&#x27;t get it fixed.) Perhaps
you could create a separate long term plan with the help of the team that
provides for long term needs, giving it real deadlines that are as immovable as
whatever conference you are showing at next. If you have to justify it to
others you can say &quot;because the long term is just as important to our business
as the now&quot;! Have the courage of your convictions. Back the long term as well
as the short term. Always have an eye on the build up of outstanding long term
items (c.f. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Technical_debt&quot;&gt;technical debt&lt;&#x2F;a&gt;). If
the long term plan doesn&#x27;t look like it fits with what you &lt;em&gt;have&lt;&#x2F;em&gt; to deliver
day to day, then maybe you need to step back and look at your software
architecture as a whole, or the resourcing in your team. I would suggest a
practical plan: set a percentage of time that will be spent on the long the
term items, say 10%, which is ring fenced for use by the technical experts (the
developers), for making sure the long term needs of your software are looked
after.&lt;&#x2F;p&gt;
&lt;p&gt;Sooner or later, if things run their new agile course, the chickens will come
home to roost, and you&#x27;ll start to wonder why it&#x27;s taking longer and longer to
get those features out, or more time will be lost to bugs, or things will just
start to outright fail. So I urge you to think about the long term and not
forget that the manager is not the expert in the detail - that&#x27;s what your
developers are there for. So listen to your techies and the advice they have on
the balance of priorities, and take that into account when creating and
prioritising your backlog. You will have a happier team and happier software as
a result.&lt;&#x2F;p&gt;
&lt;p&gt;So in summary:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Moving to agile is excellent, but prevents your technical experts from
quietly fixing things for you to the same extent.&lt;&#x2F;li&gt;
&lt;li&gt;Don&#x27;t forget the long term in the excitement of getting features done,
done, done!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git, Windows and Line endings</title>
        <published>2012-01-11T09:05:00.009+00:00</published>
        <updated>2012-01-11T09:05:00.009+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2012/01/11/git-windows-and-line-endings/"/>
        <id>https://0x5.uk/2012/01/11/git-windows-and-line-endings/</id>
        
        <content type="html" xml:base="https://0x5.uk/2012/01/11/git-windows-and-line-endings/">&lt;p&gt;I have come to the unfortunate conclusion that git is not the perfect tool for
teams developing exclusively on Windows. And by that I mean, I cannot recommend
it unconditionally as I would like to be able to do.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;6375201587&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;6237&#x2F;6375201587_3a4b7d4a19.jpg&quot;
alt=&quot;Slightly amusing photo of for-sale sign in a bin&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The main competition I would be considering is Microsoft&#x27;s TFS.&lt;&#x2F;p&gt;
&lt;p&gt;I have had plenty of experience working with git under windows (as well as on
linux), and what follows are the three reasons I can&#x27;t wholeheartedly recommend
git to a pure windows team. There are of course many reasons to avoid the
alternatives, but that is outside the scope of what I wanted to say here.&lt;&#x2F;p&gt;
&lt;p&gt;Just for the record, in spite of these flaws, I still think git is the best
thing since sliced bread.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;file-renaming&quot;&gt;File renaming&lt;&#x2F;h1&gt;
&lt;p&gt;This is an outright bug that unfortunately the msysgit developers have chosen
not to address (as is their prerogative), and I don&#x27;t have the resources needed
to provide a patch of sufficient quality or run my own variant of msysgit.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-for-windows&#x2F;git&#x2F;wiki&#x2F;File-names,-Branch-names,-Path-quotation,-Executable-bit-and-file-modes,-core.FileMod:&#x2F;&#x2F;github.com&#x2F;git-for-windows&#x2F;git&#x2F;wiki&#x2F;File-names,-Branch-names,-Path-quotation,-Executable-bit-and-file-modes,-core.FileMode&quot;&gt;Git-for-windows page on all the case issues&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The simple test is to change the case of a file&#x27;s name, which fails, however
most obvious workaround (rename to another file name in one commit, and back
again in another) actually makes the problem worse. This is because the bug
also affects checkouts, so when git on another team member&#x27;s machine attempts
to update the working copy directly from its previous state directly to the
requested revision (usually the latest), the &quot;checkout&quot; fails half way through
leaving the team member flummoxed.&lt;&#x2F;p&gt;
&lt;p&gt;This is a particularly insidious bug for a team. You will generally have some
people who are stronger with git (or pick it up quickly), and some who are not
interested or struggle with the new system. Unfortunately if your team trips
over this bug, &lt;em&gt;every&lt;&#x2F;em&gt; team member will have to work out how to get past it,
and it is not immediately obvious from the symptoms what the problem might be
or how to solve it. It also leaves the victim&#x27;s source directory in an
inconsistent state, so if they try to ignore the problem and carry on they will
get into more of a pickle.&lt;&#x2F;p&gt;
&lt;p&gt;Having to notify every member of your team that you have changed the case of a
file and point them to a workaround is hardly going to endear them to their new
fangled source control &quot;git&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;A real world example of why this might happen:&lt;&#x2F;p&gt;
&lt;p&gt;File in your source tree that has been around since before you had any naming
conventions: &quot;&lt;em&gt;VATRate.cs&lt;&#x2F;em&gt;&quot; containing a &lt;em&gt;VATRate&lt;&#x2F;em&gt; class. (Value Added Tax).
You now enforce a naming convention where Acronyms are in Pascal case, i.e.
&lt;em&gt;VatRate&lt;&#x2F;em&gt;. In order to rename the class you must also rename the file,
therefore &lt;em&gt;VATRate.cs&lt;&#x2F;em&gt; is renamed to &lt;em&gt;VatRate.cs&lt;&#x2F;em&gt;, triggering the above bug for
your entire team whenever they happen to fetch (and worse every time they
switch between branches that do &#x2F; don&#x27;t have the patch).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;line-endings&quot;&gt;Line Endings&lt;&#x2F;h1&gt;
&lt;p&gt;As you know from the depths of history, our beloved operating systems have
chosen different line ending systems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Mac: CR&lt;&#x2F;li&gt;
&lt;li&gt;Windows: CRLF&lt;&#x2F;li&gt;
&lt;li&gt;Linux&#x2F;Unix: LF&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Git has an ingenious way of handling this, and gives you three choices for
handling cross platform differences (see &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;linux.die.net&#x2F;man&#x2F;1&#x2F;git-config&quot;&gt;git config &#x2F;
core.autocrlf&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Leave them the hell alone (&lt;em&gt;false&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Store them in git as LF and convert them on checkin&#x2F;checkout (&lt;em&gt;auto&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;convert them when you checkin a file but not on checkout (&lt;em&gt;input&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Which in theory is fine and dandy, and either of the first two should both be
fine for a pure windows team... if it wasn&#x27;t for the patch tools. It would seem
that as soon as you start applying patches and using some of the more advanced
tools that come with git, they introduce inconsistent line endings into checked
in files. You also have an issue with the configuration being client side, so
it is likely one of your team members will get the setting wrong one day and
make a mess.&lt;&#x2F;p&gt;
&lt;p&gt;In my experience, neither of the first two settings are painless under windows,
leaving you with a constant overhead of meaningless &#x2F; noisy diffs, and time
spent troubleshooting, and running tools to tidy up files that have had their
line endings corrupted.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s not a show-stopper, but it does make it harder to recommend that a team
avoid TFS (for example) and use the &quot;better&quot; solution with all its benefits.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;unicode-file-handling&quot;&gt;Unicode file handling&lt;&#x2F;h1&gt;
&lt;p&gt;I may not have my facts completely straight on this one as I&#x27;m no expert in
this area, so please forgive me and provide any corrections &#x2F; references you
can in the comments.&lt;&#x2F;p&gt;
&lt;p&gt;Visual Studio has a tendency to add a byte order marker to source files. Which
as far as I know is fine. Unfortunately git then is inclined to interpret the
file as binary and refuse to show diffs.&lt;&#x2F;p&gt;
&lt;p&gt;(I&#x27;m a little uncertain on this one, but I have seen the symptoms first hand,
and it happens more than is comfortable)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;footnote-speed&quot;&gt;Footnote: Speed&lt;&#x2F;h1&gt;
&lt;p&gt;Git is held up as an example of fast source control, and seems faster than
anything else I&#x27;ve used, however it&#x27;s also worth mentioning that rewriting
commit histories (rebase), refreshing the status and tab-completion are (last
time I checked) all significantly slower on msysgit (windows) than git on
linux.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Multiple working folders for git on Windows XP</title>
        <published>2011-11-16T09:46:00.011+00:00</published>
        <updated>2011-11-16T09:46:00.011+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2011/11/16/multiple-working-folders-for-git-on/"/>
        <id>https://0x5.uk/2011/11/16/multiple-working-folders-for-git-on/</id>
        
        <content type="html" xml:base="https://0x5.uk/2011/11/16/multiple-working-folders-for-git-on/">&lt;p&gt;Multiple working folders for git on Windows XP (lucky me)&lt;&#x2F;p&gt;
&lt;p&gt;It is assumed that you have a git working copy of your project already in place
at &lt;code&gt;C:\code\myproject\&lt;&#x2F;code&gt; and that you want another copy of your project sharing
all history but with a different branch checked out at &lt;code&gt;C:\code\othercopy\&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is useful for:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;rapidly switching between branches where a switch would normally cause a
time consuming recompile &#x2F; rebuild&lt;&#x2F;li&gt;
&lt;li&gt;tracking the branch structure of Visual SourceSafe (which you aren&#x27;t using
in this century are you?) aka VSS aka Visual Source Shredder (or maybe TFS)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This can be achieved by use of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;NTFS_symbolic_link&quot;&gt;NTFS symbolic
links&lt;&#x2F;a&gt; (other related
keywords: junction points, reparse points, hard links). Grab &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;technet.microsoft.com&#x2F;en-us&#x2F;sysinternals&#x2F;bb896768&quot;&gt;Sysinternals&#x27;
Junction&lt;&#x2F;a&gt; to provide
access to NTFS symbolic links. Extract the contents and put &lt;code&gt;junction.exe&lt;&#x2F;code&gt; on
your path.&lt;&#x2F;p&gt;
&lt;p&gt;Word of warning for NTFS symbolic links in Windows XP:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Windows Explorer in XP doesn&#x27;t know about the NTFS symbolic links, and if
you delete the containing folder it will delete the real copy of your
linked folder (facepalm). &lt;strong&gt;Take backups first! You have been warned!&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Open a command prompt and run the following commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd c:\code\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir othercopy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd othercopy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir .git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd .git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;junction hooks C:\code\myproject\.git\hooks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;junction info C:\code\myproject\.git\info&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;junction logs C:\code\myproject\.git\logs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;junction objects C:\code\myproject\.git\objects&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;junction refs C:\code\myproject\.git\refs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C:\code\othercopy\.git&amp;gt;copy C:\code\myproject\.git\* .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you make a mistake, use &lt;code&gt;junction -d&lt;&#x2F;code&gt; to remove the branch point you have
created, &lt;strong&gt;do not use explorer to delete a branch point&lt;&#x2F;strong&gt; as it will delete all
your actual files.&lt;&#x2F;p&gt;
&lt;p&gt;You can now go into C:\code\othercopy\ and switch to a different branch, eg in git-bash:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd c:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd \code\othercopy\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git branch mynewbranch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git checkout -f mynewbranch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point you have two different checkouts sharing the same git data. Yay.&lt;&#x2F;p&gt;
&lt;p&gt;Word of warning for multiple working copies and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;gitextensions&#x2F;&quot;&gt;git-extensions&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Git extensions gets confused if you remove a branch that one of your
working copies is on; and incorrectly shows the folder as uninitialised. To
resolve this use the context menu in explorer or the console to force
checkout a different branch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This howto was written with &quot;&lt;em&gt;git version 1.7.6.msysgit.0&lt;&#x2F;em&gt;&quot; and &lt;em&gt;git-extensions v2.26&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;references-see-also&quot;&gt;References &#x2F; see also&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;finik.net&#x2F;2010&#x2F;10&#x2F;24&#x2F;multiple-working-folders-with-single-git-repository&#x2F;&quot;&gt;http:&#x2F;&#x2F;finik.net&#x2F;2010&#x2F;10&#x2F;24&#x2F;multiple-working-folders-with-single-git-repository&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;NTFS_symbolic_link&quot;&gt;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;NTFS_symbolic_link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;technet.microsoft.com&#x2F;en-us&#x2F;sysinternals&#x2F;bb896768&quot;&gt;http:&#x2F;&#x2F;technet.microsoft.com&#x2F;en-us&#x2F;sysinternals&#x2F;bb896768&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;gitextensions&#x2F;&quot;&gt;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;gitextensions&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;elegantcode.com&#x2F;2011&#x2F;03&#x2F;15&#x2F;git-tfs-where-have-you-been-all-my-life&#x2F;&quot;&gt;http:&#x2F;&#x2F;elegantcode.com&#x2F;2011&#x2F;03&#x2F;15&#x2F;git-tfs-where-have-you-been-all-my-life&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;github.com&#x2F;spraints&#x2F;git-tfs&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;spraints&#x2F;git-tfs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Scripts for creating and unlinking extra working copies:
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;1373136&quot;&gt;https:&#x2F;&#x2F;gist.github.com&#x2F;1373136&lt;&#x2F;a&gt; - create&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;1373142&quot;&gt;https:&#x2F;&#x2F;gist.github.com&#x2F;1373142&lt;&#x2F;a&gt; - remove&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GpsPrune file matching</title>
        <published>2011-11-09T00:08:00.001+00:00</published>
        <updated>2011-11-09T00:08:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2011/11/09/gpsprune-file-matching/"/>
        <id>https://0x5.uk/2011/11/09/gpsprune-file-matching/</id>
        
        <content type="html" xml:base="https://0x5.uk/2011/11/09/gpsprune-file-matching/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;6327537524&quot;&gt;&lt;img src=&quot;http:&#x2F;&#x2F;farm7.static.flickr.com&#x2F;6215&#x2F;6327537524_63e500602c.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to be able to load a whole bunch of gpx traces and see which one was where on the map. I&#x27;ve got a basic version working thought it&#x27;s a bit rough around the edges.&lt;&#x2F;p&gt;
&lt;p&gt;The code is available for you to grab from &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;gpsprune&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;gpsprune&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And above is a pic of it in action, having opened a load of files at once and clicked on one of them in the list&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>LVM + ReiserFS for the win</title>
        <published>2011-10-25T06:17:00.002+00:00</published>
        <updated>2011-10-25T06:17:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2011/10/25/lvm-reiserfs-for-win/"/>
        <id>https://0x5.uk/2011/10/25/lvm-reiserfs-for-win/</id>
        
        <content type="html" xml:base="https://0x5.uk/2011/10/25/lvm-reiserfs-for-win/">&lt;p&gt;LVM + ReiserFS for the win!&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s so easy to add more space&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@atom:~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# lvextend -L +100G &#x2F;dev&#x2F;vg2&#x2F;local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Extending logical volume local to 200.00 GiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Logical volume local successfully resized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@atom:~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# resize_reiserfs &#x2F;dev&#x2F;vg2&#x2F;local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;resize_reiserfs 3.6.21 (2009 www.namesys.com)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;resize_reiserfs: On-line resizing finished successfully.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@atom:~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# df -h &#x2F;dev&#x2F;mapper&#x2F;vg2-local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem            Size  Used Avail Use% Mounted on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;mapper&#x2F;vg2-local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     200G   18G  183G   9% &#x2F;media&#x2F;local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root@atom:~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>share your test data for your project</title>
        <published>2011-10-03T10:39:00.002+00:00</published>
        <updated>2011-10-03T10:39:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2011/10/03/share-your-test-data-for-your-project/"/>
        <id>https://0x5.uk/2011/10/03/share-your-test-data-for-your-project/</id>
        
        <content type="html" xml:base="https://0x5.uk/2011/10/03/share-your-test-data-for-your-project/">&lt;div&gt;Thought for the day:&lt;&#x2F;div&gt;
&lt;p&gt;Completed projects should &lt;strong&gt;always&lt;&#x2F;strong&gt; inlcude SQL scripts for creating working test data (i.e. so you can see the code in action).&lt;&#x2F;p&gt;
&lt;div&gt;I often see difficulties creating usable test data when picking up someone else&#x27;s work.&lt;&#x2F;div&gt;
&lt;div&gt;And I&#x27;d add to that, a readme file with how to use the test data.&lt;&#x2F;div&gt;
&lt;div&gt;(short blog post, but too long for a tweet!)&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Simple water butt level meter</title>
        <published>2011-08-05T21:48:00.007+00:00</published>
        <updated>2011-08-05T21:48:00.007+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2011/08/05/simple-water-butt-level-meter/"/>
        <id>https://0x5.uk/2011/08/05/simple-water-butt-level-meter/</id>
        
        <content type="html" xml:base="https://0x5.uk/2011/08/05/simple-water-butt-level-meter/">&lt;p&gt;Something new for me on this blog, a physical invention.&lt;&#x2F;p&gt;
&lt;p&gt;I made a prototype with an idea of making them and selling them. It&#x27;s designed to satisfy a personal niggle - it annoys me taking the lids off every time I want to see if they are full or empty. I then researched patents etc and decided it was a non-starter so here it is for you to make your own and for the good of the world.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s nothing ground breaking but I&#x27;m quite pleased with it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;6012906502&#x2F;&quot;&gt;&lt;img src=&quot;http:&#x2F;&#x2F;farm7.static.flickr.com&#x2F;6130&#x2F;6012906502_e434750e67.jpg&quot; alt=&quot;a diagram of my invention&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you like here&#x27;s the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;blog&#x2F;water-butt-meter.svg&quot;&gt;original svg of the diagram&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Please contact me if you like this &#x2F; use this, just so I know it was worth the evening I spent drawing it :-)&lt;&#x2F;p&gt;
&lt;p&gt;Contact me if you want me to make you one, I could sell them through ebay if there&#x27;s a demand.&lt;&#x2F;p&gt;
&lt;p&gt;To make it pretty I was thinking of putting a little fisherman on top with his rod holding the string for the level meter... (this would have the practical advantage of keeping the string straighter thus avoiding some of the error introduced by the bend in the simplest version).&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Alternatives:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.maplin.co.uk&#x2F;water-level-meter-module-265562&quot;&gt;http:&#x2F;&#x2F;www.maplin.co.uk&#x2F;water-level-meter-module-265562&lt;&#x2F;a&gt; - electronic remote meter, £30&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.irrigationwarehouse.com.au&#x2F;category264_1.htm&quot;&gt;http:&#x2F;&#x2F;www.irrigationwarehouse.com.au&#x2F;category264_1.htm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Auto-expanding django formset with jQuery</title>
        <published>2011-07-07T23:02:00.009+00:00</published>
        <updated>2011-07-07T23:02:00.009+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2011/07/07/auto-expanding-django-formset-with/"/>
        <id>https://0x5.uk/2011/07/07/auto-expanding-django-formset-with/</id>
        
        <content type="html" xml:base="https://0x5.uk/2011/07/07/auto-expanding-django-formset-with/">&lt;p&gt;As it took me quite a while to get it how I like it, here&#x27;s the relevant bits for making a django formset (custom markup in a table), that automatically adds rows (formset forms) client-side &#x2F; in the browser keeping up as you fill in the form.&lt;&#x2F;p&gt;
&lt;p&gt;Do with the code as you wish, no licence needed.&lt;&#x2F;p&gt;
&lt;p&gt;In the view (.html file server side) I have:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@login_required&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def invoiceEdit(request, invoice_id):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    InlineInvoiceItemsFormSet = inlineformset_factory(Invoice, InvoiceItem, form=DeleteIfEmptyModelForm, formset=DeleteIfEmptyInlineFormSet, can_delete=True, extra=10)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    itemFormSet = InlineInvoiceItemsFormSet()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return render_to_response(&amp;#39;foo&#x2F;edit.html&amp;#39;, {&amp;#39;invoiceForm&amp;#39;: invoiceForm, &amp;#39;itemFormSet&amp;#39;: itemFormSet, &amp;#39;invoice&amp;#39;: invoice}, context_instance=RequestContext(request))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the template I have:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;script type=&amp;quot;text&#x2F;javascript&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; $(function() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  setupInvoiceFormset();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; var initialRows;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; function setupInvoiceFormset() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  initialRows = parseInt($(&amp;#39;#id_invoiceitem_set-INITIAL_FORMS&amp;#39;).val());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;&#x2F; remove all but last two empty rows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  resizeInvoiceFormset();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;&#x2F; add handlers to all inputs to automate row adding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  $(&amp;#39;.invoiceItemRow :input&amp;#39;).blur(resizeInvoiceFormset);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; const targetExtra = 2; &#x2F;&#x2F; number of extra rows desired&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; function resizeInvoiceFormset() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;&#x2F; count the blank rows at the end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  var rows = $(&amp;#39;.invoiceItemRow&amp;#39;).filter(&amp;#39;:not(#templateItemRow)&amp;#39;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  var totalRows = rows.length&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  var blankRows = countBlankRows(rows);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  var targetRowCount = totalRows - blankRows + targetExtra;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  targetRowCount = Math.max(targetRowCount,initialRows); &#x2F;&#x2F; don&amp;#39;t trim off real rows otherwise delete breaks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  if (totalRows &amp;gt; targetRowCount) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &#x2F;&#x2F; if there too many blank rows remove the extra rows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   rows.slice(targetRowCount).remove(); &#x2F;&#x2F; negative to strip from ends&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  } else if (totalRows &amp;lt; targetRowCount) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &#x2F;&#x2F; add new blank rows to bring the total up to the desired number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   for (var newRowIndex = totalRows; newRowIndex &amp;lt; targetRowCount; newRowIndex++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    addRow(newRowIndex);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  } else {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   return;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;&#x2F; update the hidden form with the new form count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  $(&amp;#39;#id_invoiceitem_set-TOTAL_FORMS&amp;#39;).val(targetRowCount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; function countBlankRows(rows) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;&#x2F; count the empty rows from the bottom up, stopping at the first non-blank row&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  var blankRows = 0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  for (var i = rows.length -1; i&amp;gt;=0; i--) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   if (isEmptyRow(rows[i])) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blankRows++;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   } else {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    break;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  return blankRows;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; function isEmptyRow(row) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;&#x2F; loop through all the inputs in the row, return true if they are all blank&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;&#x2F; whitespace is ignored&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  var inputs = $(row).find(&amp;#39;:input&amp;#39;).filter(&amp;#39;:not(:hidden)&amp;#39;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  for (var j = 0; j &amp;lt; inputs.length; j++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   if ($.trim(inputs[j].value).length) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return false;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  return true;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; function addRow(newRowIndex) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  var newRow = $(&amp;#39;#templateItemRow&amp;#39;).clone(true);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  newRow.addClass(&amp;#39;invoiceItemRow&amp;#39;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  newRow.removeAttr(&amp;#39;id&amp;#39;); &#x2F;&#x2F;prevent duplicated template row id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  newRow.show();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;&#x2F; replace placeholder with row index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  newRow.find(&amp;#39;:input&amp;#39;).each(function() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   $(this).attr(&amp;quot;name&amp;quot;, $(this).attr(&amp;quot;name&amp;quot;).replace(&amp;#39;__prefix__&amp;#39;, newRowIndex));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   $(this).attr(&amp;quot;id&amp;quot;, $(this).attr(&amp;quot;id&amp;quot;).replace(&amp;#39;__prefix__&amp;#39;, newRowIndex));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  $(&amp;#39;.invoiceItemRow:last&amp;#39;).after(newRow);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;script&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{{ itemFormSet.management_form }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;tr id=&amp;quot;templateItemRow&amp;quot; class=&amp;quot;invoiceItemRow&amp;quot; style=&amp;quot;display: none;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;Item:&amp;lt;&#x2F;strong&amp;gt;&amp;lt;&#x2F;td&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;td&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {{ itemFormSet.empty_form.id }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {{ itemFormSet.empty_form.description }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {{ itemFormSet.empty_form.description.errors }}&amp;lt;&#x2F;td&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;td class=&amp;quot;price&amp;quot;&amp;gt;£{{ itemFormSet.empty_form.price }} {{ itemFormSet.empty_form.price.errors }}&amp;lt;&#x2F;td&amp;gt;&amp;lt;&#x2F;tr&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{% for item in itemFormSet.forms %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;tr class=&amp;quot;invoiceItemRow&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;Item:&amp;lt;&#x2F;strong&amp;gt;&amp;lt;&#x2F;td&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;td&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {{ item.id }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {{ item.description }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {{ item.description.errors }}&amp;lt;&#x2F;td&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;td class=&amp;quot;price&amp;quot;&amp;gt;£{{ item.price }} {{ item.price.errors }}&amp;lt;&#x2F;td&amp;gt;&amp;lt;&#x2F;tr&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{% endfor %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The result is a form that intuitively shrinks&#x2F;grows as the content is added&#x2F;removed.&lt;&#x2F;p&gt;
&lt;p&gt;The javascript is of course actually in a separate .js file.&lt;&#x2F;p&gt;
&lt;p&gt;References:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.djangoproject.com&#x2F;en&#x2F;dev&#x2F;topics&#x2F;forms&#x2F;formsets&#x2F;&quot;&gt;https:&#x2F;&#x2F;docs.djangoproject.com&#x2F;en&#x2F;dev&#x2F;topics&#x2F;forms&#x2F;formsets&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;api.jquery.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;api.jquery.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Footnote. You may have noticed the delete-if-empty customisation which I like for usability. References for this at&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pastebin.com&#x2F;f40a3bde9&quot;&gt;http:&#x2F;&#x2F;pastebin.com&#x2F;f40a3bde9&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;django-users&#x2F;browse_thread&#x2F;thread&#x2F;9e26cf3ab1d1fcb1?tvc=2&quot;&gt;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;django-users&#x2F;browse_thread&#x2F;thread&#x2F;9e26cf3ab1d1fcb1?tvc=2&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;django-users&#x2F;browse_thread&#x2F;thread&#x2F;23539f5e085e62b0&quot;&gt;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;django-users&#x2F;browse_thread&#x2F;thread&#x2F;23539f5e085e62b0&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Data driven test in NUnit with csv source data</title>
        <published>2011-05-23T09:38:00.004+00:00</published>
        <updated>2011-05-23T09:38:00.004+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2011/05/23/data-driven-test-in-nunit-with-csv/"/>
        <id>https://0x5.uk/2011/05/23/data-driven-test-in-nunit-with-csv/</id>
        
        <content type="html" xml:base="https://0x5.uk/2011/05/23/data-driven-test-in-nunit-with-csv/">&lt;p&gt;I wanted to test a date parser across a large range of values so wanted a simple test harness to test all the values.&lt;&#x2F;p&gt;
&lt;p&gt;The test framework options around c# &#x2F; .net seem to be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MSTest - can do csv via jet, but can&#x27;t do inline test data which is something I also want.&lt;&#x2F;li&gt;
&lt;li&gt;NUnit - can do inline data driven test data (with the TestCase(data...) attribute), and has support for extending this via the TestCaseSource attribute.&lt;&#x2F;li&gt;
&lt;li&gt;xUnit - confusing (aka flexible), doesn&#x27;t seem to get me to my end result any faster after a bit of searching around.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I&#x27;ve used NUnit and combined TestCaseSource with a simple wrapper class around the csv parsing library&lt;&#x2F;p&gt;
&lt;p&gt;To get this to work:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Save your csv file in your test project&lt;&#x2F;li&gt;
&lt;li&gt;add the file to your project (in visual studio 2008 in this case)&lt;&#x2F;li&gt;
&lt;li&gt;right-click on the csv file in solution explorer, click properties, change &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;Copy to Output Directory&lt;&#x2F;span&gt;&quot; to &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;Copy Always&lt;&#x2F;span&gt;&quot;&lt;&#x2F;li&gt;
&lt;li&gt;download the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.codeproject.com&#x2F;KB&#x2F;database&#x2F;CsvReader&#x2F;CsvReader_bin.zip&quot;&gt;binaries (dlls) for csv reader&lt;&#x2F;a&gt; from code project, add a reference to this in your test project&lt;&#x2F;li&gt;
&lt;li&gt;add a private method to your test class for reading the csv file and returning an enumarable (see code below)&lt;&#x2F;li&gt;
&lt;li&gt;add the TestCaseSource attribute to your test method(s) that you want to use the csv data, referencing your new IEnumerable method (see code below)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using System.Collections.Generic;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using System.IO;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using LumenWorks.Framework.IO.Csv;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using NUnit.Framework;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;namespace mytests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    class MegaTests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        [Test, TestCaseSource(&amp;quot;GetTestData&amp;quot;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        public void MyExample_Test(int data1, int data2, int expectedOutput)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            var methodOutput = MethodUnderTest(data2, data1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            Assert.AreEqual(expectedOutput, methodOutput, string.Format(&amp;quot;Method failed for data1: {0}, data2: {1}&amp;quot;, data1, data2));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        private int MethodUnderTest(int data2, int data1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            return 42; &#x2F;&#x2F;todo: real implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        private IEnumerable&amp;lt;int[]&amp;gt; GetTestData()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            using (var csv = new CsvReader(new StreamReader(&amp;quot;test-data.csv&amp;quot;), true))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                while (csv.ReadNextRecord())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    int data1 = int.Parse(csv[0]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    int data2 = int.Parse(csv[1]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    int expectedOutput = int.Parse(csv[2]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    yield return new[] { data1, data2, expectedOutput };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;references:&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.codeproject.com&#x2F;KB&#x2F;database&#x2F;CsvReader.aspx&quot;&gt;CodeProject.com - CsvReader&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;4036840&#x2F;data-driven-testing-in-nunit&quot;&gt;StackOverflow.com - Data-driven testing in NUnit&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;nunit.com&#x2F;index.php?p=testCaseSource&amp;amp;r=2.5.8&quot;&gt;NUnit TestCaseSource&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;9k7k7cf0%28v=vs.80%29.aspx&quot;&gt;msdn ref, c# yield&lt;&#x2F;a&gt; - for generating an IEnumerable.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Reliable javascript checkbox events</title>
        <published>2011-05-18T22:30:00.004+00:00</published>
        <updated>2011-05-18T22:30:00.004+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2011/05/18/reliable-javascript-checkbox-events/"/>
        <id>https://0x5.uk/2011/05/18/reliable-javascript-checkbox-events/</id>
        
        <content type="html" xml:base="https://0x5.uk/2011/05/18/reliable-javascript-checkbox-events/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;5734606641&#x2F;&quot;&gt;&lt;img src=&quot;http:&#x2F;&#x2F;farm4.static.flickr.com&#x2F;3652&#x2F;5734606641_c61a818d47_m.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Some sites have checkboxes which show&#x2F;hide another element when you click them. This a handy feature, but not all sites take into account the fact that firefox remembers the contents of a form when you reload the page (this is a good thing).&lt;&#x2F;p&gt;
&lt;p&gt;So here&#x27;s how you avoid that with jQuery:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;script type=&amp;quot;text&#x2F;javascript&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $(function() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; initialise show&#x2F;hide to match the checkbox value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        $(&amp;#39;.targetelements&amp;#39;).toggle($(&amp;#39;#mycheckbox&amp;#39;).attr(&amp;#39;checked&amp;#39;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; attach click handler for show&#x2F;hide to checkbox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        $(&amp;#39;#mycheckbox&amp;#39;).click(function(){ $(&amp;#39;.targetelements&amp;#39;).toggle(this.checked);})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;script&amp;gt;   &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Simples!&lt;&#x2F;p&gt;
&lt;p&gt;You could use the same principle without jQuery if you need to. Simply read the value of the checkbox with javascript the old fashioned way before deciding whether to hide when you initialise you page.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Pidgin for IRC</title>
        <published>2010-12-15T10:35:00.003+00:00</published>
        <updated>2010-12-15T10:35:00.003+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2010/12/15/using-pidgin-for-irc/"/>
        <id>https://0x5.uk/2010/12/15/using-pidgin-for-irc/</id>
        
        <content type="html" xml:base="https://0x5.uk/2010/12/15/using-pidgin-for-irc/">&lt;p&gt;&lt;a rel=&quot;external&quot; title=&quot;http:&#x2F;&#x2F;pidgin.im&#x2F;&quot; href=&quot;http:&#x2F;&#x2F;pidgin.im&#x2F;&quot;&gt;pidgin&lt;&#x2F;a&gt; is quite a good irc client.&lt;&#x2F;p&gt;
&lt;p&gt;Once you have downloaded and installed pidgin:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Accounts &amp;gt; Manage Accounts&lt;&#x2F;li&gt;
&lt;li&gt;Add...&lt;&#x2F;li&gt;
&lt;li&gt;Protocol: IRC&lt;&#x2F;li&gt;
&lt;li&gt;Username: your preferred nickname (please use your real name)&lt;&#x2F;li&gt;
&lt;li&gt;Server: your irc server, eg irc.freenode.org&lt;&#x2F;li&gt;
&lt;li&gt;Password - leave blank&lt;&#x2F;li&gt;
&lt;li&gt;Add&lt;&#x2F;li&gt;
&lt;li&gt;Close (the &quot;Accounts&quot; window)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Back in the main pidgin window:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Buddies &amp;gt; Join A Chat...&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Account: the one you just created&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Channel: #favouriteroom, eg #pidgin&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Password - leave blank&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Join&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the new chat window for the chatroom:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Conversation &amp;gt; Add...&lt;&#x2F;li&gt;
&lt;li&gt;Tick &quot;Autojoin when account connects.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Tick &quot;Remain in chat after window is closed.&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Leave everything else as defaults&lt;&#x2F;li&gt;
&lt;li&gt;Add&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now when pidgin launches you will have &quot;#favouriteroom&quot; in your buddy list, and you can double click to open the chatroom.&lt;&#x2F;p&gt;
&lt;p&gt;You may also want to make pidgin start when windows starts;&lt;&#x2F;p&gt;
&lt;p&gt;From the main window:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Tools &amp;gt; Plugins&lt;&#x2F;li&gt;
&lt;li&gt;Tick &quot;Windows Pidgin Options&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Configure Plugin&lt;&#x2F;li&gt;
&lt;li&gt;Tick &quot;Start Pidgin on Windows startup&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Close&lt;&#x2F;li&gt;
&lt;li&gt;Close (plugin window)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I also recommend enabling the Markerline plugin to help see what is new in the channel.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>configuring kdiff3 as a mergetool in msysgit</title>
        <published>2010-09-03T08:31:00.004+00:00</published>
        <updated>2010-09-03T08:31:00.004+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2010/09/03/configuring-kdiff3-as-mergetool-in/"/>
        <id>https://0x5.uk/2010/09/03/configuring-kdiff3-as-mergetool-in/</id>
        
        <content type="html" xml:base="https://0x5.uk/2010/09/03/configuring-kdiff3-as-mergetool-in/">&lt;p&gt;How to configure kdiff3 as a mergetool in msysgit. (I think if you install kdiff3 &lt;em&gt;before&lt;&#x2F;em&gt; msysgit it is picked up automatically, if not, do the following after installing both).&lt;&#x2F;p&gt;
&lt;p&gt;In git bash:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git config --global merge.tool kdiff3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git config --global mergetool.kdiff3.path &amp;quot;c:\Program Files\KDiff3\kdiff3.exe&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;double check:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cat ~&#x2F;.gitconfig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[merge]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	tool = kdiff3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[mergetool &amp;quot;kdiff3&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	path = c:\\Program Files\\KDiff3\\kdiff3.exe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;refs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;markmail.org&#x2F;message&#x2F;dvrnn7ilprvinrfp#query:msysgit%20kdiff3%20.gitconfig+page:1+mid:dvrnn7ilprvinrfp+state:results&quot;&gt;http:&#x2F;&#x2F;markmail.org&#x2F;message&#x2F;dvrnn7ilprvinrfp#query:msysgit%20kdiff3%20.gitconfig+page:1+mid:dvrnn7ilprvinrfp+state:results&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.kernel.org&#x2F;pub&#x2F;software&#x2F;scm&#x2F;git&#x2F;docs&#x2F;git-config.html&quot;&gt;http:&#x2F;&#x2F;www.kernel.org&#x2F;pub&#x2F;software&#x2F;scm&#x2F;git&#x2F;docs&#x2F;git-config.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Under cygwin, the setup would be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git config --global merge.tool kdiff3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git config --global mergetool.kdiff3.path &#x2F;cygdrive&#x2F;c&#x2F;Program\ Files\ \(x86\)&#x2F;KDiff3&#x2F;kdiff3.exe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Giving the config file contents:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[merge]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	tool = kdiff3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[mergetool &amp;quot;kdiff3&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	path = &#x2F;cygdrive&#x2F;c&#x2F;Program Files (x86)&#x2F;KDiff3&#x2F;kdiff3.exe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which by the way you can view with&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git config -e --global&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>openlayers svn into git</title>
        <published>2010-02-04T14:01:00.014+00:00</published>
        <updated>2010-02-04T14:01:00.014+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2010/02/04/openlayers-svn-into-git/"/>
        <id>https://0x5.uk/2010/02/04/openlayers-svn-into-git/</id>
        
        <content type="html" xml:base="https://0x5.uk/2010/02/04/openlayers-svn-into-git/">&lt;p&gt;Initial clone:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git svn clone -T trunk&#x2F;openlayers&#x2F; -t tags&#x2F;openlayers&#x2F; -b branches&#x2F;openlayers&#x2F; http:&#x2F;&#x2F;svn.openlayers.org&#x2F; openlayers.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&quot;http:&#x2F;&#x2F;svn.openlayers.org&#x2F;tags&#x2F;openlayers&#x2F;docs-2.8&#x2F;&quot; is in the wrong place and gets pulled in by the git clone.&lt;&#x2F;p&gt;
&lt;p&gt;I should have used &lt;code&gt;--no-follow-parent&lt;&#x2F;code&gt; to avoid the &lt;em&gt;docs-2.8&lt;&#x2F;em&gt; tag pulling in docs history but not going to re-clone now. If you are repeating this, try this instead:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git svn clone --no-follow-parent -T trunk&#x2F;openlayers&#x2F; -t tags&#x2F;openlayers&#x2F; -b branches&#x2F;openlayers&#x2F; http:&#x2F;&#x2F;svn.openlayers.org&#x2F; openlayers.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Find the errant docs branches &amp;amp; eliminate:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd openlayers.gitfor x in `git for-each-ref --format=&amp;quot;%(refname)&amp;quot; &amp;#39;refs&#x2F;remotes&#x2F;tags&#x2F;docs*&amp;#39;`; do git update-ref -d $x; done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;dound.com&#x2F;2009&#x2F;04&#x2F;git-forever-remove-files-or-folders-from-history&#x2F;&quot;&gt;http:&#x2F;&#x2F;dound.com&#x2F;2009&#x2F;04&#x2F;git-forever-remove-files-or-folders-from-history&#x2F;&lt;&#x2F;a&gt;
expunge old objects (I think this works)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git reflog expire --allgit gc --aggressive --prune&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then run: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.shatow.net&#x2F;fix-svn-refs.sh&quot;&gt;http:&#x2F;&#x2F;www.shatow.net&#x2F;fix-svn-refs.sh&lt;&#x2F;a&gt; to create real git tags.&lt;&#x2F;p&gt;
&lt;p&gt;If you just want the result you can download a copy complete with svn metadata from &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;openlayers-dev&#x2F;openlayers.git.tgz&quot;&gt;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;openlayers-dev&#x2F;openlayers.git.tgz&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You will then be able to run&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git svn fetch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to get updates from the openlayers svn server.&lt;&#x2F;p&gt;
&lt;p&gt;There is a published copy at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;openlayers&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;openlayers&lt;&#x2F;a&gt;, though it doesn&#x27;t have the svn metadata.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I also tackled the docs folder:&lt;&#x2F;p&gt;
&lt;p&gt;The docs directory has no matching branch or tag directories, so the following is sufficient:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git svn clone -T trunk&#x2F;doc http:&#x2F;&#x2F;svn.openlayers.org&#x2F; openlayers-doc.gitgit gc --aggressive --prune&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can download this from &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;openlayers-dev&#x2F;openlayers-doc.git.tgz&quot;&gt;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;openlayers-dev&#x2F;openlayers-doc.git.tgz&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Anything else I come up with will end up at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;openlayers-dev&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;openlayers-dev&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>backing up Vista</title>
        <published>2009-12-18T10:08:00.002+00:00</published>
        <updated>2009-12-18T10:08:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/12/18/backing-up-vista/"/>
        <id>https://0x5.uk/2009/12/18/backing-up-vista/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/12/18/backing-up-vista/">&lt;p&gt;So here&#x27;s a tale of annoying things.&lt;&#x2F;p&gt;
&lt;p&gt;I generally try and avoid running anything proprietary at home, and especially anything from Microsoft. But for reasons beyond my control a copy of Vista has embedded itself in our household.&lt;&#x2F;p&gt;
&lt;p&gt;For my linux backups I&#x27;ve settled on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;dar.linux.free.fr&#x2F;&quot;&gt;dar&lt;&#x2F;a&gt; (Disk ARchiver) + &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;dargui.sourceforge.net&#x2F;&quot;&gt;dargui&lt;&#x2F;a&gt; as it applies the keep it simple rule (certainly in comparison with a lot of other tools I tried, such as the ubuntu default &quot;home user backup&quot; tool, which has a simple ui but offers limited control and I&#x27;m not sure how easily I could recover files from it in a disaster). Dar is like tar (Tape ARchiver) but more designed with backup to disk in mind, which is what I was after in order to backup to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ebuyer.com&#x2F;product&#x2F;178934&quot;&gt;usb hdd&lt;&#x2F;a&gt;, and most importantly does incremental&#x2F;differential backups the way I want.&lt;&#x2F;p&gt;
&lt;p&gt;So then I came to back up this Vista home directory (sorry, Users directory &#x2F; profiles). I have disliked the old fashioned microsoft backup files (.bkf) from Windows XP and before ever since I tried to get files out of one from a Linux box. Turns out it&#x27;s not exactly the best supported format. I didn&#x27;t have much luck with &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;freshmeat.net&#x2F;projects&#x2F;mtftar&#x2F;&quot;&gt;mtftar&lt;&#x2F;a&gt;. It seems Microsoft have produced a replacement (&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wiktionary.org&#x2F;wiki&#x2F;plus_%C3%A7a_change,_plus_c%27est_la_m%C3%AAme_chose&quot;&gt;plus ça change&lt;&#x2F;a&gt;) to the old windows backup that is evidently designed to be &lt;a rel=&quot;external&quot; title=&quot;lacking mental acuteness or sense&quot; href=&quot;http:&#x2F;&#x2F;dictionary.reference.com&#x2F;browse&#x2F;simple&quot;&gt;simple&lt;&#x2F;a&gt;, which has very strange ideas about how you might want to back up your pc. It seems keener to back up the sample image files from the office install than than the user&#x27;s photos. I very quickly fell out with this tool and moved on.&lt;&#x2F;p&gt;
&lt;p&gt;Some people might recommend windows home server, but I am not about to &lt;em&gt;pay&lt;&#x2F;em&gt; for more shoddy Microsoft software in order to solve problems created by other shoddy Microsoft software. Vote with your wallet, as they say.&lt;&#x2F;p&gt;
&lt;p&gt;So next on the list, remote backup from a linux box. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;backuppc.sourceforge.net&#x2F;&quot;&gt;backup pc&lt;&#x2F;a&gt; looked great, and has many nifty features, however having got it all set up I got permissions errors in the My Documents etc folders, which are the important ones. I tried different user permissions for the backup user, and different group memberships, though stopped short of resetting all user directory permissions so as to not break anything but couldn&#x27;t get past these errors. More details on that attempt in my &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;timwise.blogspot.com&#x2F;2009&#x2F;10&#x2F;backuppc-and-windows-vista.html&quot;&gt;backuppc and windows vista&lt;&#x2F;a&gt; blog entry. There is a hint in the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Robocopy&quot;&gt;Robocopy wikipedia&lt;&#x2F;a&gt; that there is some special mode needed to be able to get past these permissions issues.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The so-called Backup mode is an administrative privilege that allows Robocopy to override permissions settings (specifically, NTFS ACLs) for the purpose of making backups.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;But I didn&#x27;t get any further than that.&lt;&#x2F;p&gt;
&lt;p&gt;So finally I come to the conclusion that Vista just doesn&#x27;t want you to do backups without paying microsoft more money, and that they have forgotten or never knew the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;KISS_principle&quot;&gt;KISS&lt;&#x2F;a&gt; mantra that makes *nix such a pleasure to work with. (Rather opting for their usual &quot;making simple things easy and difficult things impossible&quot;.)&lt;&#x2F;p&gt;
&lt;p&gt;It was &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.linuxformat.co.uk&#x2F;archives?issue=127&quot;&gt;Linux Format 127 Ubuntu 9.10 Cover Disc&lt;&#x2F;a&gt; that came to the rescue. Popped the disc in,rebooted, connected my usb hdd (formatted with ext3 of course), ran &lt;code&gt;apt-get install dar&lt;&#x2F;code&gt;, opened the disk icon on the desktop representing the evil vista installation partition on the local disk (to get it mounted), opened the usb hdd disk icon (also to get it mounted), then ran &lt;code&gt;dar -c &#x2F;media&#x2F;usbhdd&#x2F;backups&#x2F;vistargh -z&lt;&#x2F;code&gt; from the directory &#x2F;media&#x2F;vista&#x2F;Users&#x2F;. This ran fine and I was able to read the file from a better operating system with no issues.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>MCTS in ASP.NET 3.5 - Mission accomplished.</title>
        <published>2009-12-18T09:59:00.005+00:00</published>
        <updated>2009-12-18T09:59:00.005+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/12/18/mcts-in-aspnet-35-mission-accomplished/"/>
        <id>https://0x5.uk/2009/12/18/mcts-in-aspnet-35-mission-accomplished/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/12/18/mcts-in-aspnet-35-mission-accomplished/">&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;MCTS-ASP.NET-3.5.png&quot; alt=&quot;Microsoft Certified Technology Specialist&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I am now a &lt;em&gt;Microsoft Certified Technology Specialist in .NET Framework 3.5, ASP.NET Applications&lt;&#x2F;em&gt;, which is nice.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>getting supybot to announce new bugzilla bugs</title>
        <published>2009-11-16T17:22:00.005+00:00</published>
        <updated>2009-11-16T17:22:00.005+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/11/16/getting-supybot-to-announce-new/"/>
        <id>https://0x5.uk/2009/11/16/getting-supybot-to-announce-new/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/11/16/getting-supybot-to-announce-new/">&lt;p&gt;getting supybot to announce new bugzilla bugs - I&#x27;ve just put here the key non-obvious things that tripped me up when trying to set this up.&lt;&#x2F;p&gt;
&lt;p&gt;All done on Ubuntu 8.04.3 LTS&lt;&#x2F;p&gt;
&lt;p&gt;Install &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;supybot&#x2F;&quot;&gt;supybot&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;supybot-bugzilla&#x2F;&quot;&gt;supybot bugzilla plugin&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Create a system group (supybot) and user (bugbot) to run supybot as.&lt;&#x2F;p&gt;
&lt;p&gt;Set up your supybot configuration file as desired.&lt;&#x2F;p&gt;
&lt;p&gt;Getting supybot to start at startup:
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.schwer.us&#x2F;journal&#x2F;2005&#x2F;04&#x2F;17&#x2F;supybot-init-script-for-debian&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.schwer.us&#x2F;journal&#x2F;2005&#x2F;04&#x2F;17&#x2F;supybot-init-script-for-debian&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s my modified init script&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cat &#x2F;etc&#x2F;init.d&#x2F;bugbot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#! &#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# supybot init script&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# http:&#x2F;&#x2F;www.schwer.us&#x2F;journal&#x2F;2005&#x2F;04&#x2F;17&#x2F;supybot-init-script-for-debian&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PATH=&#x2F;sbin:&#x2F;bin:&#x2F;usr&#x2F;sbin:&#x2F;usr&#x2F;bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DAEMON=&#x2F;usr&#x2F;bin&#x2F;supybot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NAME=supybot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DESC=supybot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;test -f $DAEMON || exit 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;set -e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;case &amp;quot;$1&amp;quot; in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;start)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo -n &amp;quot;Starting $DESC: &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;start-stop-daemon --start --quiet \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--chuid bugbot --exec $DAEMON -- --daemon &#x2F;etc&#x2F;supybot&#x2F;bugbot.conf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;$NAME.&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stop)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo -n &amp;quot;Stopping $DESC: &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;start-stop-daemon --stop --quiet \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--oknodo --exec &#x2F;usr&#x2F;bin&#x2F;python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;$NAME.&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;restart)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$0 stop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$0 start&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;*)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;Usage: $0 {start|stop|restart}&amp;quot; &amp;gt;&amp;amp;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;exit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;esac&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;exit 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Set up bugzilla to send a copy of all bugmail to a local address (eg bugbot@localhost), and configure exim4 to accept local mail (as well as smart host delivery), using the mbox format.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo dpkg-reconfigure exim4-config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Start a conversation with bugbot, get it to identify you, then set the required configuration by sending it messages (you can also set these in the supybot .conf file for your bot):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;config plugins.Bugzilla.mbox &#x2F;var&#x2F;mail&#x2F;bugbot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;config plugins.Bugzilla.bugzillas.your-bugzilla-name.watchedItems.all True&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which will turn on the announcements (i had to read the code to find that one!)&lt;&#x2F;p&gt;
&lt;p&gt;Note that supybot doesn&#x27;t immediately write config changes to disc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>bugzilla upgrades and user tokens</title>
        <published>2009-11-08T18:12:00.006+00:00</published>
        <updated>2009-11-08T18:12:00.006+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/11/08/bugzilla-upgrades-and-user-tokens/"/>
        <id>https://0x5.uk/2009/11/08/bugzilla-upgrades-and-user-tokens/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/11/08/bugzilla-upgrades-and-user-tokens/">&lt;p&gt;It&#x27;s bugzilla upgrade time for my private install, and I have for the second time run into a strange issue with the tokens system. Since this is the second time and I know how to fix it, here it is for the record.&lt;&#x2F;p&gt;
&lt;p&gt;I have upgrade from v3.0.4 to 3.4.3.&lt;&#x2F;p&gt;
&lt;p&gt;Once the site was up again, saving the site parameters (&lt;code&gt;editparams.cgi&lt;&#x2F;code&gt;) showed a big red warning:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;It looks like you didn&#x27;t come from the right page (you have no valid token
for the &lt;em&gt;edit_parameters&lt;&#x2F;em&gt; action while processing the &#x27;editparams.cgi&#x27;
script). The reason could be one of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You clicked the &quot;Back&quot; button of your web browser after having
successfully submitted changes, which is generally not a good idea (but
harmless).&lt;&#x2F;li&gt;
&lt;li&gt;You entered the URL in the address bar of your web browser directly,
which should be safe.&lt;&#x2F;li&gt;
&lt;li&gt;You clicked on a URL which redirected you here &lt;strong&gt;without your consent&lt;&#x2F;strong&gt;,
in which case this action is much more critical.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Are you sure you want to commit these changes anyway? This may result in
unexpected and undesired results.&lt;&#x2F;p&gt;
&lt;p&gt;[Confirm Changes]&lt;&#x2F;p&gt;
&lt;p&gt;Or throw away these changes and go back to editparams.cgi.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Pushing the button doesn&#x27;t work (same page shows again).&lt;&#x2F;p&gt;
&lt;p&gt;After much digging last time I discovered that the tokens it refers to are stored in table bugs.tokens, and that the size of the field is wrong in my installation after the upgrade (again).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mysql&amp;gt; use bugs;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mysql&amp;gt; describe tokens;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-----------+--------------+------+-----+---------+-------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Field | Type | Null | Key | Default | Extra |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-----------+--------------+------+-----+---------+-------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| userid | mediumint(9) | YES | MUL | NULL | |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| issuedate | datetime | NO | | NULL | |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| &amp;lt;span style=&amp;quot;font-weight: bold;&amp;quot;&amp;gt;token | varchar(5)&amp;lt;&#x2F;span&amp;gt; | NO | PRI | NULL | |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| tokentype | varchar(8) | YES | | NULL | |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| eventdata | tinytext | YES | | NULL | |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+-----------+--------------+------+-----+---------+-------+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 rows in set (0.02 sec)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;According to the published schema, token should be &lt;code&gt;varchar(16)&lt;&#x2F;code&gt;. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ravenbrook.com&#x2F;project&#x2F;p4dti&#x2F;tool&#x2F;cgi&#x2F;bugzilla-schema&#x2F;index.cgi?action=single&amp;amp;version=3.4.2&amp;amp;view=View+schema#table-tokens&quot;&gt;http:&#x2F;&#x2F;www.ravenbrook.com&#x2F;project&#x2F;p4dti&#x2F;tool&#x2F;cgi&#x2F;bugzilla-schema&#x2F;index.cgi?action=single&amp;amp;version=3.4.2&amp;amp;view=View+schema#table-tokens&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To fix the problem I modified the data type as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mysql&amp;gt; alter table tokens modify column token varchar(16) not null;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Query OK, 20 rows affected (0.32 sec)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Records: 20 Duplicates: 0 Warnings: 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then I was able to change my parameters.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bugzilla.mozilla.org&#x2F;show_bug.cgi?id=527780&quot;&gt;https:&#x2F;&#x2F;bugzilla.mozilla.org&#x2F;show_bug.cgi?id=527780&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>life update - software learning</title>
        <published>2009-10-24T22:29:00.002+00:00</published>
        <updated>2009-10-24T22:29:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/10/24/life-update-software-learning/"/>
        <id>https://0x5.uk/2009/10/24/life-update-software-learning/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/10/24/life-update-software-learning/">&lt;p&gt;I&#x27;m currently reading &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.amazon.co.uk&#x2F;Journey-Software-Professional-Sociology-Programming&#x2F;dp&#x2F;0132366134&quot;&gt;Journey of the Software Professional: Sociology of Computer Programming&lt;&#x2F;a&gt;. It&#x27;s proved so far to be a unique insight into how developers go from seeing a problem to providing a solution, good or bad. It&#x27;s quite hard going as there&#x27;s a lot of detailed analysis into how we work, but it&#x27;s certainly given me food for thought.&lt;&#x2F;p&gt;
&lt;p&gt;In another area of self improvement, I recently passed &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.microsoft.com&#x2F;learning&#x2F;en&#x2F;us&#x2F;Exam.aspx?ID=70-536&amp;amp;Locale=en-us&quot;&gt;70-536: TS: Microsoft .NET Framework - Application Development Foundation&lt;&#x2F;a&gt;, and am currently reading up on the ASP.NET exam with a view to gaining the MCTS cert. Much as I had hoped I&#x27;d left exams behind years ago, it is proving to be a useful exercise in filling in the gaps in my knowledge. Today I finally got around to creating something with Web Parts, which I wouldn&#x27;t otherwise have done, another plan filed away in my cognitive library (cf. Journey of the Software Professional).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>backuppc and windows vista</title>
        <published>2009-10-23T01:51:00.005+00:00</published>
        <updated>2009-10-23T01:51:00.005+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/10/23/backuppc-and-windows-vista/"/>
        <id>https://0x5.uk/2009/10/23/backuppc-and-windows-vista/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/10/23/backuppc-and-windows-vista/">&lt;p&gt;Steps I took to get a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;backuppc.sourceforge.net&#x2F;&quot;&gt;backuppc&lt;&#x2F;a&gt; server on an
ubuntu 8.10 pc in order to be able to back up a windows vista business pc. I&#x27;ve
only documented the non-obvious and undocumented items here.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Added a user called backup to the vista pc.&lt;&#x2F;li&gt;
&lt;li&gt;Added the backup user to the &quot;administrators&quot; group. I tried the &quot;backup
operators&quot; group but it didn&#x27;t give access to the user profiles. It looks
like robocopy has some black magic that allows it to bypass ACLs when a
member of backup operators.&lt;&#x2F;li&gt;
&lt;li&gt;Enabled admin shares (ie &lt;code&gt;\\machine\C$&lt;&#x2F;code&gt;) by adding &lt;code&gt;DWORD&lt;&#x2F;code&gt; registry key
&lt;code&gt;LocalAccountTokenFilterPolicy&lt;&#x2F;code&gt; to
&lt;code&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System&lt;&#x2F;code&gt;
and setting the value to &lt;code&gt;1&lt;&#x2F;code&gt;. See &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.paulspoerry.com&#x2F;2007&#x2F;05&#x2F;09&#x2F;how-to-access-administrative-shares-on-vista-c&#x2F;&quot;&gt;How to access Administrative Shares on
Vista
(C$)&lt;&#x2F;a&gt;
by PaulSpoerry&lt;&#x2F;li&gt;
&lt;li&gt;Removed the &lt;code&gt;-N&lt;&#x2F;code&gt; from the &lt;code&gt;SmbClientFullCmd&lt;&#x2F;code&gt; etc options in backuppc&#x27;s
transfer (&lt;code&gt;xfer&lt;&#x2F;code&gt;) settings as it didn&#x27;t seem to be using the provided
password. Troubleshooting was aided by running
&lt;code&gt;&#x2F;usr&#x2F;share&#x2F;backuppc&#x2F;bin&#x2F;BackupPC_dump -v -f vistamachine&lt;&#x2F;code&gt; directly as user
backuppc.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;forums.techarena.in&#x2F;vista-administration&#x2F;689162.htm#post2788050&quot;&gt;Hide the backup
user&lt;&#x2F;a&gt;
from the welcome screen by adding &lt;code&gt;DWORD&lt;&#x2F;code&gt;
&lt;code&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList\backup&lt;&#x2F;code&gt; with value &lt;code&gt;0&lt;&#x2F;code&gt;
to the registry. &quot;backup&quot; is the name of the user to hide, &lt;code&gt;0&lt;&#x2F;code&gt; means hide,
&lt;code&gt;1&lt;&#x2F;code&gt; means show.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Enjoy.&lt;&#x2F;p&gt;
&lt;p&gt;See also:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.ubuntu.com&#x2F;community&#x2F;BackupPC&#x2F;smb&quot;&gt;ubuntu backuppc&#x2F;vista
guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Current status: This has only been partially successful so far. The backup runs
but has lots of files missing due access denied errors on many of the important
folders. It looks like I will have to manually give &quot;backup operators&quot;
permissions to these folders. Sigh. Vista is proving to be less than easy for
me to support.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>git-svn imports for open source projects</title>
        <published>2009-04-11T22:04:00.001+00:00</published>
        <updated>2009-04-11T22:04:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/04/11/git-svn-imports-for-open-source/"/>
        <id>https://0x5.uk/2009/04/11/git-svn-imports-for-open-source/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/04/11/git-svn-imports-for-open-source/">&lt;p&gt;I&#x27;ve just written a lengthy &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lists.gnucash.org&#x2F;pipermail&#x2F;gnucash-devel&#x2F;2009-April&#x2F;025196.html&quot;&gt;open letter to github&lt;&#x2F;a&gt; in the hope that they will support continuous centralized imports from svn to git.&lt;&#x2F;p&gt;
&lt;p&gt;If they don&#x27;t wish to rise to the challenge (and I wouldn&#x27;t hold it against them), I am wondering if it would be viable to run a server on fasthosts or something funded by donations that would do nothing but continuously import from svn servers, and push the result to github.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s all for now.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mini police eye in the sky</title>
        <published>2009-04-11T16:26:00.001+00:00</published>
        <updated>2009-04-11T16:26:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/04/11/mini-police-eye-in-sky/"/>
        <id>https://0x5.uk/2009/04/11/mini-police-eye-in-sky/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/04/11/mini-police-eye-in-sky/">&lt;p&gt;Just a quick note on an idea that&#x27;s been bothering me.&lt;&#x2F;p&gt;
&lt;p&gt;How about a mini semi autonomous police surveillance helicopter?&lt;&#x2F;p&gt;
&lt;p&gt;Would cheaper than a real helicopter, but still offers many of the advantages of having an eye in the sky that can go direct to the scene without contending with traffic etc.&lt;&#x2F;p&gt;
&lt;p&gt;Something like a electric model helicopter with 2+ blades for stability, with a petrol generator for longer run times.&lt;&#x2F;p&gt;
&lt;p&gt;Electronics and gyros to make it naturally stable, and a gps &amp;amp; altimeter for auto navigation.&lt;&#x2F;p&gt;
&lt;p&gt;Carrying a payload of normal and infrared cameras for information gathering.&lt;&#x2F;p&gt;
&lt;p&gt;Transmitting a live video feed over long range radio, and offering long distance control, so it could be controlled centrally by an operator.&lt;&#x2F;p&gt;
&lt;p&gt;I reckon these could be produced for a few thousand pounds each and provide excellent assistance to the force.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>format all documents in a visual studio solution</title>
        <published>2009-01-29T11:49:00.011+00:00</published>
        <updated>2009-01-29T11:49:00.011+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2009/01/29/format-all-document-in-visual-studio/"/>
        <id>https://0x5.uk/2009/01/29/format-all-document-in-visual-studio/</id>
        
        <content type="html" xml:base="https://0x5.uk/2009/01/29/format-all-document-in-visual-studio/">&lt;p&gt;Here&#x27;s a handy macro script for visual studio I knocked together today.  It
runs &quot;edit, format document&quot; on every document of the listed file types.&lt;&#x2F;p&gt;
&lt;p&gt;You have to keep an eye on it as it&#x27;s interactive and does sometimes pop up a
message and wait for an answer.&lt;&#x2F;p&gt;
&lt;p&gt;You can get the vb file at
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;vs-formatter-macro&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;vs-formatter-macro&lt;&#x2F;a&gt;
More info at
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wiki.github.com&#x2F;timabell&#x2F;vs-formatter-macro&quot;&gt;http:&#x2F;&#x2F;wiki.github.com&#x2F;timabell&#x2F;vs-formatter-macro&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Below is the original code. Note that this is older than the version available
on github above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Imports System&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Imports EnvDTE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Imports EnvDTE80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Imports EnvDTE90&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Imports System.Collections.Generic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Imports System.Diagnostics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Imports System.Text&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Public Module Formatting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Dim allowed As List(Of String) = New List(Of String)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Dim processed As Integer = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Dim ignored As Integer = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Dim errors As StringBuilder = New StringBuilder()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Dim skippedExtensions As List(Of String) = New List(Of String)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Public Sub FormatProject()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.master&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.aspx&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.ascx&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.asmx&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.cs&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.vb&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.config&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.css&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.htm&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.html&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  allowed.Add(&amp;quot;.js&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Try&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   recurseSolution(AddressOf processItem)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Catch ex As Exception&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Debug.Print(&amp;quot;error in main loop: &amp;quot; + ex.ToString())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  End Try&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Debug.Print(&amp;quot;processed items: &amp;quot; + processed.ToString())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Debug.Print(&amp;quot;ignored items: &amp;quot; + ignored.ToString())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Debug.Print(&amp;quot;ignored extensions: &amp;quot; + String.Join(&amp;quot; &amp;quot;, skippedExtensions.ToArray()))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Debug.Print(errors.ToString())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; End Sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Private Sub processItem(ByVal Item As ProjectItem)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  If Not Item.Name.Contains(&amp;quot;.&amp;quot;) Then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;#39;Debug.Print(&amp;quot;no file extension. ignoring.&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   ignored += 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  End If&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Dim ext As String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ext = Item.Name.Substring(Item.Name.LastIndexOf(&amp;quot;.&amp;quot;)) &amp;#39;get file extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  If allowed.Contains(ext) Then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   formatItem(Item)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   processed += 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;#39;Debug.Print(&amp;quot;ignoring file with extension: &amp;quot; + ext)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   If Not skippedExtensions.Contains(ext) Then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    skippedExtensions.Add(ext)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   End If&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   ignored += 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  End If&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; End Sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Private Sub formatItem(ByVal Item As ProjectItem)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Debug.Print(&amp;quot;processing file &amp;quot; + Item.Name)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Try&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Dim window As EnvDTE.Window&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   window = Item.Open()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   window.Activate()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   DTE.ExecuteCommand(&amp;quot;Edit.FormatDocument&amp;quot;, &amp;quot;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   window.Document.Save()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   window.Close()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Catch ex As Exception&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Debug.Print(&amp;quot;error processing file.&amp;quot; + ex.ToString())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   errors.Append(&amp;quot;error processing file &amp;quot; + Item.Name + &amp;quot;  &amp;quot; + ex.ToString())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  End Try&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; End Sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Private Delegate Sub task(ByVal Item As ProjectItem)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Private Sub recurseSolution(ByVal taskRoutine As task)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  For Each Proj As Project In DTE.Solution.Projects&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Debug.Print(&amp;quot;project &amp;quot; + Proj.Name)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   For Each Item As ProjectItem In Proj.ProjectItems&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    recurseItems(Item, 0, taskRoutine)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Next&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Next&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; End Sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Private Sub recurseItems(ByVal Item As ProjectItem, ByVal depth As Integer, ByVal taskRoutine As task)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Dim indent As String = New String(&amp;quot;-&amp;quot;, depth)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Debug.Print(indent + &amp;quot; &amp;quot; + Item.Name)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  If Not Item.ProjectItems Is Nothing Then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   For Each Child As ProjectItem In Item.ProjectItems&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    taskRoutine(Child)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    recurseItems(Child, depth + 1, taskRoutine)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Next&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  End If&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; End Sub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;End Module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>password-free ubuntu login with facebrowser</title>
        <published>2008-12-18T21:27:00.002+00:00</published>
        <updated>2008-12-18T21:27:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/12/18/password-free-ubuntu-login-with/"/>
        <id>https://0x5.uk/2008/12/18/password-free-ubuntu-login-with/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/12/18/password-free-ubuntu-login-with/">&lt;p&gt;If you trust everyone who has physical access to a pc (if not then you are
encrypting your files, right?) then there seems little point in having to type
a password just because more than one user uses the pc.&lt;&#x2F;p&gt;
&lt;p&gt;So here&#x27;s how to log in from the gdm &quot;face browser&quot; with a single click.
Instructions tested with Ubuntu 8.04 Hardy Heron and 8.10 Intrepid Ibex.&lt;&#x2F;p&gt;
&lt;p&gt;As root, create a new file containing the usernames of all the users you want
be able to log in through gdm without entering a password:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo -i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;#39;username&amp;#39; &amp;gt;&amp;gt; &#x2F;etc&#x2F;gdm&#x2F;nopassusers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;now still as root modify the pam settings for gdm to check this file and allow this user in based on being in the list:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vi &#x2F;etc&#x2F;pam.d&#x2F;gdm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and modify to contain the new listfile item&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#%PAM-1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth requisite pam_nologin.so&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth required pam_env.so readenv=1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth required pam_env.so readenv=1 envfile=&#x2F;etc&#x2F;default&#x2F;locale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**auth sufficient pam_listfile.so item=user sense=allow file=&#x2F;etc&#x2F;gdm&#x2F;nopassusers onerr=fail** #add this line&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@include common-auth&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth optional pam_gnome_keyring.so&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@include common-account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;session required pam_limits.so&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@include common-session&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;session optional pam_gnome_keyring.so auto_start&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@include common-password&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;now simply restart gdm (or the whole machine) and try your new one-click login&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;etc&#x2F;init.d&#x2F;gdm restart&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;notes&quot;&gt;Notes&lt;&#x2F;h1&gt;
&lt;p&gt;This means the keyring isn&#x27;t unlocked, so you may have to type in your password anyway before your wireless connects.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;mirror.hamakor.org.il&#x2F;archives&#x2F;linux-il&#x2F;05-2004&#x2F;10149.html&quot;&gt;http:&#x2F;&#x2F;mirror.hamakor.org.il&#x2F;archives&#x2F;linux-il&#x2F;05-2004&#x2F;10149.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.kernel.org&#x2F;pub&#x2F;linux&#x2F;libs&#x2F;pam&#x2F;Linux-PAM-html&#x2F;sag-pam_listfile.html&quot;&gt;http:&#x2F;&#x2F;www.kernel.org&#x2F;pub&#x2F;linux&#x2F;libs&#x2F;pam&#x2F;Linux-PAM-html&#x2F;sag-pam_listfile.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>error &quot;Not a valid object name&quot; filtering an ex-svn git repo with renames</title>
        <published>2008-09-10T14:18:00.007+00:00</published>
        <updated>2008-09-10T14:18:00.007+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/09/10/error-not-valid-object-name-filtering/"/>
        <id>https://0x5.uk/2008/09/10/error-not-valid-object-name-filtering/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/09/10/error-not-valid-object-name-filtering/">&lt;p&gt;Under git version 1.5.4.3, which as of writing is the current in ubuntu 8.04
hardy heron, trying to split out a folder from a git repo where the repo was an
import from subversion (svn), and the folder was renamed in the past causes a
failure as show below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash -v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rm -rf test-case&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir test-case&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd test-case&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svnadmin create svnrepo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;export repo=&amp;quot;`pwd`&#x2F;svnrepo&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir -p import&#x2F;a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;#39;1&amp;#39; &amp;gt;&amp;gt; import&#x2F;a&#x2F;file.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn import -m &amp;#39;initial import&amp;#39; import file:&#x2F;&#x2F;$repo&#x2F;trunk&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn co file:&#x2F;&#x2F;$repo&#x2F;trunk&#x2F; checkout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;#39;2&amp;#39; &amp;gt;&amp;gt; checkout&#x2F;a&#x2F;file.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn ci -m &amp;quot;file modified&amp;quot; checkout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn mv -m &amp;quot;moving file&amp;quot; file:&#x2F;&#x2F;$repo&#x2F;trunk&#x2F;a file:&#x2F;&#x2F;$repo&#x2F;trunk&#x2F;b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn up checkout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;#39;3&amp;#39; &amp;gt;&amp;gt; checkout&#x2F;b&#x2F;file.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn ci -m &amp;quot;modified again&amp;quot; checkout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn log -v checkout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir -p gitcopy&#x2F;a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git svn clone file:&#x2F;&#x2F;$repo&#x2F;trunk&#x2F; gitcopy&#x2F;a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd gitcopy&#x2F;a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git filter-branch --subdirectory-filter a   # &amp;lt;= FAILS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&#x2F;..&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir gitcopy&#x2F;b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git svn clone file:&#x2F;&#x2F;$repo&#x2F;trunk&#x2F; gitcopy&#x2F;b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd gitcopy&#x2F;b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git filter-branch --subdirectory-filter b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The marked line above fails with the following error:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[1] Rewrite bcfe73ef303832b6112a2419dc1da5f782672c14 (3&#x2F;3)fatal:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Not a valid object name bcfe73ef303832b6112a2419dc1da5f782672c14:a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This has been fixed in the latest build of git: &lt;code&gt;version 1.6.0.1.294.gda06a&lt;&#x2F;code&gt;
and no longer fails.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;fatal: Not a git repository&quot; error message that filter branch produces
doesn&#x27;t seem to matter.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a  href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;2800643267&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;3085&#x2F;2800643267_aa1dd46299.jpg&quot; alt=&quot;Photo of a break dancer in barcelona&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>reseting home folder permissions in ubuntu linux</title>
        <published>2008-08-24T15:03:00.006+00:00</published>
        <updated>2008-08-24T15:03:00.006+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/08/24/reseting-home-folder-permissions-in/"/>
        <id>https://0x5.uk/2008/08/24/reseting-home-folder-permissions-in/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/08/24/reseting-home-folder-permissions-in/">&lt;p&gt;If you are like me and my coworkers, you often end up running stuff as root in
your home folder and end up not able to access your own files.&lt;&#x2F;p&gt;
&lt;p&gt;For the record, here&#x27;s the commands to reset the permissions (leaving all execute flags off, which may not be what you want).&lt;&#x2F;p&gt;
&lt;p&gt;Warning, this could have undesired side effects. If you have executable files in your home folder that you actually want to be executable, you will have to manually mark them as executable again.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Become root (as you don&amp;#39;t currently have permissions to modify your own files)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo -i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Reset ownership &amp;amp; group to yourself&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chown -R tim:tim &#x2F;home&#x2F;tim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# give yourself the default read-write permissions, set group and other to read only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chmod -R 644 &#x2F;home&#x2F;tim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# re-apply excecute permissions on all the directories&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;find &#x2F;home&#x2F;tim -type d -print0 | xargs -0 -II chmod 755 &amp;#39;I&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Don&amp;#39;t leave your private keys showing:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chmod -R 700 &#x2F;home&#x2F;tim&#x2F;.ssh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;My latest use for this was after extracting files from my p910i with p3nfs,
which as with so many desktop&#x2F;device tasks needed root to work.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;2792157421&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;3226&#x2F;2792157421_2b8a33c6c6.jpg&quot; alt=&quot;Photo of stained class at Guilford Catherdral&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;You could do this slightly more neatly if you know what permissions you have
ended up with by using &lt;code&gt;chmod u+w&lt;&#x2F;code&gt; etc so you don&#x27;t have to re-apply directory
permissions, but I wanted to easily guarantee permissions are right regardless
of what state they have ended up in.&lt;&#x2F;p&gt;
&lt;p&gt;It occurs to me it might be sensible to set the sticky bit on the home folders
so that anything added by root stays owned by the user. (&lt;code&gt;chmod u+s g+s &#x2F;home&#x2F;tim&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Don&#x27;t trust audible.com, it&#x27;s drm infected and they don&#x27;t tell you</title>
        <published>2008-07-23T22:28:00.006+00:00</published>
        <updated>2008-07-23T22:28:00.006+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/07/23/dont-trust-audiblecom-its-drm-infected/"/>
        <id>https://0x5.uk/2008/07/23/dont-trust-audiblecom-its-drm-infected/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/07/23/dont-trust-audiblecom-its-drm-infected/">&lt;p&gt;If there&#x27;s one thing I hate (there isn&#x27;t, there&#x27;s lots, but this is today&#x27;s)
it&#x27;s companies being economical with the truth to get you to part with your
money, only to have you disappointed when you find out the whole truth.&lt;&#x2F;p&gt;
&lt;p&gt;I just bought an audio book on audible.co.uk. And now I can&#x27;t even listen to
it. I thought I was buying an mp3, or maybe even an ogg file. It is only on
actually attempting to download the thing I have just paid for that I discover
to my utter disgust that &lt;em&gt;all&lt;&#x2F;em&gt; the download links are for some kind of evil drm
type program (I presume here, but there sure as hell was no mp3 in sight).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;audible-screenshot-2008.jpg&quot; alt=&quot;audible.com screenshot claiming mp3 support&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As you can see from the screenshot above, they clearly imply an mp3 download. I
haven&#x27;t seen such a clear use of weasel sales words for some time.&lt;&#x2F;p&gt;
&lt;p&gt;Next time I&#x27;ll read the god damn small print, but I still think this is totally
out of order not warning that they are providing crippled versions of what you
think you are buying.&lt;&#x2F;p&gt;
&lt;p&gt;Thank fsm for people like the FSF. Their logo really sums up how I feel about
being treated in this way.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.defectivebydesign.org&#x2F;&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;dbd-logo.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;update-credit-where-due-24th-july-2008&quot;&gt;Update: credit where due. 24th July 2008&lt;&#x2F;h2&gt;
&lt;p&gt;My complaint about the website still stands, and my aversion to
drm has not diminished, however the responses I have received from their
customer service (by email), have been prompt, courteous and have totally
resolved my outstanding problem. I have been given a full refund. I&#x27;ve been
especially impressed given the hot blooded content of my initial contact. A lot
of companies could learn lessons in good customer relations from these people.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;update-the-battle-is-lost-for-now-12-aug-2019&quot;&gt;Update: the battle is lost (for now). 12 Aug 2019&lt;&#x2F;h2&gt;
&lt;p&gt;I use audible (now an amazon company) on my not-very-freedom-loving android
phone these days. I haven&#x27;t tried using audbile on a linux desktop lately,
times have changed and everything is android&#x2F;iphone first now. I still consider
DRM to be a nasty form of lockin.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>work at emapsite</title>
        <published>2008-07-16T14:34:00.003+00:00</published>
        <updated>2008-07-16T14:34:00.003+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/07/16/work-at-emapsite/"/>
        <id>https://0x5.uk/2008/07/16/work-at-emapsite/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/07/16/work-at-emapsite/">&lt;p&gt;The company I work for, emapsite is hiring a developer.&lt;br &#x2F;&gt;
Interviews are starting so you&#x27;ll have to be quick.&lt;&#x2F;p&gt;
&lt;p&gt;More details available on their &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.emapsite.com&#x2F;news&#x2F;viewnews.aspx?story=160&quot;&gt;news item&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New wiki, mostly for car pc</title>
        <published>2008-07-14T21:37:00.002+00:00</published>
        <updated>2008-07-14T21:37:00.002+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/07/14/new-wiki-mostly-for-car-pc/"/>
        <id>https://0x5.uk/2008/07/14/new-wiki-mostly-for-car-pc/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/07/14/new-wiki-mostly-for-car-pc/">&lt;p&gt;I&#x27;ve created a wiki at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.wikispaces.com&#x2F;&quot;&gt;wikispaces.com&lt;&#x2F;a&gt;, to document things that are less transient than a blog entry.&lt;&#x2F;p&gt;
&lt;p&gt;Take a look at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;timwise.wikispaces.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;timwise.wikispaces.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve started adding information about the car pc, and won&#x27;t make any promises about what else I&#x27;ll be adding (personal motto: under promise, over deliver).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve made it open to all editors, and licensed under the GNU Free documentation licence to ensure the maximum value, reach and participation.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nightly Shutdown, a new product from Proven Works</title>
        <published>2008-07-03T19:30:00.006+00:00</published>
        <updated>2008-07-03T19:30:00.006+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/07/03/nightly-shutdown-new-product-from/"/>
        <id>https://0x5.uk/2008/07/03/nightly-shutdown-new-product-from/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/07/03/nightly-shutdown-new-product-from/">&lt;p&gt;Congratulations to Joel Mansford, a good friend of mine, and his company
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.provenworks.com&#x2F;&quot;&gt;Proven Works&lt;&#x2F;a&gt; on getting the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;joelmansford.wordpress.com&#x2F;2008&#x2F;07&#x2F;02&#x2F;new-utility-to-shutdown-your-network-pcs-at-night&#x2F;&quot;&gt;first
release&lt;&#x2F;a&gt;
of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.nightlyshutdown.com&#x2F;&quot;&gt;Nightly Shutdown&lt;&#x2F;a&gt; out of the door.&lt;&#x2F;p&gt;
&lt;p&gt;This looks to be a great product and hopefully will make system administrators&#x27;
lives easier and greener. It&#x27;s a utility for ensuring that the computers are
off when you want them to be, and can be deployed through active directory
making the sys admin&#x27;s life easier. There&#x27;s a 10 PC free trial available, so
check it out at the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.nightlyshutdown.com&#x2F;DownloadRequest.aspx&quot;&gt;download
page&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.nightlyshutdown.com&#x2F;&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;nightly-shutdown.png&quot; alt=&quot;Nightly Shutdown poster&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Without even looking I know this will be a good
product and fantastically well supported. Best of luck to all at Proven Works,
and to all the potential users and buyers out there, don&#x27;t forget to check it
out and provide any feedback you can.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A vision of open in-car computing systems</title>
        <published>2008-06-06T21:36:00.007+00:00</published>
        <updated>2008-06-06T21:36:00.007+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/06/06/vision-of-open-in-car-computing-systems/"/>
        <id>https://0x5.uk/2008/06/06/vision-of-open-in-car-computing-systems/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/06/06/vision-of-open-in-car-computing-systems/">&lt;p&gt;I have a vision. A vision that puts you in control of your in car computing
experience.&lt;&#x2F;p&gt;
&lt;p&gt;There are many superb appliances and embedded devices available for your in-car
enjoyment, such as the sat navs, the dvd players, the built in games consoles.
But they all share one thing in common, they are closed to you. You don&#x27;t have
the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fsf.org&#x2F;about&#x2F;what-is-free-software&quot;&gt;freedoms&lt;&#x2F;a&gt; defined by
Stallman because they are designed, intentionally or otherwise, to be hard for
you to modify as you wish.&lt;&#x2F;p&gt;
&lt;p&gt;I feel deep in my heart that there is enormous potential for in-car computing.
There are more possibilities than any individual or company can imagine or
provide on their own. I&#x27;m sure my imagination is not big enough to list them
here, so I leave the ideas for you to contemplate.&lt;&#x2F;p&gt;
&lt;p&gt;Add to this, the evidence and my experience that open source when done right
produces the better engineered solution at a lower cost, and you have a
compelling argument for such a system.&lt;&#x2F;p&gt;
&lt;p&gt;I have seen the freedom that open source and the GPL provide on the desktop
computer, and I believe that this culture of openness and freedom for the users
can be applied to the in-car computing market to the benefit of all.&lt;&#x2F;p&gt;
&lt;p&gt;My mission is to provide a basis for this innovation, and cultivate a thriving
ecosystem in the way that only open systems can. And so, my vision is a range
of affordable flexible and most importantly open computing devices for your
car.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;carpc-case.jpg&quot; alt=&quot;front view of voompc case&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And so, I introduce to you in the above photo, the mark one of my in-car pc. It
has no name, and the software and hardware needs some work to say the least,
but in the tradition of openness on the internet, I will present here my ups
and downs, successes and failures, genius and downright stupidity for your
entertainment.&lt;&#x2F;p&gt;
&lt;p&gt;I have minimal spare time and numerous other projects, but there is no rush, as
I think this plan will stand the test of time, and all the while hardware gets
cheaper, smaller, faster and less power hungry. As I progress in fits and
starts I will post photos to flickr under the tag carpc (&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;sets&#x2F;72157605474187579&#x2F;&quot;&gt;first
set&lt;&#x2F;a&gt;) and
progress updates to this blog under tag
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;timwise.blogspot.com&#x2F;search&#x2F;label&#x2F;carpc&quot;&gt;carpc&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;All feedback welcome. I will announce new articles on my twitter feed,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;twitter.com&#x2F;tim_abell&quot;&gt;twitter.com&#x2F;tim_abell&lt;&#x2F;a&gt;, and can be contacted
using the links at the bottom of my blog.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sharing work between computers with a usb flash drive and git</title>
        <published>2008-05-29T23:36:00.007+00:00</published>
        <updated>2008-05-29T23:36:00.007+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/05/29/sharing-work-between-computers-with-usb/"/>
        <id>https://0x5.uk/2008/05/29/sharing-work-between-computers-with-usb/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/05/29/sharing-work-between-computers-with-usb/">&lt;p&gt;I couldn&#x27;t find anything exactly matching this on the net when I was figuring
it out, so here&#x27;s what I did.&lt;&#x2F;p&gt;
&lt;p&gt;This is working against a remote svn (subversion) server, but applies even
without one.&lt;&#x2F;p&gt;
&lt;p&gt;On the first computer, grab your git working copy from svn with git-svn clone
(or clone a git repo, or just start a new one).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir ~&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ~&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git-svn clone svn:&#x2F;&#x2F;project-server&#x2F;trunk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git repack #for good measure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Plugin your usb flash drive&#x2F;stick&#x2F;external harddrive, I&#x27;ll presume it&#x27;s a
vfat&#x2F;fat32&#x2F;fat16 formated device mounted at &lt;code&gt;&#x2F;media&#x2F;flash&lt;&#x2F;code&gt;.  Create an empty
repository on the drive, I&#x27;ll use a bare one as there&#x27;s no need to keep the
working copy as well.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir &#x2F;media&#x2F;flash&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git --bare init &#x2F;media&#x2F;flash&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then add the flash drive git repo as a remote source in your local git repo.
&quot;flash&quot; is the name I&#x27;ve given to the remote branch reference, you can call it
whatever you like.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git remote add flash &#x2F;media&#x2F;flash&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you push immediately it will fail (as I discovered) because fat doesn&#x27;t
support the execute flag on files, so all the hooks are automatically active.&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;2500350904&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;3180&#x2F;2500350904_0b0c2a44f3.jpg&quot; alt=&quot;Photo of blue parrot&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I deleted all the hooks as I wasn&#x27;t planning on using them, this may be wrong
so no promises, but it seems ok so far for me. So remove the hooks with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rm &#x2F;media&#x2F;flash&#x2F;project.git&#x2F;hooks&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then push your current local copy to the flash drive with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git push flash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will copy all your committed work onto the flash drive, even if you
haven&#x27;t pushed it upstream to the svn server with &lt;code&gt;git-svn dcommit&lt;&#x2F;code&gt; yet. Bonus!
It won&#x27;t copy any of your branches across though, so you if you want them you
can add those independently with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git push flash mybranch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now move over to the second computer and plug the flash drive in. I&#x27;m making
the same assumptions on paths and devices. Do another completely independent
svn checkout as above:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir ~&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ~&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git-svn clone svn:&#x2F;&#x2F;project-server&#x2F;trunk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git repack #for good measure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then add the flash drive&#x27;s repo to the git repo on the second pc and pull all
changes from the flash drive, optionally including any branches:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git remote add flash &#x2F;media&#x2F;flash&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git pull flash master&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git pull flash mybranch #if you like&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When you&#x27;ve committed changes to git or pulled the latest changes from svn on
either pc, you can then update the flash drive with the simple command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git push flash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which pushes all your changes on your master branch on to the flash drive. You
are now ready to run the pull command on the other computer to get back in
sync:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git pull flash master&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you don&#x27;t push changes to the flash drive before committing to svn then
things will be very simple. If you push changes to the flash drive, and then
commit them to the svn server you will need to do a little more work. This is
because when you run &quot;git svn dcommit&quot; it pushes your latest git commits to the
svn server, deletes your locally committed changes, and then fetches them back
from the svn server. This means that git won&#x27;t recognise your local changes as
being the same as the ones on the flash drive because they have different
commit message and SHA1 hash. Attempting to push to the flash drive fails with
the message &lt;code&gt;! [rejected] master -&amp;gt; master (non-fast forward)&lt;&#x2F;code&gt; as the old copy
of the commits are still there.&lt;&#x2F;p&gt;
&lt;p&gt;To resolve this you need to throw away the matching set of changes on the flash
drive. To do this you can use git reset as follows, where &lt;code&gt;HEAD~1&lt;&#x2F;code&gt; should be
the number of commits you need to throw away (eg &lt;code&gt;HEAD~3&lt;&#x2F;code&gt; to throw away the
last 3 commits that were pushed to the flash drive):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &#x2F;media&#x2F;flash&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git --bare log #to see how many changes don&amp;#39;t have svn information&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git --bare reset HEAD~1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can then push your changes as above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ~&#x2F;project.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git push flash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;ve glossed over subtleties with fetch vs pull, but hopefully you will find
this useful.&lt;&#x2F;p&gt;
&lt;p&gt;This howto makes use of git&#x27;s ability to pull from multiple sources, and I&#x27;ve
found that git quite happily copes with changes that were checked in to svn
coming via the flash drive, even when later running &quot;git-svn rebase&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Please do comment or contact me with any problems, errors, extra info and
feedback, and let me know if it was useful.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Removing the execute flag from many files</title>
        <published>2008-05-17T20:33:00.003+00:00</published>
        <updated>2008-05-17T20:33:00.003+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/05/17/removing-execute-flag-from-many-files/"/>
        <id>https://0x5.uk/2008/05/17/removing-execute-flag-from-many-files/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/05/17/removing-execute-flag-from-many-files/">&lt;p&gt;Here&#x27;s how to recursively remove execute permissions on files that have been copied from a windows system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;find * -type f -exec chmod -x {} \;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ie, find all files (not directories), and execute a command to remove all execute permissions for each file.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My bash prompt</title>
        <published>2008-03-31T21:37:00.007+00:00</published>
        <updated>2008-03-31T21:37:00.007+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/03/31/my-bash-prompt/"/>
        <id>https://0x5.uk/2008/03/31/my-bash-prompt/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/03/31/my-bash-prompt/">&lt;p&gt;I like a new line in my prompt so that if I&#x27;m deep in a path I don&#x27;t end up
with 10 characters left to type in, and pretty colours so that it&#x27;s easy to
spot the prompt when scrolling through lots of output.&lt;&#x2F;p&gt;
&lt;p&gt;Update 26&#x2F;04&#x2F;2008, added red for root.&lt;&#x2F;p&gt;
&lt;p&gt;From my &lt;code&gt;~&#x2F;.bashrc&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Comment in the above and uncomment this below for a color prompt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if [ $UID = 0 ] ;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PS1=&amp;#39;${debian_chroot:+($debian_chroot)}\[\033[00;31m\]\u@\h\[\033[00m\]:\[\033[00;34m\]\w\[\033[00m\]\n\$ &amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PS1=&amp;#39;${debian_chroot:+($debian_chroot)}\[\033[00;32m\]\u@\h\[\033[00m\]:\[\033[00;34m\]\w\[\033[00m\]\n\$ &amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The result (more or less):&lt;&#x2F;p&gt;
&lt;div&gt;
&lt;code&gt;
&lt;span style=&quot;color: rgb(0, 153, 0);&quot;&gt;tim@lap&lt;&#x2F;span&gt;:&lt;span style=&quot;color: rgb(102, 0, 204);&quot;&gt;~&#x2F;Documents&lt;&#x2F;span&gt;
$ echo &quot;That&#x27;s better&quot;
&lt;&#x2F;code&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Enjoy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>stop motion animation on linux</title>
        <published>2008-03-27T21:29:00.007+00:00</published>
        <updated>2008-03-27T21:29:00.007+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/03/27/stop-motion-animation-on-linux/"/>
        <id>https://0x5.uk/2008/03/27/stop-motion-animation-on-linux/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/03/27/stop-motion-animation-on-linux/">&lt;p&gt;A quick howto...&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Take a series of photos on your digital camera.&lt;&#x2F;li&gt;
&lt;li&gt;Copy them onto your linux box.&lt;&#x2F;li&gt;
&lt;li&gt;shrink the photos to a more managable size:
&lt;code&gt;mogrify -verbose -resize 600x400 -quality 60% *.JPG&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Preview the animation with animate:
&lt;code&gt;animate -delay 8 *&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Optionally rotate the image to match the exif information from your camera (mine was sideways):
&lt;code&gt;exiftran -ai *&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Convert the jpg files to png:
mogrify -format png *.JPG&lt;&#x2F;li&gt;
&lt;li&gt;Create the flash animation from the PNG files:
&lt;code&gt;png2swf -r 15 -o flower2.swf -v -X 399 -Y 600 *.png&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Create an html file to hold the animation containing the following:&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;object&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;param name=&amp;quot;movie&amp;quot; value=&amp;quot;flower2.swf&amp;quot; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;param name=&amp;quot;loop&amp;quot; value=&amp;quot;true&amp;quot; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;param name=&amp;quot;quality&amp;quot; value=&amp;quot;high&amp;quot; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;embed src=&amp;quot;flower2.swf&amp;quot; width=&amp;quot;399&amp;quot; height=&amp;quot;600&amp;quot; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;object&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Write a blog article to tell everyone about it ;-)
&quot;history&quot; is a handy command for reviewing your activities for writing up your achievements.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;And here it is, providing I&#x27;ve kept up with my hosting fees and not been slashodotted:&lt;&#x2F;p&gt;
&lt;div style=&quot;padding: 1em; border: 2px solid black;&quot;&gt;
&lt;object&gt;
&lt;param name=&quot;movie&quot; value=&quot;http:&#x2F;&#x2F;timwise.co.uk&#x2F;photos&#x2F;flower2.swf&quot;&gt;
&lt;param name=&quot;loop&quot; value=&quot;true&quot;&gt;
&lt;param name=&quot;quality&quot; value=&quot;high&quot;&gt;
&lt;embed src=&quot;https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;timabell&#x2F;timwise.co.uk&#x2F;master&#x2F;assets&#x2F;flower2.swf&quot; width=&quot;399&quot; height=&quot;600&quot;&gt;
&lt;&#x2F;object&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Update, that was an embedded flash file ^ which isn&#x27;t really a thing on the internet any more.&lt;&#x2F;p&gt;
&lt;p&gt;The original flash file: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;timabell&#x2F;timwise.co.uk&#x2F;master&#x2F;assets&#x2F;flower2.swf&quot;&gt;flower2.swf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tech support at its worst</title>
        <published>2008-01-30T18:51:00.001+00:00</published>
        <updated>2008-01-30T18:51:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2008/01/30/tech-support-at-its-worst/"/>
        <id>https://0x5.uk/2008/01/30/tech-support-at-its-worst/</id>
        
        <content type="html" xml:base="https://0x5.uk/2008/01/30/tech-support-at-its-worst/">&lt;p&gt;As you may know, I&#x27;m working through a Microsoft e-learning course at the
moment. Having had a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.flickr.com&#x2F;photo_zoom.gne?id=2206580619&amp;amp;size=o&quot;&gt;few
problems&lt;&#x2F;a&gt; with the
service I&#x27;ve been trying to extract some common sense from their support
services. Having failed to get anything vaguely helpful I thought I&#x27;d ask them
about who they were, and I think the following response really sums up the
level of idiocy I have encountered thus far.&lt;&#x2F;p&gt;
&lt;p&gt;When asked a simple direct question about who I was communicating with, the
response is either hilarious or depressing, I&#x27;m not sure which. It would seem
that before they can tell me where they are based, they need to know what
operating system I run, what version of flash I have, what my login is etc etc.
Talk about customer disservice. The finishing touch for me is the addition of
upbeat advertising added to a response to an evidently already irritated
customer.&lt;&#x2F;p&gt;
&lt;p&gt;Here are the last two messages for your entertainment (identifiers stripped out):&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;-------- Original Message --------&lt;br &#x2F;&gt;
Subject: Re: MCP Ref: C ###### \ site broken. (########)&lt;br &#x2F;&gt;
Date: Thu, 24 Jan 2008 16:03:12 +0000&lt;br &#x2F;&gt;
From: Tim&amp;lt;tim@timwise.co.uk&amp;gt;&lt;br &#x2F;&gt;
To: emeamcp@msdirectservices.com&amp;lt;emeamcp@msdirectservices.com&amp;gt;&lt;&#x2F;p&gt;
&lt;p&gt;I have a couple of questions for you:&lt;&#x2F;p&gt;
&lt;p&gt;What company are you directly employed by?
Where are you based?&lt;&#x2F;p&gt;
&lt;p&gt;Thanks&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The highly considered response:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;-------- Original Message --------&lt;br &#x2F;&gt;
Subject: MCP Ref: C ##### \ site broken. (#######################)&lt;br &#x2F;&gt;
Date: Wed, 30 Jan 2008 15:59:21 +0100 (CET)&lt;br &#x2F;&gt;
From: emeamcp@msdirectservices.com&amp;lt;emeamcp@msdirectservices.com&amp;gt;&lt;br &#x2F;&gt;
To: Tim&amp;lt;tim@timwise.co.uk&amp;gt;&lt;&#x2F;p&gt;
&lt;p&gt;Hello Tim,&lt;&#x2F;p&gt;
&lt;p&gt;Thank you for contacting Learning Manager Support.&lt;&#x2F;p&gt;
&lt;p&gt;In order for us to process this request, we need the following
information from you:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Step by step screen shots of the entire process including the error
message&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Your log in Live ID and the Unique ID associated to it.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To obtain your Unique ID, please follow the steps provided:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Visit http:&#x2F;&#x2F;account.live.com&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Sign in using your passport account.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;After singing in you will see a page with more options. Please click
on &#x27;Registered information&#x27;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;At the bottom of this page you will see your Unique ID. It will look
like this: &#x27;000XXXXXXXXXXXXX&#x27;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Detailed description of what the problem&#x2F;issue is that you are
experiencing.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;What is the Operating System that you are using?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;What is the Internet Browser and version that you are using?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;What version of Flash and Shockwave are you using?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Screenshot of the following webpage: https:&#x2F;&#x2F;learning.microsoft.com&#x2F;Commerce&#x2F;PurchaseHistory.aspx&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While some of the above information may not seem applicable to your
issue, it is important that we must receive them in order to best
resolve your issue.&lt;&#x2F;p&gt;
&lt;p&gt;Please also note that we unfortunately are not allowed to provide you
any information about our location.&lt;&#x2F;p&gt;
&lt;p&gt;Looking forward to receiving your reply.&lt;&#x2F;p&gt;
&lt;p&gt;Kind Regards&lt;&#x2F;p&gt;
&lt;p&gt;Natalia Wojtaszek&lt;&#x2F;p&gt;
&lt;p&gt;Microsoft Regional Service Center&lt;br &#x2F;&gt;
E-Mail: emeamcp@msdirectservices.com&lt;br &#x2F;&gt;
Tel.: 0800-9170758 or 0800 0960137&lt;br &#x2F;&gt;
Fax: ++49 5 24 11 79 60 77&lt;&#x2F;p&gt;
&lt;p&gt;In order to keep up to date with the MCP&#x2F; MCT program your contact
details need to be correct.&lt;&#x2F;p&gt;
&lt;p&gt;Don´t forget: You can update your contact details yourself in the
Profile Editor on the MCP&#x2F; MCT Secure Site at ...&lt;&#x2F;p&gt;
&lt;p&gt;NOW AVAILABLE: Virtual PC-enabled Labs in Official Microsoft Learning
Products https:&#x2F;&#x2F;partnering.one.microsoft.com&#x2F;mct&#x2F;vpc&#x2F;default.aspx&lt;&#x2F;p&gt;
&lt;p&gt;Microsoft highly recommends that users with Internet access update their
Microsoft software to protect against viruses and security
vulnerabilities. The easiest way to do this is to visit the following
website: http:&#x2F;&#x2F;www.Microsoft.com&#x2F;protect&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It&#x27;s worth noting that this is totally consistent with the level of service I
have experienced with Microsoft e-learning. As far as I can fathom, the
e-learning system has been set up on a pile of servers and then been left to
rot whilst paying customers are fobbed off by a nameless and faceless 3rd
party. It may be profitable in the short term, but this kind of behaviour may
well be the cracks in the foundations of Microsoft&#x27;s empire. I for one am
certainly plotting a course for fairer pastures.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Preparing photos for a digital picture frame</title>
        <published>2007-12-28T19:28:00.003+00:00</published>
        <updated>2007-12-28T19:28:00.003+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/12/28/preparing-photos-for-digital-picture/"/>
        <id>https://0x5.uk/2007/12/28/preparing-photos-for-digital-picture/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/12/28/preparing-photos-for-digital-picture/">&lt;p&gt;Challenge of the day was to fit as many photos as possible on a single flash
card to stick in a digital photo frame. Here&#x27;s how it&#x27;s done.&lt;&#x2F;p&gt;
&lt;p&gt;The frame from Philips goes by the memorable name of
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.consumer.philips.com&#x2F;consumer&#x2F;en&#x2F;ca&#x2F;consumer&#x2F;cc&#x2F;_productid_9FF2M4_37_CA_CONSUMER&#x2F;&quot;&gt;9FF2M4&lt;&#x2F;a&gt;
, and by way of a quick review it is very nice. If I were a normal person, I
would probably have copied the original 2.5MB &#x2F; 5 megapixel images to the
frame&#x27;s flash card (1GB Compact Flash in this case, though it can take others),
and put up with not being able to fit &lt;em&gt;all&lt;&#x2F;em&gt; the photos on, and having some of them show sideways. But
being a perfectionist I instead sacrificed precious sleeping time to figure out
what to do. In the end I managed to trim the files down to around 200KB each,
and put portrait photos on a black background the right way up in order to save
neck ache from squinting at a sideways eiffel tower. This was all done by the
power of OSS and bash scripting. Here I present for your convenience the
methods I used, and highlight some of the useful things I picked up along the
way.&lt;&#x2F;p&gt;
&lt;p&gt;The first thing that taxed me was what size the photos needed to be to display
best whilst taking up minimal space. You would think the answer would be
emblazened on the product&#x27;s box, but no! Philips don&#x27;t seem to be too keen on
promoting the resolution of the display, and even the shop keeper struggled to
give me a number. The owner&#x27;s manual states: &quot;Resolution: 800 x 480 pixels
(viewing area 680 x 480)&quot; but after some time experimenting with test images
created with &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;gimp.org&#x2F;&quot;&gt;the gimp&lt;&#x2F;a&gt; I came to the conclusion that it was
impossible to get the frame to display an image pixel perfect as it seemed to
be re-scaling every picture regardless of original size. There appears to be no
guidance from Philips as to what a good resolution for the photos would be, so
after some experimentation I settled on 800x600 as this is slightly higher than
the frame&#x27;s native resolution, and fills the screen nicely without loosing too
much off the edges when displayed.&lt;&#x2F;p&gt;
&lt;p&gt;The frame does not appear to read orientation from the exif data so I looked
into rotating all the portrait images to display correctly. I am using the
frame in its landscape orientation as that is the form of most of the photos,
even though it can be placed in portrait orientation. When a portrait photos is
displayed (eg 480x600), the frame puts a fair amount of the image off the top
and bottom of the display, and by default puts it on a full white background
which is a little hard on the eyes and detracts from darker photos. I therefore
opted to create landscape images of 800x600 with a black background for all the
portrait photos. I later discovered that you can on this frame change the
background colour as follows: Main menu &amp;gt; Slideshow &amp;gt; Background colour &amp;gt; White
&#x2F; Black Grey.&lt;&#x2F;p&gt;
&lt;p&gt;The process I have used is a little specific to my setup and needs, but
hopefully will give you a good starting point. I have created 3 bash scripts
that call each other to orchestrate the conversion from my raw photo collection
to a new set suitable for the frame, which in turn make use of imageMagick and
exiftran to do the work.&lt;&#x2F;p&gt;
&lt;p&gt;I found out about &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.imagemagick.org&#x2F;&quot;&gt;imageMagick&lt;&#x2F;a&gt; through searching,
and tutorials such as &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.smokinglinux.com&#x2F;tutorials&#x2F;howto-batch-image-resize-on-linux&quot;&gt;HowTo - Batch Image Resize on
Linux&lt;&#x2F;a&gt;.
The version packaged with Ubuntu 7.10 is quite old, so I ended up building and
installing the latest version (6.3.7) from source to get all the functionality
I needed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;exiftran&lt;&#x2F;code&gt; is a nifty utility that reads the exif orientation information in a
photo, losslessly rotates the photo to match and then updates the exif data. It
is closely related to &lt;code&gt;jpegtran&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;My folder structure in my home folder (so the scripts make sense):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;scripts (for bash scripts)&lt;&#x2F;li&gt;
&lt;li&gt;photos (originals)
&lt;ul&gt;
&lt;li&gt;2005
&lt;ul&gt;
&lt;li&gt;2005-12-31 event name&lt;&#x2F;li&gt;
&lt;li&gt;etc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;2006
&lt;ul&gt;
&lt;li&gt;etc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;photos_frame (for the modified and shrunk photos which will be copied onto the flash card)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So without further ado, here&#x27;s the scripts:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;frame.sh&lt;&#x2F;strong&gt; - runs the processing scripts on each year folder of interest&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash -v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;scripts&#x2F;frame_photo_folder.sh 2005 ~&#x2F;photos_frame&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;scripts&#x2F;frame_photo_folder.sh 2006 ~&#x2F;photos_frame&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;scripts&#x2F;frame_photo_folder.sh 2007 ~&#x2F;photos_frame&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;frame_photo_folder.sh&lt;&#x2F;strong&gt; - runs the processing script on subfolder of the year&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#arg 1 = input folder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#arg 2 = output folder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;INPUTPATH=$1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OUTPATH=$2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd $INPUTPATH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if [ ! -d &amp;quot;$OUTPATH$INPUTPATH&amp;quot; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo creating output folder \&amp;quot;$OUTPATH$INPUTPATH\&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir $OUTPATH$INPUTPATH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;for fname in *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if [ -d &amp;quot;$fname&amp;quot; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if [ ! -d &amp;quot;$OUTPATH$INPUTPATH&#x2F;$fname&amp;quot; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo creating output folder \&amp;quot;$OUTPATH$INPUTPATH&#x2F;$fname\&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir &amp;quot;$OUTPATH$INPUTPATH&#x2F;$fname&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo searching for jpg files in \&amp;quot;$fname\&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &amp;quot;$fname&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;find . -maxdepth 1 -type f -name \*.JPG | xargs -iimgfile ~&#x2F;scripts&#x2F;frame_photo.sh &amp;quot;imgfile&amp;quot; &amp;quot;$OUTPATH$INPUTPATH&#x2F;$fname&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;frame_photo.sh&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;creates output folder(s)&lt;&#x2F;li&gt;
&lt;li&gt;copies original photo into output folder&lt;&#x2F;li&gt;
&lt;li&gt;uses exiftran to rotate the photo to the correct orientation&lt;&#x2F;li&gt;
&lt;li&gt;shrinks the photo to a maximum of 800x600, and fills any remaining space with a black background&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#arg 1 = photo file name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#arg 2 = where to put result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#resizes and pads suitable for a photo frame.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;INPUTFILE=$1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OUTPATH=$2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#pwd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo copying \&amp;quot;$INPUTFILE\&amp;quot; into \&amp;quot;$OUTPATH\&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cp &amp;quot;$INPUTFILE&amp;quot; &amp;quot;$OUTPATH&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &amp;quot;$OUTPATH&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#pwd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#echo processing \&amp;quot;$INPUTFILE\&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;exiftran -ai &amp;quot;$INPUTFILE&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;convert &amp;quot;$INPUTFILE&amp;quot; -resize &amp;#39;800x600&amp;gt;&amp;#39; -background black -gravity center -extent 800x600 &amp;quot;$INPUTFILE&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I timed the whole operation using the time command, and copied all output to a
log file as follows.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ time .&#x2F;frame.sh 2&amp;gt;&amp;amp;1 | tee frame.log&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The conversion of around 6000 photos took around one and a half hours.&lt;&#x2F;p&gt;
&lt;p&gt;The concept of redirection of stdout &amp;amp; stderr was neatly explained by the
article &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.linux.com&#x2F;articles&#x2F;113686&quot;&gt;CLI magic: need redirection?&lt;&#x2F;a&gt;,
so now I know that 2&amp;gt;&amp;amp;1 means redirect ouput number two into output number one,
in other words redirect stderr into stdout, which then alows you to pipe the
whole lot into something else like &quot;tee&quot; (No, not tea, though it may be
interesting redirecting my photos into my tea...)&lt;&#x2F;p&gt;
&lt;p&gt;Add a comment or drop me a line if you find it interesting or useful or if you
have any questions or criticisms.&lt;&#x2F;p&gt;
&lt;p&gt;Update: I&#x27;ve worked this script into a small python gui app, check it out at
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;photo-frame-prep&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;timabell&#x2F;photo-frame-prep&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Enabling TV-Out on Ubuntu Linux 7.10 on a Dell Inspiron 8500</title>
        <published>2007-12-09T01:41:00.001+00:00</published>
        <updated>2007-12-09T01:41:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/12/09/enabling-tv-out-on-ubuntu-linux-710-on/"/>
        <id>https://0x5.uk/2007/12/09/enabling-tv-out-on-ubuntu-linux-710-on/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/12/09/enabling-tv-out-on-ubuntu-linux-710-on/">&lt;p&gt;This weekend, I finally got the tv-out working under linux (Ubuntu 7.10 aka
gusty gibbon) on my laptop. Here&#x27;s what was involved, including some of the
(time consuming) red herrings involved in getting this set up.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;tim_abell&#x2F;2096850378&#x2F;&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;inspiron-tv-out.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve included the full &lt;code&gt;xorg.conf&lt;&#x2F;code&gt; files for normal display and tv output at
the end of this post.&lt;&#x2F;p&gt;
&lt;p&gt;I used the composite video output as that&#x27;s what I have cables for. I haven&#x27;t
ever tried the s-video output, and I haven&#x27;t tried the digital audio output
since I divorced microsoft windows and threw her things out into the rain a
couple of years ago.&lt;&#x2F;p&gt;
&lt;p&gt;The quality is pretty poor, but good enough. I think there&#x27;s a limit of 800x600
for the video out. I&#x27;m getting a fair amount of interference on both the video
and audio when the laptop is on mains and connected to my amplifier &#x2F; tv. I&#x27;m
not sure what the cause it but it&#x27;s not bad enough to be unusable.&lt;&#x2F;p&gt;
&lt;p&gt;I installed the nvidia proprietary (that&#x27;s a negative word in case you don&#x27;t
live in my world) drivers some time ago in order to get 3D acceleration, and I
think this is a prerequisite to running the tv-out.&lt;&#x2F;p&gt;
&lt;p&gt;In my intial investigation I came across
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sorgonet.com&#x2F;linux&#x2F;nvoption&#x2F;&quot;&gt;nvoption&lt;&#x2F;a&gt;, which in theory allows you
to turn on the tv-out on the nvidia cards. I did manage to compile and run it
after several hours of trial, error and finding build dependencies but when I
finally got it built and running I found that it would seg fault when I hit the
&quot;apply&quot; button, hurrah! In the process of playing with nvoption however, I
noticed the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sorgonet.com&#x2F;linux&#x2F;nv-online&#x2F;&quot;&gt;nv-online&lt;&#x2F;a&gt; page that
this person has very generously set up. Reading this it dawned on me that
nvoption purely modifies the &#x2F;etc&#x2F;X11&#x2F;xorg.conf file, and that I don&#x27;t actually
&lt;em&gt;need&lt;&#x2F;em&gt; the tool to get tv-out running. I had originally presumed (the brother
of all ...) that the nvoption tool did some magical proprietary prodding of the
graphics card directly. After a bit of searching to find out where the options
should go (the device section), I was then able to use the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sorgonet.com&#x2F;linux&#x2F;nv-online&#x2F;help.html&quot;&gt;documentation of
options&lt;&#x2F;a&gt; in the second frame
of the nv-online page to configure my own X. After a bit of experimenting with
different options and lots of restarting of the X server (ctrl+alt+backspace) I
was able to get the desired result of the display mirrored&#x2F;cloned on both the
lcd and the television.&lt;&#x2F;p&gt;
&lt;p&gt;I tried the nvidia-settings gui tool that comes with the proprietary drivers,
but it was no use for this task. This tool modifies the xorg.conf file. It did
help me recently with a normal dual screen setup (using a crt monitor plugged
into the vga port on the laptop), but it was no help for the tv-out, which was
not even mentioned in the interface.&lt;&#x2F;p&gt;
&lt;p&gt;There is a tool called displayconfig-gtk which is fairly new to Ubuntu that
allows you to save named display profiles for different configurations
(including dual screen, though it didn&#x27;t quite behave for me). It can be found
under System &amp;gt; Administration &amp;gt; Screens and Graphics. This stores an xorg.conf
file for each profile in &#x2F;var&#x2F;lib&#x2F;displayconfig-gtk&#x2F;locations&#x2F;, and an index
file in &#x2F;var&#x2F;lib&#x2F;displayconfig-gtk&#x2F;locations.conf. This is almost ideal, as I
have created a set of xorg.conf files for my various setups, however it doesn&#x27;t
seem to cope with applying these custom xorg files. Additionally nvidia seem to
have a weird way of setting the screen to run at its native resolution of
1920x1600, and this tool doesn&#x27;t cope with it. This was corrected by selecting
the right resolution under System &amp;gt; Preferences &amp;gt; Screen Resolution.&lt;&#x2F;p&gt;
&lt;p&gt;Sadly it looks like there are no tools for easy switching X configuration
files, so the process for now is involves manually copying the config files.
I&#x27;ve created multiple files in &#x2F;etc&#x2F;X11, one for each set up including
xorg.conf_lcd and xorg.conf_tv. The switching process is then something along
the lines of &quot;cd &#x2F;etc&#x2F;X11&#x2F;&quot;, &quot;sudo cp xorg.conf_tv xorg.conf&quot;,
ctrl+alt+backspace (restart x server).&lt;&#x2F;p&gt;
&lt;p&gt;If it&#x27;s any consolation I recall the process in windows involved starting from
scratch in a distinctly non-intuitive gui and trying to get a whole load of
settings just right, so being able to save the settings is a big step up. I
think it took similar amounts of time to get tv-out running under windoze. I
guess that&#x27;s the price we pay for allowing companies to deny us access to the
hardware specs so it can be integrated properly. I bought this laptop before I
knew how much control I was giving away, and I endeavour not to make such
mistakes these days.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;designed for windows xp&quot; sticker has been moved to the equally shiny
microwave oven which brings me a small piece of joy when I make porridge in the
morning.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;xorg-conf-for-just-the-laptop-screen&quot;&gt;xorg.conf for just the laptop screen&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# nvidia-settings: X configuration file generated by nvidia-settings&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# nvidia-settings: version 1.0 (buildmeister@builder3) Mon Apr 16 20:38:05 PDT 2007&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;ServerLayout&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Layout0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Screen 0 &amp;quot;Screen0&amp;quot; 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;InputDevice &amp;quot;Keyboard0&amp;quot; &amp;quot;CoreKeyboard&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;InputDevice &amp;quot;Mouse0&amp;quot; &amp;quot;CorePointer&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Inputdevice &amp;quot;Synaptics Touchpad&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Files&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RgbPath &amp;quot;&#x2F;usr&#x2F;X11R6&#x2F;lib&#x2F;X11&#x2F;rgb&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Module&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;dbe&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;extmod&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;type1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;freetype&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;glx&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;ServerFlags&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Xinerama&amp;quot; &amp;quot;0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;InputDevice&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# generated from default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Mouse0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Driver &amp;quot;mouse&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Protocol&amp;quot; &amp;quot;auto&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Device&amp;quot; &amp;quot;&#x2F;dev&#x2F;psaux&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Emulate3Buttons&amp;quot; &amp;quot;no&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;ZAxisMapping&amp;quot; &amp;quot;4 5&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;InputDevice&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Synaptics Touchpad&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Driver &amp;quot;synaptics&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;SendCoreEvents&amp;quot; &amp;quot;true&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Device&amp;quot; &amp;quot;&#x2F;dev&#x2F;psaux&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Protocol&amp;quot; &amp;quot;auto-dev&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;HorizScrollDelta&amp;quot; &amp;quot;0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;InputDevice&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# generated from default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Keyboard0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Driver &amp;quot;kbd&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Monitor&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# HorizSync source: edid, VertRefresh source: edid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Monitor0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VendorName &amp;quot;Unknown&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ModelName &amp;quot;Sharp&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;HorizSync 30.0 - 75.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VertRefresh 60.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;DPMS&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Device&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Videocard0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Driver &amp;quot;nvidia&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VendorName &amp;quot;NVIDIA Corporation&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BoardName &amp;quot;GeForce4 4200 Go&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Screen&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Screen0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Device &amp;quot;Videocard0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Monitor &amp;quot;Monitor0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DefaultDepth 24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;metamodes&amp;quot; &amp;quot;DFP: nvidia-auto-select +0+0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SubSection &amp;quot;Display&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Depth 24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Modes &amp;quot;1600x1200&amp;quot; &amp;quot;1280x1024&amp;quot; &amp;quot;1024x768&amp;quot; &amp;quot;800x600&amp;quot; &amp;quot;640x480&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSubSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;xorg-conf-for-running-the-tv-out-at-800x600-with-the-laptop-displaying-the-same&quot;&gt;xorg.conf for running the tv-out at 800x600, with the laptop displaying the same&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# nvidia-settings: X configuration file generated by nvidia-settings&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# nvidia-settings: version 1.0 (buildmeister@builder3) Mon Apr 16 20:38:05 PDT 2007&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;ServerLayout&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Layout0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Screen 0 &amp;quot;Screen0&amp;quot; 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;InputDevice &amp;quot;Keyboard0&amp;quot; &amp;quot;CoreKeyboard&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;InputDevice &amp;quot;Mouse0&amp;quot; &amp;quot;CorePointer&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Inputdevice &amp;quot;Synaptics Touchpad&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Files&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RgbPath &amp;quot;&#x2F;usr&#x2F;X11R6&#x2F;lib&#x2F;X11&#x2F;rgb&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Module&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;dbe&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;extmod&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;type1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;freetype&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Load &amp;quot;glx&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;ServerFlags&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Xinerama&amp;quot; &amp;quot;0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;InputDevice&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# generated from default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Mouse0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Driver &amp;quot;mouse&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Protocol&amp;quot; &amp;quot;auto&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Device&amp;quot; &amp;quot;&#x2F;dev&#x2F;psaux&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Emulate3Buttons&amp;quot; &amp;quot;no&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;ZAxisMapping&amp;quot; &amp;quot;4 5&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;InputDevice&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Synaptics Touchpad&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Driver &amp;quot;synaptics&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;SendCoreEvents&amp;quot; &amp;quot;true&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Device&amp;quot; &amp;quot;&#x2F;dev&#x2F;psaux&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;Protocol&amp;quot; &amp;quot;auto-dev&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;HorizScrollDelta&amp;quot; &amp;quot;0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;InputDevice&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# generated from default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Keyboard0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Driver &amp;quot;kbd&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Monitor&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# HorizSync source: edid, VertRefresh source: edid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Monitor0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VendorName &amp;quot;Unknown&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ModelName &amp;quot;Sharp&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;HorizSync 30.0 - 75.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VertRefresh 60.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;DPMS&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Device&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Videocard0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Driver &amp;quot;nvidia&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VendorName &amp;quot;NVIDIA Corporation&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BoardName &amp;quot;GeForce4 4200 Go&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;**Option &amp;quot;TwinView&amp;quot; &amp;quot;1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;TwinViewOrientation&amp;quot; &amp;quot;Clone&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;MetaModes&amp;quot; &amp;quot;800x600, 800x600;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;TVStandard&amp;quot; &amp;quot;PAL-I&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Option &amp;quot;ConnectedMonitor&amp;quot; &amp;quot;DFP,TV&amp;quot;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section &amp;quot;Screen&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Identifier &amp;quot;Screen0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Device &amp;quot;Videocard0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Monitor &amp;quot;Monitor0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DefaultDepth 24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#Option &amp;quot;metamodes&amp;quot; &amp;quot;DFP: nvidia-auto-select +0+0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SubSection &amp;quot;Display&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Depth 24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Modes &amp;quot;1600x1200&amp;quot; &amp;quot;1280x1024&amp;quot; &amp;quot;1024x768&amp;quot; &amp;quot;800x600&amp;quot; &amp;quot;640x480&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSubSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EndSection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Making money with free software</title>
        <published>2007-11-04T14:04:00+00:00</published>
        <updated>2007-11-04T14:04:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/11/04/making-money-with-free-software/"/>
        <id>https://0x5.uk/2007/11/04/making-money-with-free-software/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/11/04/making-money-with-free-software/">&lt;p&gt;Business model #1!&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Turning capital into code&quot;&lt;&#x2F;p&gt;
&lt;p&gt;I believe there is a viable business to be had running a software company in a novel fashion. Each project to create a new or improved piece of open source software would be funded by multiple contracts with businesses who have a need for the software. The software business would be run as a partnership ala &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;John_Lewis_Partnership&quot;&gt;John Lewis&lt;&#x2F;a&gt;, where the employees own the company.&lt;&#x2F;p&gt;
&lt;p&gt;You can stop reading now, that was it. Move a long, no more useful thoughts here.&lt;&#x2F;p&gt;
&lt;p&gt;Still here? Okay, if you insist I&#x27;ll explain myself. I didn&#x27;t have time to write you a short blog post, so I wrote you a long one.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m always interested in how business is done. And the more I see, the more I start to realize that business doesn&#x27;t have to involve exploiting people (wanna buy a ringtone?), it is in fact more usually an agreement where both parties benefit.&lt;&#x2F;p&gt;
&lt;p&gt;Sure I could make a motorcar myself, but by the time I&#x27;ve finished tightening all the bolts in the mechano set it will probably have cost me fifty grand to make and do naught to sixty in pieces. Much better to buy a production car for fifteen grand and be happy that the manufacturer, sales person, mechanics etc take a percentage of &lt;span style=&quot;font-style: italic;&quot;&gt;my&lt;&#x2F;span&gt; money as, shock horror (communists look away now) ... profit! Besides didn&#x27;t my money come from charging someone enough to make a profit anyway?...&lt;&#x2F;p&gt;
&lt;p&gt;So, having alluded to the fact that I live in a capitalist society, I shall tell you what this has to do with open source &#x2F; free software in my mind.&lt;&#x2F;p&gt;
&lt;p&gt;By trade and by choice I&#x27;m a software developer, turning my hand to whatever variant of software is needed at the time, and not afraid to set up systems and databases if the need arises.&lt;&#x2F;p&gt;
&lt;p&gt;I have for some time now been of the opinion that the open source method of development and distribution is superior to the proprietary (closed source) model, both as a user and as a developer. As a user, I find that community driven software generally does the things that are important well, and is significantly better supported due to the community that gathers around it. As a developer (though I have yet to run an open source project), I think that the direct, unfiltered feedback from users is better, the collaboration between developers is more effective, and there isn&#x27;t a pressure to deviate from the correct solution to a problem into making pretty things that don&#x27;t work. Having said all that, all software is written by humans, so some projects fair better than others. There are limited resources on both sides of the fence so each has its own areas of strength and weakness in terms of quality and completeness.&lt;&#x2F;p&gt;
&lt;p&gt;Okay, so I like open source software (OSS). So what?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;farm3.static.flickr.com&#x2F;2354&#x2F;1860676320_0f7da3bcfb_m.jpg&quot; alt=&quot;impressive old glass roof&quot; &#x2F;&gt;Well, you or I can make money with proprietary software by creating something desirable, then charging people for using it ala &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;articles&#x2F;CamelsandRubberDuckies.html&quot;&gt;Fog Creek&lt;&#x2F;a&gt;. Which fits nicely in the capitalist world, and you can run your business as anything from evil empire (mention no names) to tree hugging near-as-damn-it open source and still turn a healthy profit. But that&#x27;s never sat right with me because although I see the logic, you aren&#x27;t really charging for the work you do, you are charging for an artificial restriction on redistribution. In other words I get enough investment together (time or money) to create the software in the first place, and get paid nothing for it. Then I sell it with virtually no overhead and hope to make up my initial investment, followed by a healthy profit. You can then use the healthy profit to improve the software, fund new software or attempt crush&#x2F;buy the competition (maniacal laugh). Sure it works, but what if you could give your software away to the world once it has paid for itself? Wouldn&#x27;t that make the world a better place? Well, that probably depends if you are creating restrictive crapware, but either way the way the answer is likely to be &quot;Are you nuts?!! Throw away all that free profit?!&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;There is another business model around that is working very nicely for some people and companies. The &quot;you want it, you pay for creating it&quot; approach. This comes in two flavours. Very common is hiring a contractor &#x2F; employee to create exactly what you desire even if you have no idea how to create software. This can be used to give a business an edge over its competition, or even to allow it to do business at all. This is a very expensive way of creating software (for that company) but is sometimes the only way. Some open source companies are expert at negotiating contracts to create custom software for profit, that software may then join the world&#x27;s supply of open source software.&lt;&#x2F;p&gt;
&lt;p&gt;Both of the above models fund a fair amount of the open source software available today, but I would like to see more money going into the creation of open source software, as it directly enriches all the people on this planet (money being simply a representation of all available resources, and open source being one of those resources).&lt;&#x2F;p&gt;
&lt;p&gt;It strikes me that there is a gap in between the two methods of funding software outlined above. On the one hand you take a punt that lots of people need something, create it and charge for the result, and on the other hand you find one person &#x2F; company that needs something and charge them a handsome sum to create it (after which you can do as you please with the result, contract permitting). Given an imaginary need such as &quot;software for tracking individual lumps of coal&quot;, what if there are not enough companies who want to track their coal in detail to make it worth taking a punt and using the packaged software model, but equally no individual company can justify paying the extortionate rates us technical mumbo jumbo types charge for such things? Well it just won&#x27;t get created, and they&#x27;ll just have to carry on using illegal immigrants to write on their coal with chalk.&lt;&#x2F;p&gt;
&lt;p&gt;At risk of getting to the point, we might find with the coal tracking software scenario that if we were to divide the cost of creating a coal tracker system (CTS) by the number of companies in need of such a system, then it would be a viable project. So maybe we could approach all these companies with a proposal to create a CTS (we love acronyms in IT, we even pretend to know what they mean), and get an agreement that they will jointly fund it. Okay so some won&#x27;t go with it but the more that do the lower the cost per client.&lt;&#x2F;p&gt;
&lt;p&gt;What has this to do with open source? I figure that seeing as open source is a better development model anyway, it makes sense to run such a project as an open source project. This way, all clients get full control and visibility over the software they have paid for, and can benefit from others&#x27; additions. The world then becomes a slightly richer place for everyone (unless it&#x27;s crapware!). This plan has the added bonus that it panders to my highly unprofitable desire not to charge for things that don&#x27;t involve effort or materials.&lt;&#x2F;p&gt;
&lt;p&gt;There are many ways to approach getting contracts for such work (all of them hard no doubt). One could start with a single contract for the full price of the work, with the possibility of paying a lower price if more clients come on board. ie, contract one for 100% of the cost, but reduced to 60% if a second contract is found, with the second contract also paying 60%, giving a 120% income, continuing on this theme as more clients are found. Going for slightly higher than an equal division of costs gives an incentive to find more contracts and reduce the price for the original client. It might prove easier to start with say four contracts that state work and billing are dependent on finding four clients. I don&#x27;t imagine for a minute this would be easy to swing, even with some of the more open minded companies out there, but I reckon all the worthwhile things in life require some effort (like flying &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.buzzflyer.co.uk&#x2F;Sub-Micro-RC-Helicopters&#x2F;Walkera-5-6-Genius&#x2F;p-97-523&#x2F;&quot;&gt;helicopters&lt;&#x2F;a&gt; of any size, for example). Perhaps with the right marketing spin it could happen, and the once it is proved to work, it might get easier to win the next contract.&lt;&#x2F;p&gt;
&lt;p&gt;So if this is a successful business in the waiting, why would you want run the business as a partnership and share all that juicy profit with mere employees?! Well the inspiration for this one comes from my favourite software business writer Joel Spolsky and his explanation in his article &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;articles&#x2F;fog0000000074.html&quot;&gt;&quot;Converting Capital Into Software That Works&quot;&lt;&#x2F;a&gt; that software companies&#x27; most valuable assets are the programmers. The long and short is that if programmers have financial buy in to the company they will care about the company, and if you are successful then the programmers will stick with you for the money. In fact I would go as far as taking the mission statement for such a business straight from the article, &quot;turning capital into code&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;I have one last point to cover before you turn off your set, tuck the cat up in bed, post to twitter what it just did and turn out the lights.&lt;&#x2F;p&gt;
&lt;p&gt;If this is such a killer business model, why on earth would I post the intellectual property (don&#x27;t use this term, or &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fsf.org&#x2F;licensing&#x2F;essays&#x2F;not-ipr.xhtml&quot;&gt;the FSF will get you&lt;&#x2F;a&gt;), er I mean information for some smart banana to beat me to it? Simple. Successful business is one percent inspiration, ninety-nine percent perspiration, and it is the successful execution of an idea that makes or breaks a business, much more so than the original idea. In fact I&#x27;m sure many businesses start with one idea, then discover the harsh realities of commerce and up doing something else anyway. And if someone does beat me to it, it will make the software world a richer place, so I in say earnest good luck to you.&lt;&#x2F;p&gt;
&lt;p&gt;The other side to releasing such information, is that I&#x27;ve seen what a positive effect openness has on the business of writing software, and I can see the potential positive effects for business run in an equally open fashion. Sure there are a few downsides, such as visibility for the competition, but I think as a rule they are massively overstated, and completely outweighed by the buy in and good will that you could gain from customers and potential customers from being completely open with them.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d love to hear of any ventures in this field, and any feedback, constructive or destructive is always welcome.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks as always for your time. All the best from your host Tim Abell.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>xsession sold out</title>
        <published>2007-11-04T13:59:00+00:00</published>
        <updated>2007-11-04T13:59:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/11/04/xsession-sold-out/"/>
        <id>https://0x5.uk/2007/11/04/xsession-sold-out/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/11/04/xsession-sold-out/">&lt;p&gt;My web host &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;xsession.com&#x2F;&quot;&gt;xsession&lt;&#x2F;a&gt; has been bought by &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.names.co.uk&#x2F;&quot;&gt;namesco&lt;&#x2F;a&gt;, and promptly put domain renewal prices up from £8 to £17. Time for a new web host.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OSS Contribution Number One!</title>
        <published>2007-10-27T17:37:00+00:00</published>
        <updated>2007-10-27T17:37:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/10/27/oss-contribution-number-one/"/>
        <id>https://0x5.uk/2007/10/27/oss-contribution-number-one/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/10/27/oss-contribution-number-one/">&lt;p&gt;I&#x27;ve had my first ever patch to an open source project accepted! Yay! (Fanfare please... no? anyone? oh well.)&lt;&#x2F;p&gt;
&lt;p&gt;Ok it&#x27;s a one word change to a piece of documentation, but hey it&#x27;s still something.&lt;&#x2F;p&gt;
&lt;p&gt;The project is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.gnucash.org&#x2F;&quot;&gt;gnucash&lt;&#x2F;a&gt;. For details take a look at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;bugzilla.gnome.org&#x2F;show_bug.cgi?id=490699&quot;&gt;the bug report&lt;&#x2F;a&gt; I created to hold the patch. I even got a thanks :-).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creating a blogroll</title>
        <published>2007-09-03T20:13:00.001+00:00</published>
        <updated>2007-09-03T20:13:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/09/03/creating-blogroll/"/>
        <id>https://0x5.uk/2007/09/03/creating-blogroll/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/09/03/creating-blogroll/">&lt;p&gt;Update 11th Sep 2007:&lt;br &#x2F;&gt;
xsession responded to my support request, and the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;blogroll.opml&quot;&gt;opml&lt;&#x2F;a&gt; file is now served, complete with the correct mime type.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Update 26th Dec 2009&lt;br &#x2F;&gt;
Now on a linux host so no mime type issues now.&lt;&#x2F;p&gt;
&lt;p&gt;Podcast list added: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;podcasts.opml&quot;&gt;podcasts.opml&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now styled with custom xslt file &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;opml.xsl&quot;&gt;opml.xsl&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;As people may want to see my rss and podcast subscriptions, I have created a blogroll for you.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve started with an &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;OPML&quot;&gt;OPML&lt;&#x2F;a&gt; file, created by hand and uploaded to my web host. Unfortunately my web host won&#x27;t (currently) serve the &quot;.opml&quot; file extension so I&#x27;ve had to use .txt.&lt;&#x2F;p&gt;
&lt;p&gt;so &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;blogroll.opml&quot;&gt;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;blogroll.opml&lt;&#x2F;a&gt; became &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;blogroll.opml.txt&quot;&gt;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;blogroll.opml.txt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I then validated the file with &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;validator.opml.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;validator.opml.org&#x2F;&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
I then added my feed to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;share.opml.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;share.opml.org&#x2F;&lt;&#x2F;a&gt; so you can now see the list at &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;share.opml.org&#x2F;viewsharedfeeds&#x2F;?user_id=7189&quot;&gt;http:&#x2F;&#x2F;share.opml.org&#x2F;viewsharedfeeds&#x2F;?user_id=7189&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
In the opml I&#x27;ve separated podcasts and news feeds, but share.opml doesn&#x27;t use this info.&lt;&#x2F;p&gt;
&lt;p&gt;There is some &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.isolani.co.uk&#x2F;blog&#x2F;semanticweb&#x2F;OpmlTheXmlFormatWithNoFriends&quot;&gt;controversy&lt;&#x2F;a&gt; over opml, but hell, it does the job. We can all upgrade when a better alternative goes mainstream.&lt;&#x2F;p&gt;
&lt;p&gt;Useful references:&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.kbcafe.com&#x2F;rss&#x2F;?guid=20051003145153&quot;&gt;http:&#x2F;&#x2F;www.kbcafe.com&#x2F;rss&#x2F;?guid=20051003145153&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.rss-tools.com&#x2F;opml-generators.htm&quot;&gt;http:&#x2F;&#x2F;www.rss-tools.com&#x2F;opml-generators.htm&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bioneural.net&#x2F;2005&#x2F;10&#x2F;09&#x2F;iblog-opml-bloglines-reading-list&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.bioneural.net&#x2F;2005&#x2F;10&#x2F;09&#x2F;iblog-opml-bloglines-reading-list&#x2F;&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;nayyeri.net&#x2F;archive&#x2F;2007&#x2F;02&#x2F;17&#x2F;create-a-blogroll-from-opml-files.aspx&quot;&gt;http:&#x2F;&#x2F;nayyeri.net&#x2F;archive&#x2F;2007&#x2F;02&#x2F;17&#x2F;create-a-blogroll-from-opml-files.aspx&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Taking a Microsoft Learning course - my experience so far</title>
        <published>2007-08-16T21:20:00+00:00</published>
        <updated>2007-08-16T21:20:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/08/16/taking-microsoft-learning-course-my/"/>
        <id>https://0x5.uk/2007/08/16/taking-microsoft-learning-course-my/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/08/16/taking-microsoft-learning-course-my/">&lt;p&gt;I am currently studying for a Microsoft ASP.NET qualification&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.microsoft.com&#x2F;learning&#x2F;mcp&#x2F;mcts&#x2F;webapps&#x2F;default.mspx&quot;&gt;MCTS: .NET Framework 2.0 Web Applications&lt;&#x2F;a&gt;.&lt;br &#x2F;&gt;
I have paid for and begun one of the Microsoft Learning training courses:&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microsoftelearning.com&#x2F;eLearning&#x2F;offerDetail.aspx?offerPriceId=127339&quot;&gt;Collection 5160: Core Development with the Microsoft® .NET Framework 2.0 Foundation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here are my first impressions. I have posted most of this content on the private boards of the course provider.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been pretty pleased with the course so far. The coverage of the material seems good, and I have already learnt quite a few extra things even though I have been using ASP.NET in earnest for a couple of years commercially. The mix of presentation of content works well for me, with the video presentations, factual content, puzzles, quizzes and final lab sessions combining well to reinforce the new material.&lt;&#x2F;p&gt;
&lt;p&gt;The ability to use a virtual machine at the end of each module, loaded with Visual Studio 2005 is essential for those without a copy, handy for those of us who are no longer trapped in Bill&#x27;s world and a neat trick even if you do have an msdn subscription.&lt;&#x2F;p&gt;
&lt;p&gt;Most of my feedback is minor annoyances. In my experience any form of education is often imperfect, and this would appear to be on the good side of such things, though it remains to be seen if it gets me through the exams!&lt;&#x2F;p&gt;
&lt;p&gt;My comments:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Firefox support could be improved (except for activex stuff of course). I couldn&#x27;t get into the course at all in firefox. (I don&#x27;t atually run windows at all at home, so had to fire up a vm just to get in, even though most of the content is no more than html, css &amp;amp; flash).&lt;&#x2F;li&gt;
&lt;li&gt;Page width and font size seem to be linked, so if I increases the text size I have to scroll side to side, which is a PITA, as i run a super hi res screen so default text is tiny. Particularly noticeable on the lab exercise pages.&lt;&#x2F;li&gt;
&lt;li&gt;Providing a zip of the starter and solution files would be much better for those of us who have visual studio installed locally.&lt;&#x2F;li&gt;
&lt;li&gt;As someone else said, why do you have to log in to the lab machines? It&#x27;s trivial to get windows to automatically log a user in.&lt;&#x2F;li&gt;
&lt;li&gt;I had a connection drop on me (while reading up), it would have been good to be able to reconnect to same session.&lt;&#x2F;li&gt;
&lt;li&gt;It would be good to see the remaining lab time in the same window as the rdp activex control.&lt;&#x2F;li&gt;
&lt;li&gt;The keyboard in the VM is set to US, which is a PITA as I have a UK keyboard, so &quot; comes out as @.&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s not clear if the forum emails you if someone replies. I&#x27;m not likely to monitor it, but the answers I get will affect my decision to buy the rest of the courses I&#x27;m planning on doing.&lt;&#x2F;li&gt;
&lt;li&gt;The forums seem to be lacking in input from course staff in helping struggling (paying) students, and in providing technical support.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Blocking web adverts</title>
        <published>2007-07-02T21:23:00+00:00</published>
        <updated>2007-07-02T21:23:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/07/02/blocking-web-adverts/"/>
        <id>https://0x5.uk/2007/07/02/blocking-web-adverts/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/07/02/blocking-web-adverts/">&lt;p&gt;A friend asked me to write this up.&lt;&#x2F;p&gt;
&lt;p&gt;To remove all those annoying adverts from the web as you see it:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;install &amp;amp; use &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.mozilla-europe.org&#x2F;en&#x2F;products&#x2F;firefox&#x2F;&quot;&gt;firefox&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;install &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;addons.mozilla.org&#x2F;en-US&#x2F;firefox&#x2F;addon&#x2F;1865&quot;&gt;adblock plus&lt;&#x2F;a&gt; add-in&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;install &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;addons.mozilla.org&#x2F;en-US&#x2F;firefox&#x2F;addon&#x2F;1136&quot;&gt;fliterset-g updater&lt;&#x2F;a&gt; add in&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Job done. Thanks for listening.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Ubuntu screen locking</title>
        <published>2007-07-02T21:15:00+00:00</published>
        <updated>2007-07-02T21:15:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/07/02/ubuntu-screen-locking/"/>
        <id>https://0x5.uk/2007/07/02/ubuntu-screen-locking/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/07/02/ubuntu-screen-locking/">&lt;p&gt;Howto prevent ubuntu locking the screen when closing the laptop lid.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to jrib in irc:&#x2F;&#x2F;freenode.net&#x2F;#ubuntu for this one.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Run gconf-editor (with alt+F2)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Go to or search for &#x2F;desktop&#x2F;gnome&#x2F;lockdown&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Tick disable_lock_screen&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Restart gnome (ctrl+alt+backspace - after saving your documents it&#x27;s a bit brutal!)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>backing up your home folder</title>
        <published>2007-06-20T20:59:00+00:00</published>
        <updated>2007-06-20T20:59:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/06/20/backing-up-your-home-folder/"/>
        <id>https://0x5.uk/2007/06/20/backing-up-your-home-folder/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/06/20/backing-up-your-home-folder/">&lt;p&gt;Here I outline the solution I chose for backing up my life, er... I mean home folder. (I&#x27;m sure there&#x27;s life outside &#x2F;home&#x2F;tim somewhere...)&lt;&#x2F;p&gt;
&lt;p&gt;My requirements were:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;backup to dvd+rw&lt;&#x2F;li&gt;
&lt;li&gt;&amp;gt;20GB of data to back up&lt;&#x2F;li&gt;
&lt;li&gt;no obscure formats (in case I don&#x27;t have the backup tool when I need to restore)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I looked at several solutions for backups but ended up writing scripts to meet my needs.&lt;&#x2F;p&gt;
&lt;p&gt;The main script creates a tar file of my home directory, excluding certain items, which is then split into files suitable for writing to dvd+rw discs, with tar based verification, md5sums and file list text files created at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;The reason for splitting to 3 files per disc is that the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ISO_9660#The_2_GiB_.28or_4.2GB_depending_on_implementation.29_file_size_limit&quot;&gt;iso 9660&lt;&#x2F;a&gt; spec has a 2GB file size limit, and it&#x27;s important that the discs are as simple as possible (ie no UDF) to aid recovery in awkward situations. This is also why I avoided compression.&lt;&#x2F;p&gt;
&lt;p&gt;backup_home.sh&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash -v  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#DVD+R SL capacity 4,700,372,992 bytes DVD, (see [wikipedia on DVD](http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;DVD))  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#ISO max file size 2GB. 4.38GB&#x2F;3 = 1,566,790,997bytes = 1,494MB  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#1,490MB to leave some space for listings and checksums  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tar -cvv --directory &#x2F;home tim --exclude-from backup_home_exclude.txt | split -b 1490m - &#x2F;var&#x2F;backups&#x2F;tim&#x2F;home&#x2F;home.tar.split.  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &#x2F;var&#x2F;backups&#x2F;tim&#x2F;home  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;md5sum home.tar.split.* &amp;gt; home.md5  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cat home.tar.split.* | tar -t &amp;gt; home_file_list.txt  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cat home.tar.split.* | tar -d --directory &#x2F;home tim &amp;gt; home_diff.txt  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ls -l home.* &amp;gt; home_backup_files.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;backup_home_exclude.txt&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim&#x2F;work*  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim&#x2F;.Trash*  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim&#x2F;.thumbnails*  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This leaves me with a big pile of split files (named .aa, .ab etc) and a few text files. I proceeded to write 3 split files per disc, and put the 4 text files on every disc for convenience. I used gnome&#x27;s built in DVD writing to create the discs.&lt;&#x2F;p&gt;
&lt;p&gt;I also wanted to verify the md5 checksums as the discs were created, so I wrote another little script to make life easier. This ensures the newley written disc has been remounted properly, and runs the md5 check. So long as the 3 relevant checksums came out correctly on each disc I can be reasonably confident of recovering the data should I need it.&lt;br &#x2F;&gt;
&quot;eject -t&quot; closes the cdrom, which is handy.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;reload_and_verify.sh  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash -v  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &#x2F;media  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eject  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eject -t  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mount &#x2F;media&#x2F;cdrom  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd cdrom  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;md5sum -c home.md5  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd &#x2F;media  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eject  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In addition to the above mechanism (which is a pain at best, mostly due to media limitations) I keep my machines in sync with &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cis.upenn.edu&#x2F;~bcpierce&#x2F;unison&#x2F;&quot;&gt;unison&lt;&#x2F;a&gt; which I strongly recommend for both technical and non-technical users. I gather it also runs on microsoft (who?), so you might find it useful if you are mid transition.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My mum and her super ceramics</title>
        <published>2007-05-28T02:18:00.001+00:00</published>
        <updated>2007-05-28T02:18:00.001+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/05/28/my-mum-and-her-super-ceramics/"/>
        <id>https://0x5.uk/2007/05/28/my-mum-and-her-super-ceramics/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/05/28/my-mum-and-her-super-ceramics/">&lt;p&gt;My mum has started posting &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;sarah_abell&#x2F;&quot;&gt;pics of her fab ceramics work on
flickr&lt;&#x2F;a&gt;. Go mum!&lt;&#x2F;p&gt;
&lt;p&gt;One of her early pieces has pride of place in my display cabinet and is admired
by all. Watch this space for more funky designs as she heads towards the end of
uni.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Get emailed Tim&#x27;s blog and photos</title>
        <published>2007-05-27T17:35:00+00:00</published>
        <updated>2007-05-27T17:35:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/05/27/get-emailed-tims-blog-and-photos/"/>
        <id>https://0x5.uk/2007/05/27/get-emailed-tims-blog-and-photos/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/05/27/get-emailed-tims-blog-and-photos/">&lt;p&gt;Can&#x27;t be bothered to check here and see if I&#x27;ve written anything this month? Great news! You can now have my blog entries and latest flickr photos sent to you by email thanks to the feedblitz service.&lt;&#x2F;p&gt;
&lt;p&gt;You can subscribe to my blog using the email box on the bottom of the right hand menu, or by clicking &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.feedblitz.com&#x2F;f&#x2F;?Sub=216154&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can subscribe to my flickr photo feed &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.feedblitz.com&#x2F;f&#x2F;?Sub=216268&quot;&gt;here&lt;&#x2F;a&gt; (public photos only - you have to be my flickr contact to see photos of friends I post).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>starfighter</title>
        <published>2007-05-27T13:44:00+00:00</published>
        <updated>2007-05-27T13:44:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/05/27/starfighter/"/>
        <id>https://0x5.uk/2007/05/27/starfighter/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/05/27/starfighter/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;starfighter.nongnu.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;starfighter.nongnu.org&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;starfighter.nongnu.org&#x2F;images&#x2F;screenshot2.png&quot; alt=&quot;starfighter screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Whilst looking for backup packages on ubuntu via synaptic by searching for the word &quot;tar&quot;, I stumbled across the package &quot;starfighter&quot;. So I installed it. Then ran it. And played it. It&#x27;s rather good fun. Ctrl to fire lasers, space to fire rockets, cursors to get around. Spend your time chasing enemy ships around the screen, and collecting bonuses &#x2F; money. Has a decent sound track too.&lt;&#x2F;p&gt;
&lt;p&gt;Highly recommended. I love the open source world.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ apt-cache show starfighter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Package: starfighter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Priority: optional&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Section: universe&#x2F;games&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Installed-Size: 368&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Maintainer: Debian Games Team &amp;lt;pkg-games-devel@lists.alioth.debian.org&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Architecture: i386&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Version: 1.1-6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Depends: libc6 (&amp;gt;= 2.4-1), libgcc1 (&amp;gt;= 1:4.1.0), libsdl-image1.2 (&amp;gt;= 1.2.3), lib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sdl-mixer1.2 (&amp;gt;= 1.2.6), libsdl1.2debian (&amp;gt;&amp;gt; 1.2.7+1.2.8), libstdc++6 (&amp;gt;= 4.1.0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;, starfighter-data (= 1.1-6)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filename: pool&#x2F;universe&#x2F;s&#x2F;starfighter&#x2F;starfighter_1.1-6_i386.deb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Size: 116320&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MD5sum: 959f894e78517a3411c3c2656d61b85c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHA1: ac7e2f458d4bd8c57056e11bb3da8609f35b528c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHA256: 29c9adee1ee2fb52f1d790254683579e919655ad01bb806a02a59d32abcb8d58&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Description: 2D scrolling shooter game&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; After decades of war one company, who had gained powerful supplying both&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; sides with weaponary, steps forwards and crushes both warring factions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; in one swift movement. Using far superior weaponary and AI craft, the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; company was completely unstoppable and now no one can stand in their&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; way. Thousands began to perish under the iron fist of the company. The&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; people cried out for a saviour, for someone to light this dark hour...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; and someone did.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Features of the game:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  o 26 missions over 4 star systems&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  o Primary and Secondary Weapons (including a laser cannon and a charge weapon)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  o A weapon powerup system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  o Wingmates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  o Missions with Primary and Secondary Objectives&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  o A Variety of Missions (Protect, Destroy, etc)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  o 13 different music tracks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  o Boss battles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Homepage: &amp;lt;http:&#x2F;&#x2F;www.parallelrealities.co.uk&#x2F;starfighter.php&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Bugs: mailto:ubuntu-users@lists.ubuntu.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Origin: Ubuntu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>running partimage in batch mode</title>
        <published>2007-04-10T22:01:00+00:00</published>
        <updated>2007-04-10T22:01:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/04/10/running-partimage-in-batch-mode/"/>
        <id>https://0x5.uk/2007/04/10/running-partimage-in-batch-mode/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/04/10/running-partimage-in-batch-mode/">&lt;p&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;A continuation of the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.partimage.org&#x2F;&quot;&gt;partimage&lt;&#x2F;a&gt; project.&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As it would appear that stdout support doesn&#x27;t work due the user interface
making use of stdout, I have been figuring out how to make the program run in
batch mode, with a little help from KDevelop.&lt;&#x2F;p&gt;
&lt;p&gt;My continued findings:&lt;&#x2F;p&gt;
&lt;p&gt;The help presents a fully batch mode, -B&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ .&#x2F;partimage --help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;===============================================================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Partition Image (http:&#x2F;&#x2F;www.partimage.org&#x2F;) version 0.6.5_beta4 [stable]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---- distributed under the GPL 2 license (GNU General Public License) ----&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Supported file systems:....Ext2&#x2F;3, Reiser3, FAT16&#x2F;32, HPFS, JFS, XFS,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                           UFS(beta), HFS(beta), NTFS(experimental)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;usage: partimage [options] &amp;lt;action&amp;gt; &amp;lt;device&amp;gt; &amp;lt;image_file&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       partimage &amp;lt;imginfo&#x2F;restmbr&amp;gt; &amp;lt;image_file&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ex: partimage -z1 -o -d save &#x2F;dev&#x2F;hda12 &#x2F;mnt&#x2F;backup&#x2F;redhat-6.2.partimg.gz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ex: partimage restore &#x2F;dev&#x2F;hda13 &#x2F;mnt&#x2F;backup&#x2F;suse-6.4.partimg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ex: partimage restmbr &#x2F;mnt&#x2F;backup&#x2F;debian-potato-2.2.partimg.bz2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ex: partimage -z1 -om save &#x2F;dev&#x2F;hda9 &#x2F;mnt&#x2F;backup&#x2F;win95-osr2.partimg.gz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ex: partimage imginfo &#x2F;mnt&#x2F;backup&#x2F;debian-potato-2.2.partimg.bz2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ex: partimage -a&#x2F;dev&#x2F;hda6#&#x2F;mnt&#x2F;partimg#vfat -V 700 save &#x2F;dev&#x2F;hda12 &#x2F;mnt&#x2F;partimg&#x2F;redhat-6.2.partimg.gz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Arguments:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* &amp;lt;action&amp;gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - save: save the partition datas in an image file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - restore: restore the partition from an image file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - restmbr: restore a MBR of the image file to an hard disk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - imginfo: show informations about the image file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* &amp;lt;device&amp;gt;: partition to save&#x2F;restore (example: &#x2F;dev&#x2F;hda1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* &amp;lt;image_file&amp;gt;: file where data will be read&#x2F;written. Can be very big.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                For restore, &amp;lt;image_file&amp;gt; can have the value &amp;#39;stdin&amp;#39;. This allows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                for providing image files through a pipe.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Options:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -z,  --compress      (image file compression level):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -z0, --compress=0    don&amp;#39;t compress: very fast but very big image file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -z1, --compress=1    compress using gzip: fast and small image file (default)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -z2, --compress=2    (compress using bzip2: very slow and very small image file):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -c,  --nocheck       don&amp;#39;t check the partition before saving&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -o,  --overwrite     overwrite the existing image file without confirmation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -d,  --nodesc        don&amp;#39;t ask any description for the image file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -V,  --volume        (split image into multiple volumes files)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -VX, --volume=X      create volumes with a size of X MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -w,  --waitvol       wait for a confirmation after each volume change&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -e,  --erase         erase empty blocks on restore with zero bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -m,  --allowmnt      don&amp;#39;t fail if the partition is mounted. Dangerous !&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -M,  --nombr         don&amp;#39;t create a backup of the MBR (Mast Boot Record) in the image file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -h,  --help          show help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -v,  --version       show version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -i,  --compilinfo    show compilation options used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -f,  --finish        (action to do if finished successfully):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -f0, --finish=0      wait: don&amp;#39;t make anything&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -f1, --finish=1      halt (power off) the computer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -f2, --finish=2      reboot (restart the computer):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -f3, --finish=3      quit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -b,  --batch         batch mode: the GUI won&amp;#39;t wait for an user action&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -BX, --fully-batch=X batch mode without GUI, X is a challenge response string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -y,  --nosync        don&amp;#39;t synchronize the disks at the end of the operation (dangerous)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -sX, --server=X      give partimaged server&amp;#39;s ip address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -pX, --port=X        give partimaged server&amp;#39;s listening port&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -g,  --debug=X       set the debug level to X (default: 1):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -n,  --nossl         disable SSL in network mode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -S,  --simulate      simulation of restoration mode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -aX, --automnt=X     automatic mount with X options. Read the doc for more details&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -UX  --username=X    username to authenticate to server&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* -PX  --password=X    password for authentication of user to server&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;===============================================================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is not immediately obvious what &quot;X is a challenge response string&quot; means.
I was able to get the program to run to a limited extend after a bit of searching the internet and trial and error with the option &quot;-B x=y&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Having stepped through the program, it transpires that where I have put &quot;x&quot;, the program expects a pattern to match with the title and content of any messages that would otherwise have been shown to the user, and &quot;y&quot; is the pre-programmed response. This is in the &quot;interface_none&quot; section.
&quot;x&quot; has to match the question in the form &quot;message title&#x2F;message content&quot; and is compared using fnmatch which allows * as a wildcard (anyone got a good reference for fnmatch?).
If the program hits a question for the user, and cannot find a matching answer in the command arguments, &quot;CInterfaceNone::invalid_programmed_response()&quot; fires &quot;exit(8)&quot; and the program dies.&lt;&#x2F;p&gt;
&lt;p&gt;So far I have been running the program as a normal user, which will inevitably fail where it attempts to work with block devices &#x2F; root owned files &amp;amp; folders. This produces a warning in the user interface, followed by program termination.&lt;&#x2F;p&gt;
&lt;p&gt;To bypass this first &quot;not root&quot; warning, I successfully used this pre-programmed answer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;partimage -B Warning*=Continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Alternatively the following is more specific and also works:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;partimage -B Warning*root*=continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I haven&#x27;t figured out how to pass more than one predefined answer in batch mode.&lt;&#x2F;p&gt;
&lt;p&gt;The run arguments can be set in KDevelop here:
project &amp;gt; options &amp;gt; debugger &amp;gt; program arguments&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Side note:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The program has a base class of user interface defined, and then either instantiates interface_none or interface_newt depending on command line arguments.&lt;&#x2F;p&gt;
&lt;p&gt;If not using full batch mode it helps to set &quot;enable separate terminal for application IO&quot; in KDevelop (project &amp;gt; options &amp;gt; debugger) so that you can see the full user interface. However if the program exits then the console closes and any output is lost.&lt;&#x2F;p&gt;
&lt;p&gt;As part of stepping through the code, I came across a macro, which makes the program harder to follow while debugging due to not being able to step through. So I figured out what it did, and wrote out its output C++ code in full:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;partimage.svn.sourceforge.net&#x2F;viewvc&#x2F;partimage&#x2F;trunk&#x2F;partimage&#x2F;src&#x2F;client&#x2F;interface_none.cpp?revision=1&amp;amp;view=markup&amp;amp;pathrev=20#l_103&quot;&gt;interface_none.cpp, line 103&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#define MB_2(One,Other,ONE,OTHER)       \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;int CInterfaceNone::msgBox##One##Other(char *title, char *text, ...) {  \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;char *result= lookup(title,text,&amp;quot;(unspecified)&amp;quot;);     \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;va_list al;          \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;va_start(al,text);         \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;message_only(#One &amp;quot;&#x2F;&amp;quot; #Other, title, text, al, result);    \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;va_end(al);          \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if (!strcasecmp(result,#One)) return MSGBOX_##ONE;     \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if (!strcasecmp(result,#Other)) return MSGBOX_##OTHER;    \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;invalid_programmed_response();       \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return 0;                                                             \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MB_2(Continue,Cancel,CONTINUE,CANCEL)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MB_2(Yes,No,YES,NO)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;my expanded version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;notes: have expanded out macro so I can step through it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;int CInterfaceNone::msgBoxContinueCancel(char *title, char *text, ...) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; char *result= lookup(title,text,&amp;quot;(unspecified)&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; va_list al;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; va_start(al,text);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; message_only(&amp;quot;Continue&amp;quot; &amp;quot;&#x2F;&amp;quot; &amp;quot;Cancel&amp;quot;, title, text, al, result);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; va_end(al);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; if (!strcasecmp(result,&amp;quot;Continue&amp;quot;)) return MSGBOX_CONTINUE;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; if (!strcasecmp(result,&amp;quot;Cancel&amp;quot;)) return MSGBOX_CANCEL;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; invalid_programmed_response();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return 0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;int CInterfaceNone::msgBoxYesNo(char *title, char *text, ...) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; char *result= lookup(title,text,&amp;quot;(unspecified)&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; va_list al;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; va_start(al,text);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; message_only(&amp;quot;Yes&amp;quot; &amp;quot;&#x2F;&amp;quot; &amp;quot;No&amp;quot;, title, text, al, result);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; va_end(al);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; if (!strcasecmp(result,&amp;quot;Yes&amp;quot;)) return MSGBOX_YES;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; if (!strcasecmp(result,&amp;quot;No&amp;quot;)) return MSGBOX_NO;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; invalid_programmed_response();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; return 0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;creating a ramdisk for testing.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.vanemery.com&#x2F;Linux&#x2F;Ramdisk&#x2F;ramdisk.html&quot;&gt;http:&#x2F;&#x2F;www.vanemery.com&#x2F;Linux&#x2F;Ramdisk&#x2F;ramdisk.html&lt;&#x2F;a&gt;
(I am on ubuntu 6.10 here, details may vary)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ls -l &#x2F;dev&#x2F;ram*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  0 2007-04-08 20:10 &#x2F;dev&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  1 2007-04-08 20:10 &#x2F;dev&#x2F;ram1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1, 10 2007-04-08 20:10 &#x2F;dev&#x2F;ram10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1, 11 2007-04-08 20:10 &#x2F;dev&#x2F;ram11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1, 12 2007-04-08 20:10 &#x2F;dev&#x2F;ram12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1, 13 2007-04-08 20:10 &#x2F;dev&#x2F;ram13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1, 14 2007-04-08 20:10 &#x2F;dev&#x2F;ram14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1, 15 2007-04-08 20:10 &#x2F;dev&#x2F;ram15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  2 2007-04-08 20:10 &#x2F;dev&#x2F;ram2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  3 2007-04-08 20:10 &#x2F;dev&#x2F;ram3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  4 2007-04-08 20:10 &#x2F;dev&#x2F;ram4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  5 2007-04-08 20:10 &#x2F;dev&#x2F;ram5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  6 2007-04-08 20:10 &#x2F;dev&#x2F;ram6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  7 2007-04-08 20:10 &#x2F;dev&#x2F;ram7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  8 2007-04-08 20:10 &#x2F;dev&#x2F;ram8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brw-rw---- 1 root disk 1,  9 2007-04-08 20:10 &#x2F;dev&#x2F;ram9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;create and mount test ramdisk&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mke2fs &#x2F;dev&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mkdir &#x2F;media&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mount &#x2F;dev&#x2F;ram0 &#x2F;media&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;add a test file and unmount the disk&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# echo &amp;quot;test data #1.&amp;quot; &amp;gt;&amp;gt; &#x2F;media&#x2F;ram0&#x2F;foo.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# umount &#x2F;media&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;the above, as a script:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# create and mount test ramdisk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mke2fs &#x2F;dev&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if [ ! -d &#x2F;media&#x2F;ram0 ]; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mkdir &#x2F;media&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mount &#x2F;dev&#x2F;ram0 &#x2F;media&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#add a test file and unmount the disk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;test file.&amp;quot; &amp;gt;&amp;gt; &#x2F;media&#x2F;ram0&#x2F;foo.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;date &amp;gt;&amp;gt; &#x2F;media&#x2F;ram0&#x2F;foo.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cat &#x2F;media&#x2F;ram0&#x2F;foo.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;umount &#x2F;media&#x2F;ram0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Create &amp;amp; run script (as root, because it (un)mounts a file system, and creates a dir in a root owned folder):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ gedit mkram.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ chmod ug+x mkram.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo .&#x2F;mkram.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wierdly, partimage won&#x27;t run in full batch mode without a second part to the -B switch, even if it&#x27;s set up to not need to ask any questions. Supplying a dummy &quot;x=y&quot; seems sufficient to fool it.&lt;&#x2F;p&gt;
&lt;p&gt;Runing as root without asking for partition description works:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo .&#x2F;partimage -d -B x=y save &#x2F;dev&#x2F;ram0 ram0.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Restore image to a different ramdisk and check file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo .&#x2F;partimage -B x=y restore &#x2F;dev&#x2F;ram1 ram0.img.000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo mount &#x2F;dev&#x2F;ram1 &#x2F;media&#x2F;ram1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cat &#x2F;media&#x2F;ram1&#x2F;foo.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;test file.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Mon Apr  9 12:56:59 BST 2007&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Success!&lt;&#x2F;p&gt;
&lt;p&gt;Script for checking file in saved partition:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mount and check restored ramdisk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if [ ! -d &#x2F;media&#x2F;ram1 ]; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mkdir &#x2F;media&#x2F;ram1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mount &#x2F;dev&#x2F;ram1 &#x2F;media&#x2F;ram1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cat &#x2F;media&#x2F;ram1&#x2F;foo.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;umount &#x2F;media&#x2F;ram1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To debug in KDevelop as root (in ubuntu):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;alt-F2 (run)&lt;&#x2F;li&gt;
&lt;li&gt;gksudo kdevelop&lt;&#x2F;li&gt;
&lt;li&gt;open project... (go find existing copy)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So in summary, I have made progress in understanding the ways of this useful utility, and am a step closer to making a useful contribution to the project.&lt;&#x2F;p&gt;
&lt;p&gt;The rambling nature of this post reflects the way in which one begins to understand a new program. Hopefully it&#x27;s not too hard to follow, or pick out the useful pieces. All feedback gratefully appreciated.&lt;&#x2F;p&gt;
&lt;p&gt;Tim.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>bad geek joke: the bourne shell</title>
        <published>2007-03-30T00:36:00+00:00</published>
        <updated>2007-03-30T00:36:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/03/30/bad-geek-joke-bourne-shell/"/>
        <id>https://0x5.uk/2007/03/30/bad-geek-joke-bourne-shell/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/03/30/bad-geek-joke-bourne-shell/">&lt;p&gt;Here&#x27;s one I made earlier (19 Oct 2006 according to my pc):&lt;&#x2F;p&gt;
&lt;div class=&quot;flickr-pic&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;7463254@N02&#x2F;439217204&#x2F;&quot;&gt;&lt;img
src=&quot;https:&#x2F;&#x2F;live.staticflickr.com&#x2F;160&#x2F;439217204_ddcd1306e6.jpg&quot; alt=&quot;bourneshell.png&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;It&#x27;s modified from &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;thebourneidentity.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;thebourneidentity.com&#x2F;&lt;&#x2F;a&gt;, which is incidentally a film I very much like.&lt;&#x2F;p&gt;
&lt;p&gt;For those who don&#x27;t know, this is the bourne shell:&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bourne_shell&quot;&gt;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bourne_shell&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Which is the father of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;bash&#x2F;&quot;&gt;BASH&lt;&#x2F;a&gt; (&#x2F;bin&#x2F;bash, the Bourne Again SHell)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>partimage + stdout, existing code</title>
        <published>2007-03-30T00:09:00+00:00</published>
        <updated>2007-03-30T00:09:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/03/30/partimage-stdout-existing-code/"/>
        <id>https://0x5.uk/2007/03/30/partimage-stdout-existing-code/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/03/30/partimage-stdout-existing-code/">&lt;p&gt;On first inspection it looks like some code already exists for writing an image to stdout (standard output).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;partimage.svn.sourceforge.net&#x2F;viewvc&#x2F;partimage&#x2F;trunk&#x2F;partimage&#x2F;src&#x2F;shared&#x2F;image_disk.cpp?revision=1&amp;amp;view=markup&amp;amp;pathrev=20#l_558&quot;&gt;image_disk.cpp, line 558&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  if (strcmp(m_szImageFilename, &amp;quot;stdout&amp;quot;))    {      &#x2F;&#x2F;... network output code hidden for clarity ...    }  else &#x2F;&#x2F; it&amp;#39;s stdout    {      m_fImageFile = stdout;      showDebug(1, &amp;quot;image will be on stdout\n&amp;quot;);    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Unlike stdin for restore, stdout for save is not currently available in the command line options. I did do a build earlier where I enabled it (which I don&#x27;t have any more due to my build problems). I managed to pipe an image to hexdump and seemed to be able to see some of the user interface info in the output.&lt;&#x2F;p&gt;
&lt;p&gt;It would seem the problem with the stdout option is that even in batch mode the program outputs interface data to stdout, which then corrupts the image.&lt;&#x2F;p&gt;
&lt;p&gt;I think I shall attempt to remove all the UI stuff, and make it act more like all the other unix tools. Might also try to create a reusable library out of it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>compiling partimage</title>
        <published>2007-03-26T23:06:00+00:00</published>
        <updated>2007-03-26T23:06:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/03/26/compiling-partimage/"/>
        <id>https://0x5.uk/2007/03/26/compiling-partimage/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/03/26/compiling-partimage/">&lt;p&gt;Had a problems getting partimage to compile on one of my pcs from a fresh checkout.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;svn co https:&#x2F;&#x2F;partimage.svn.sourceforge.net&#x2F;svnroot&#x2F;partimage&#x2F;trunk&#x2F;partimage partimage  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The .&#x2F;autogen.sh script was failing as follows&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tim@lap:~&#x2F;projects&#x2F;partimage$ .&#x2F;autogen.sh  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Running &amp;quot;autoreconf -vif&amp;quot; ...  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: Entering directory .&amp;#39;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: running: autopoint --force  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: running: aclocal -I m4 --output=aclocal.m4t  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: aclocal.m4&amp;#39; is unchanged  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: configure.ac: tracing  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: running: libtoolize --copy --force  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: running: &#x2F;usr&#x2F;bin&#x2F;autoconf --force  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: running: &#x2F;usr&#x2F;bin&#x2F;autoheader --force  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: running: automake --add-missing --copy  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;configure.ac: 16: required file .&#x2F;[config.h].in&amp;#39; not found  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Makefile.am:1: AM_GNU_GETTEXT in configure.ac&amp;#39; but intl&amp;#39; not in SUBDIRS  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;automake: Makefile.am: AM_GNU_GETTEXT in configure.ac&amp;#39; but ALL_LINGUAS&amp;#39; not defined  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoreconf: automake failed with exit status: 1  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Done.  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Barked up lots of wrong trees, including looking for missing libraries, gettext config etc.&lt;&#x2F;p&gt;
&lt;p&gt;Turned out to be an old version of automake.&lt;&#x2F;p&gt;
&lt;p&gt;Not sure how my other pc ended up with the right version, but this pc&#x27;s version was:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ automake --version  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;automake (GNU automake) 1.4-p6  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Installing new version (with some help from command line auto-completion):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ apt-get install automake_[tab]_  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;automake automake1.5 automake1.8  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;automake1.4 automake1.6 automake1.9  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;automake1.4-doc automake1.7 automaken  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo apt-get install automake1.9  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ automake --version  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;automake (GNU automake) 1.9.6  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After updating automake, the .&#x2F;autogen.sh script ran, and I could then run .&#x2F;configure and make successfully, and was left with a binary for partimage in src&#x2F;client&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;Hurrah.&lt;&#x2F;p&gt;
&lt;p&gt;The solution came from a post by Tibor Simko on cdsware.cern.ch:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cdsware.cern.ch&#x2F;lists&#x2F;project-cdsware-users&#x2F;archive&#x2F;msg00694.shtml&quot;&gt;Re: problem with autoreconf when installing from cvs&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;From: Tibor Simko&lt;a href=&quot;mailto:tibor.simko@xxxxxxx&quot;&gt;tibor.simko@xxxxxxx&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Subject: Re: problem with autoreconf when installing from cvs&lt;&#x2F;li&gt;
&lt;li&gt;Date: Thu, 18 Jan 2007 18:12:20 +0100&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Hello:&lt;&#x2F;p&gt;
&lt;p&gt;On Thu, 18 Jan 2007, robert forkel wrote:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;$ autoreconf&lt;br &#x2F;&gt;
Makefile.am:23: AM_GNU_GETTEXT in configure.ac&#x27; but intl&#x27; not in SUBDIRS&lt;br &#x2F;&gt;
automake: Makefile.am: AM_GNU_GETTEXT in configure.ac&#x27; but&lt;br &#x2F;&gt;
ALL_LINGUAS&#x27; not defined&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Which version numbers of automake, autoconf, and gettext do you have?&lt;br &#x2F;&gt;
E.g. automake versions prior to 1.9 and gettext versions prior to 0.14&lt;br &#x2F;&gt;
will not work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;best-regards&quot;&gt;Best regards&lt;&#x2F;h2&gt;
&lt;p&gt;Tibor Simko&lt;a href=&quot;mailto:&#x2F;tibor.simko@xxxxxxx&quot;&gt;&#x2F;tibor.simko@xxxxxxx&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>tim; now available with flickr pics</title>
        <published>2007-03-23T22:21:00+00:00</published>
        <updated>2007-03-23T22:21:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/03/23/tim-now-available-with-flickr-pics/"/>
        <id>https://0x5.uk/2007/03/23/tim-now-available-with-flickr-pics/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/03/23/tim-now-available-with-flickr-pics/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.flickr.com&#x2F;photos&#x2F;7463254%40N02&#x2F;&quot;&gt;me on flickr&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve now started putting pretty photos up on flickr.&lt;&#x2F;p&gt;
&lt;p&gt;here&#x27;s my first pic:&lt;br &#x2F;&gt;
&lt;img src=&quot;http:&#x2F;&#x2F;farm1.static.flickr.com&#x2F;160&#x2F;431853892_7828040373_d.jpg&quot; alt=&quot;trees&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Multi-room music at home</title>
        <published>2007-03-16T17:09:00+00:00</published>
        <updated>2007-03-16T17:09:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/03/16/multi-room-music-at-home/"/>
        <id>https://0x5.uk/2007/03/16/multi-room-music-at-home/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/03/16/multi-room-music-at-home/">&lt;p&gt;me and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;freshmeat.net&#x2F;projects&#x2F;slimserver&#x2F;&quot;&gt;slimserver&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Today, I wanted to play music&#x2F;radio in more than one room, and since BBC Radio 4 was playing The Archers, that ruled out the FM&#x2F;Radio 4 simple option!&lt;&#x2F;p&gt;
&lt;p&gt;So, not liking to do anything the simple way, I set about searching for a way to broadcast sound to multiple rooms, preferably with a UDP&#x2F;multicast type setup. Didn&#x27;t manage that in the end, but have got something quite cool running.&lt;&#x2F;p&gt;
&lt;p&gt;Initially came across &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fireflymediaserver.org&#x2F;&quot;&gt;firefly&lt;&#x2F;a&gt; media server, from &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.linux-magazine.com&#x2F;issue&#x2F;77&#x2F;Firefly_Audio_Streaming.pdf&quot;&gt;an article&lt;&#x2F;a&gt; [pdf] in &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.linux-magazine.com&#x2F;&quot;&gt;linux magazine&lt;&#x2F;a&gt;. Was put off by its absence from the ubuntu repositories.&lt;&#x2F;p&gt;
&lt;p&gt;I have a mate with a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.slimdevices.com&#x2F;&quot;&gt;slimdevice&lt;&#x2F;a&gt;, which is an awesome device. The server side of it is available free as it is OSS, and it is in the ubuntu repo (universe). So install was trivial:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo apt-get install slimserver  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I could immediately connect with a web browser to http:&#x2F;&#x2F;localhost:9000&#x2F; and see the web interface (which is very good), and point any of my media players to http:&#x2F;&#x2F;localhost:9000&#x2F;stream.mp3 and listen to the selected music. Nice. (Requires mp3 codec support to be installed. See &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;easyubuntu.freecontrib.org&#x2F;&quot;&gt;easyubuntu&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;Two things tripped me up connecting remotely. I had already spotted &quot;Server Settings &#x2F; Security &#x2F; Allowed IP Addresses&quot; and added my local subnet, but wasn&#x27;t able to connect from another pc.&lt;br &#x2F;&gt;
netstat showed that the server had only bound to the local ip address:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ netstat -tln  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Active Internet connections (only servers)  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Proto Recv-Q Send-Q Local Address Foreign Address State  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Through chance I knew about defaults files in ubuntu. Looking in &#x2F;etc&#x2F;defaults&#x2F;slimserver, what do I find? Only bind to localhost. duh!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# This limits http access to the local host.  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Comment it out for network-wide access, or change  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# to enable a single interface.  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;HTTP_ADDR=127.0.0.1  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So, I commented out the http_addr line, and restarted the slimserver.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#657B83, #839496); background-color: light-dark(#FDF6E3, #002B36);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo &#x2F;etc&#x2F;init.d&#x2F;slimserver restart  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Slim server was now listening on *:9000&lt;&#x2F;p&gt;
&lt;p&gt;The other thing that tripped me up is that slimserver doesn&#x27;t multicast, it maintains an independent stream &amp;amp; playlist for each connected device. So when I connected remotely I hadn&#x27;t added music to the right playlist. In the web based interface there is a drop down list to select which device&#x27;s playlist you want to modify. Once I figured that out it all worked. Yay. :-)&lt;&#x2F;p&gt;
&lt;p&gt;Didn&#x27;t solve the original problem of playing the same audio simultaneously in multiple rooms, but it&#x27;s cool nonetheless.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Today&#x27;s project - partimage enhancement</title>
        <published>2007-03-13T22:01:00+00:00</published>
        <updated>2007-03-13T22:01:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/03/13/todays-project-partimage-enhancement/"/>
        <id>https://0x5.uk/2007/03/13/todays-project-partimage-enhancement/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/03/13/todays-project-partimage-enhancement/">&lt;p&gt;&lt;em&gt;me and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.partimage.org&#x2F;&quot;&gt;partimage&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I recently reorganised the partitions on my laptop, with the help of some
invaluable OSS tools.&lt;&#x2F;p&gt;
&lt;p&gt;The laptop was split into OS partitions, with a data and swap partition at the
end, but I&#x27;d starting running out of space. I have since made ubuntu my only OS
at home, so no longer require multiple partitions.  My partition table ended up
looking something like this: &lt;em&gt;data | OS | more data | swap&lt;&#x2F;em&gt;, and I wanted it to
look like this: &lt;em&gt;OS &amp;amp; data | swap&lt;&#x2F;em&gt;, but without having to rebuild (again).&lt;&#x2F;p&gt;
&lt;p&gt;With another linux box available with bags of disc space, I did something like the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;from each data partition and my home folder: &lt;code&gt;tar -cv datafolder | ssh otherbox &quot;cat &amp;gt; laptop&#x2F;datafolder.tar&quot;&lt;&#x2F;code&gt;, which gave me a tarball of all my
data&lt;&#x2F;li&gt;
&lt;li&gt;boot into knoppix 4&lt;&#x2F;li&gt;
&lt;li&gt;use partimage to save os parition image into filesystem of another
partition&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;scp osimage.img otherbox:laptop&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fdisk&lt;&#x2F;code&gt; to set up new partitions&lt;&#x2F;li&gt;
&lt;li&gt;pipe the image back into partimage across the wire: &lt;code&gt;ssh otherbox &quot;cat laptop&#x2F;osimage.img&quot; | partimage ....&lt;&#x2F;code&gt; plus some flags for batch writing to
new partition&lt;&#x2F;li&gt;
&lt;li&gt;use parted (partition editor) to stretch partition image back up to full
size of new partition.&lt;&#x2F;li&gt;
&lt;li&gt;fix grub with help from knoppix - &lt;code&gt;hda(0,2)&lt;&#x2F;code&gt; to &lt;code&gt;hda(0,0)&lt;&#x2F;code&gt; or something.&lt;&#x2F;li&gt;
&lt;li&gt;remove references to non existent partitions from fstab&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Which was all great, but I feel there&#x27;s a feature missing from partimage.
Although it can read an image from stdin for writing to disc, it can&#x27;t write an
image to stdout from disc. This would have saved me some thinking and some
hassle. So in the true spirit of OSS, I shall have a go at adding the
functionality.&lt;&#x2F;p&gt;
&lt;p&gt;So far, I have grabbed the source from sourceforge&#x27;s svn server, managed to
compile the source (after being confused by a misleading error message) and
installed an IDE. I started with Eclipse, as I&#x27;ve been using it a bit recently
and really like it, but figure that perhaps the C++ devs aren&#x27;t likely to be
java fans and maybe they would choose something else. So I&#x27;ve installed
KDevelop, and will be having a go with that.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>new blog, take two</title>
        <published>2007-03-13T00:00:00+00:00</published>
        <updated>2007-03-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/03/13/slashdot-journal-166369-new-blog-take-two/"/>
        <id>https://0x5.uk/2007/03/13/slashdot-journal-166369-new-blog-take-two/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/03/13/slashdot-journal-166369-new-blog-take-two/">&lt;p&gt;ok, that was an enormous failure.&lt;&#x2F;p&gt;
&lt;p&gt;installed wordpress on a machine at home. got hacked (duh). spent a month working my butt off at work and haven&#x27;t even looked it.&lt;br&gt;second attempt here: &lt;a href=&quot;http:&#x2F;&#x2F;timwise.blogspot.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;timwise.blogspot.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;will be full of lots of fascinating open source exploits. might even start posting pretty photos with flickr.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>tim&#x27;s new blog</title>
        <published>2007-01-07T00:00:00+00:00</published>
        <updated>2007-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2007/01/07/slashdot-journal-158640-tims-new-blog/"/>
        <id>https://0x5.uk/2007/01/07/slashdot-journal-158640-tims-new-blog/</id>
        
        <content type="html" xml:base="https://0x5.uk/2007/01/07/slashdot-journal-158640-tims-new-blog/">&lt;p&gt;Seeing as blogging has reached the masses I&#x27;m going to start writing in a normal blog.&lt;br&gt;I will no longer write in here most likely.&lt;&#x2F;p&gt;
&lt;p&gt;the new url is currently &lt;a href=&quot;http:&#x2F;&#x2F;timwise.dyndns.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;timwise.dyndns.org&#x2F;&lt;&#x2F;a&gt; but we&#x27;ll see how that goes.&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mountain bike stolen</title>
        <published>2006-11-24T00:00:00+00:00</published>
        <updated>2006-11-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/11/24/slashdot-journal-136097-mountain-bike-stolen/"/>
        <id>https://0x5.uk/2006/11/24/slashdot-journal-136097-mountain-bike-stolen/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/11/24/slashdot-journal-136097-mountain-bike-stolen/">&lt;p&gt;Some low life stole my mountain bike on sunday night.&lt;br&gt;Bolt cropped both locks.&lt;br&gt;Was in the bike shed behind the closed gate behind the flats.&lt;br&gt;Bastards.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>a manual? for £££££?!</title>
        <published>2006-07-19T00:00:00+00:00</published>
        <updated>2006-07-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/07/19/slashdot-journal-140082-a-manual-for-/"/>
        <id>https://0x5.uk/2006/07/19/slashdot-journal-140082-a-manual-for-/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/07/19/slashdot-journal-140082-a-manual-for-/">&lt;p&gt;What kind of two bit fucked up piece of shit organisation expects you to *BUY* manuals for a product you have already paid for?!&lt;&#x2F;p&gt;
&lt;p&gt;Holy cow, that&#x27;d be canon.&lt;br&gt;&quot;Selected User Manuals are available to purchase from Robert Scott...&quot;&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.canon.co.uk&#x2F;Support&#x2F;User_Manuals&#x2F;index.asp&quot;&gt;http:&#x2F;&#x2F;www.canon.co.uk&#x2F;Support&#x2F;User_Manuals&#x2F;index.asp&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Last fucking business they get from me.&lt;&#x2F;p&gt;
&lt;p&gt;And their support of linux consists of fingers in ears &quot;la la la it doens&#x27;t exist&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m going to try and get a refund for my printer and buy one from a company who cares about their customer&#x27;s experience.&lt;&#x2F;p&gt;
&lt;p&gt;Wankers.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sailing pics</title>
        <published>2006-07-09T00:00:00+00:00</published>
        <updated>2006-07-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/07/09/slashdot-journal-139362-sailing-pics/"/>
        <id>https://0x5.uk/2006/07/09/slashdot-journal-139362-sailing-pics/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/07/09/slashdot-journal-139362-sailing-pics/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;timwise.co.uk&#x2F;photos&#x2F;sailing06&#x2F;&quot;&gt;http:&#x2F;&#x2F;timwise.co.uk&#x2F;photos&#x2F;sailing06&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>M4 J11 Reading plans</title>
        <published>2006-07-07T00:00:00+00:00</published>
        <updated>2006-07-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/07/07/slashdot-journal-139223-m4-j11-reading-plans/"/>
        <id>https://0x5.uk/2006/07/07/slashdot-journal-139223-m4-j11-reading-plans/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/07/07/slashdot-journal-139223-m4-j11-reading-plans/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;england&#x2F;berkshire&#x2F;5154816.stm&quot;&gt;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;england&#x2F;berkshire&#x2F;5154816.stm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.pba.co.uk&#x2F;keyprojects.asp?ID=29&quot;&gt;http:&#x2F;&#x2F;www.pba.co.uk&#x2F;keyprojects.asp?ID=29&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.reading.gov.uk&#x2F;Documents&#x2F;transport_streets&#x2F;M4J11Map1.pdf&quot;&gt;http:&#x2F;&#x2F;www.reading.gov.uk&#x2F;Documents&#x2F;transport_streets&#x2F;M4J11Map1.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.reading.gov.uk&#x2F;Documents&#x2F;transport_streets&#x2F;1211MajorSchemes.pdf&quot;&gt;http:&#x2F;&#x2F;www.reading.gov.uk&#x2F;Documents&#x2F;transport_streets&#x2F;1211MajorSchemes.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(Thanks Liz)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>comedy email circular</title>
        <published>2006-05-25T00:00:00+00:00</published>
        <updated>2006-05-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/05/25/slashdot-journal-136226-comedy-email-circular/"/>
        <id>https://0x5.uk/2006/05/25/slashdot-journal-136226-comedy-email-circular/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/05/25/slashdot-journal-136226-comedy-email-circular/">&lt;p&gt;Thanks to our head of sales for this one:&lt;&#x2F;p&gt;
&lt;p&gt;=========================================&lt;&#x2F;p&gt;
&lt;p&gt;The Department of Transport has now devised a new scheme in order to identify poor drivers and give good drivers the opportunity to recognise them whilst driving.&lt;&#x2F;p&gt;
&lt;p&gt;For this reason as from the middle of May 2006 those drivers  who are&lt;br&gt;found to be driving badly which includes:&lt;&#x2F;p&gt;
&lt;p&gt;
    -overtaking in dangerous places;&lt;&#x2F;p&gt;
&lt;p&gt;
    -hovering within one inch of the car in front;&lt;&#x2F;p&gt;
&lt;p&gt;
    -stopping sharply;&lt;&#x2F;p&gt;
&lt;p&gt;
    -speeding in residential areas;&lt;&#x2F;p&gt;
&lt;p&gt;
    -pulling out without indication;&lt;&#x2F;p&gt;
&lt;p&gt;
    -performing U turns inappropriately in busy high streets;&lt;&#x2F;p&gt;
&lt;p&gt;
    -under taking on motorways and&lt;&#x2F;p&gt;
&lt;p&gt;
    -taking up more than one lane in multi lane roads,&lt;&#x2F;p&gt;
&lt;p&gt;
  These drivers will be issued with flags, white with a red cross,&lt;br&gt;signifying their inability to drive properly. These flags must be&lt;br&gt;clipped to a door of the car and be visible to all other drivers and&lt;br&gt;pedestrians.&lt;&#x2F;p&gt;
&lt;p&gt;Those drivers who have shown particularly poor driving skills will have&lt;br&gt;to display a flag on each side of the car to indicate their greater lack&lt;br&gt;of  skill and general lower intelligence mindset to the general public.&lt;&#x2F;p&gt;
&lt;p&gt;Please circulate this to as many other motorists as you can so that&lt;br&gt;drivers and pedestrians will be aware of the meaning of these flags.&lt;&#x2F;p&gt;
&lt;p&gt;
  Department of Transport.&lt;&#x2F;p&gt;
&lt;p&gt;Samantha Harvey - Engineer&lt;br&gt;SCC Highway Safety and Improvement&lt;br&gt;Integrated Transport (East)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Ian &amp; broadband</title>
        <published>2006-05-23T00:00:00+00:00</published>
        <updated>2006-05-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/05/23/slashdot-journal-136058-ian-broadband/"/>
        <id>https://0x5.uk/2006/05/23/slashdot-journal-136058-ian-broadband/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/05/23/slashdot-journal-136058-ian-broadband/">&lt;p&gt;Ian was &lt;a href=&quot;http:&#x2F;&#x2F;www.pure-virtual.org&#x2F;ian&#x2F;PermaLink.aspx?guid=941da462-0038-44ee-99e8-fc2253e7a4c0&quot;&gt;here&lt;&#x2F;a&gt; (old news).&lt;br&gt;Found that page &lt;a href=&quot;http:&#x2F;&#x2F;www.google.co.uk&#x2F;search?hl=en&amp;amp;q=site%3A+timwise.co.uk&amp;amp;btnG=Search&amp;amp;meta=&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;New broadband connection up on timwise.dyndns.org (no website yet).&lt;br&gt;Nice bt engineer, who called 10 mins before showing up. Handy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Get with the (music) program - podsafe radio</title>
        <published>2006-04-28T00:00:00+00:00</published>
        <updated>2006-04-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/04/28/slashdot-journal-134479-get-with-the-music-program---podsafe-radio/"/>
        <id>https://0x5.uk/2006/04/28/slashdot-journal-134479-get-with-the-music-program---podsafe-radio/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/04/28/slashdot-journal-134479-get-with-the-music-program---podsafe-radio/">&lt;p&gt;I&#x27;ve been looking for a show to listen to for some time that has some decent music in it. Finally I&#x27;ve found one:&lt;br&gt;The podshow music rewind: &lt;a href=&quot;http:&#x2F;&#x2F;rewind.podshow.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;rewind.podshow.com&#x2F;&lt;&#x2F;a&gt;&lt;br&gt;Check it out. This guy plays clips from all the podshows, showcasing the best new music from the podsafe music network.&lt;&#x2F;p&gt;
&lt;p&gt;I came across it thanks to Adam Curry &lt;a href=&quot;http:&#x2F;&#x2F;curry.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;curry.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Fyi: you can subscribe with:&lt;br&gt;iTunes (easy)&lt;br&gt;Juice (desiigned for the job) &lt;a href=&quot;http:&#x2F;&#x2F;juicereceiver.sourceforge.net&#x2F;index.php&quot;&gt;http:&#x2F;&#x2F;juicereceiver.sourceforge.net&#x2F;index.php&lt;&#x2F;a&gt;&lt;br&gt;or bashpodder (quick &amp;amp; effective linux script) &lt;a href=&quot;http:&#x2F;&#x2F;linc.homeunix.org:8080&#x2F;scripts&#x2F;bashpodder&#x2F;&quot;&gt;http:&#x2F;&#x2F;linc.homeunix.org:8080&#x2F;scripts&#x2F;bashpodder&#x2F;&lt;&#x2F;a&gt; - my favourite&lt;br&gt;there&#x27;s many more of course.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>bad websites</title>
        <published>2006-03-11T00:00:00+00:00</published>
        <updated>2006-03-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/03/11/slashdot-journal-131064-bad-websites/"/>
        <id>https://0x5.uk/2006/03/11/slashdot-journal-131064-bad-websites/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/03/11/slashdot-journal-131064-bad-websites/">&lt;p&gt;I didn&#x27;t think this kind of thing still existed, let alone on a commercial site:&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.mytravelmoney.com&#x2F;SiteBrowser.htm&quot;&gt;https:&#x2F;&#x2F;www.mytravelmoney.com&#x2F;SiteBrowser.htm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So I sent them a rant&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;&#x2F;p&gt;
&lt;p&gt;---------------&lt;br&gt;To: webmaster@mytravelmoney.com; webmaster@goingplaces.co.uk&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.goingplaces.co.uk&#x2F;AniteNextPage.asp?p=HOLIDAYEXTRASHOME&amp;amp;s=162000990&quot;&gt;http:&#x2F;&#x2F;www.goingplaces.co.uk&#x2F;AniteNextPage.asp?p=HOLIDAYEXTRASHOME&amp;amp;s=162000990&lt;&#x2F;a&gt;&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.mytravelmoney.com&#x2F;SiteBrowser.htm&quot;&gt;https:&#x2F;&#x2F;www.mytravelmoney.com&#x2F;SiteBrowser.htm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From your site:&lt;&#x2F;p&gt;
&lt;p&gt;
        &quot;The view this site you must use Internet Explorer 5.0 or later.&lt;&#x2F;p&gt;
&lt;p&gt;
        You may download the latest version of Internet Explorer from the following URL:&lt;&#x2F;p&gt;
&lt;p&gt;
        &lt;a href=&quot;http:&#x2F;&#x2F;www.microsoft.com&#x2F;windows&#x2F;ie&#x2F;downloads&quot;&gt;http:&#x2F;&#x2F;www.microsoft.com&#x2F;windows&#x2F;ie&#x2F;downloads&lt;&#x2F;a&gt;&quot;&lt;&#x2F;p&gt;
&lt;p&gt;This is unacceptable.&lt;&#x2F;p&gt;
&lt;p&gt;Haven&#x27;t you heard of Firefox, Opera, Netscape, Mozilla, Lynx, Safari? Or Linux? Or Macs? Or the W3C and the drive for standards? This kind of message makes your site look like it&#x27;s stuck in the 80&#x27;s. If you cannot design a site for more than one browser then you shouldn&#x27;t be designing websites.&lt;br&gt;In case you hadn&#x27;t guessed, I won&#x27;t now be buying currency from you.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>bicycles</title>
        <published>2006-03-10T00:00:00+00:00</published>
        <updated>2006-03-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/03/10/slashdot-journal-130984-bicycles/"/>
        <id>https://0x5.uk/2006/03/10/slashdot-journal-130984-bicycles/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/03/10/slashdot-journal-130984-bicycles/">&lt;p&gt;BBC News on new highway code:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;magazine&#x2F;4789146.stm&quot;&gt;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;magazine&#x2F;4789146.stm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bad cycle lanes:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.warringtoncyclecampaign.co.uk&#x2F;facility-of-the-month&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.warringtoncyclecampaign.co.uk&#x2F;facility-of-the-month&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sunglasses mounted mirror:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;icebike.org&#x2F;Equipment&#x2F;cyclingmirrors.htm&quot;&gt;http:&#x2F;&#x2F;icebike.org&#x2F;Equipment&#x2F;cyclingmirrors.htm&lt;&#x2F;a&gt; - skip down to &quot;Take A Look:&quot;&lt;&#x2F;p&gt;
&lt;p&gt;My new favourite bike shop: CycleZone (no real website)&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.touchreading.com&#x2F;business&#x2F;list&#x2F;bid&#x2F;3605783&quot;&gt;http:&#x2F;&#x2F;www.touchreading.com&#x2F;business&#x2F;list&#x2F;bid&#x2F;3605783&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>gimp trouble</title>
        <published>2006-01-04T00:00:00+00:00</published>
        <updated>2006-01-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2006/01/04/slashdot-journal-125704-gimp-trouble/"/>
        <id>https://0x5.uk/2006/01/04/slashdot-journal-125704-gimp-trouble/</id>
        
        <content type="html" xml:base="https://0x5.uk/2006/01/04/slashdot-journal-125704-gimp-trouble/">&lt;p&gt;I like the gimp a lot, and have been trying out some &lt;a href=&quot;http:&#x2F;&#x2F;www.flashgimp.com&#x2F;tutorials&#x2F;photoshop_tutorials.php&quot;&gt;tutorials&lt;&#x2F;a&gt;. Then it started crashing whenever I created a new image! argh! So after a bit of searching and a pointer from a &lt;a href=&quot;http:&#x2F;&#x2F;bugzilla.gnome.org&#x2F;show_bug.cgi?id=317570&quot;&gt;bug report&lt;&#x2F;a&gt; I tried replacing the GTK+ installation I had obtained with &lt;a href=&quot;http:&#x2F;&#x2F;gaim.sf.net&#x2F;&quot;&gt;gaim&lt;&#x2F;a&gt; with a new one from the gimp &lt;a href=&quot;http:&#x2F;&#x2F;gimp-win.sourceforge.net&#x2F;&quot;&gt;installer page&lt;&#x2F;a&gt;. One restart later, problem solved. I like open sauce. Closed source software companies don&#x27;t tend to be keen on publishing problems, even when people have resolutions to offer.&lt;&#x2F;p&gt;
&lt;p&gt;A small insight into Tim&#x27;s life.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>article: Windows rapidly approaching desktop usability!</title>
        <published>2005-12-07T00:00:00+00:00</published>
        <updated>2005-12-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/12/07/slashdot-journal-123764-article-windows-rapidly-approaching-desktop-usability/"/>
        <id>https://0x5.uk/2005/12/07/slashdot-journal-123764-article-windows-rapidly-approaching-desktop-usability/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/12/07/slashdot-journal-123764-article-windows-rapidly-approaching-desktop-usability/">&lt;p&gt;There have been many articles on the merits of linux based systems from the perspective of windows users. Now the tables are turned in this excellently written article. If you have read previous &quot;linux versus windows&quot; tests you will recognise the style and approach, and how it affects the conclusions reached.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;os.newsforge.com&#x2F;article.pl?sid=05&#x2F;05&#x2F;18&#x2F;2033216&amp;amp;tid=149&quot;&gt;http:&#x2F;&#x2F;os.newsforge.com&#x2F;article.pl?sid=05&#x2F;05&#x2F;18&#x2F;2033216&amp;amp;tid=149&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>cv</title>
        <published>2005-11-30T00:00:00+00:00</published>
        <updated>2005-11-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/11/30/slashdot-journal-123305-cv/"/>
        <id>https://0x5.uk/2005/11/30/slashdot-journal-123305-cv/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/11/30/slashdot-journal-123305-cv/">&lt;p&gt;new cv released:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;timwise.co.uk&#x2F;cv.pdf&quot;&gt;http:&#x2F;&#x2F;timwise.co.uk&#x2F;cv.pdf&lt;&#x2F;a&gt; [111Kb&lt;nobr&gt; &lt;&#x2F;nobr&gt;.pdf]&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>colds. ugh</title>
        <published>2005-11-29T00:00:00+00:00</published>
        <updated>2005-11-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/11/29/slashdot-journal-123212-colds-ugh/"/>
        <id>https://0x5.uk/2005/11/29/slashdot-journal-123212-colds-ugh/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/11/29/slashdot-journal-123212-colds-ugh/">&lt;p&gt;today I have a cold.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:(&lt;&#x2F;p&gt;
&lt;p&gt;oh, and i did write a journal entry the other day, but my computer died b4 I could post it.&lt;&#x2F;p&gt;
&lt;p&gt;it looks like usage of bebo.com is taking off amongst my friends, which is good.&lt;&#x2F;p&gt;
&lt;p&gt;Plan to see Tom this weekend, looking forward to that.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>read a book today - without leaving your chair</title>
        <published>2005-11-18T00:00:00+00:00</published>
        <updated>2005-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/11/18/slashdot-journal-122411-read-a-book-today---without-leaving-your-chair/"/>
        <id>https://0x5.uk/2005/11/18/slashdot-journal-122411-read-a-book-today---without-leaving-your-chair/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/11/18/slashdot-journal-122411-read-a-book-today---without-leaving-your-chair/">&lt;p&gt;Scott Adams is giving his latest book away, for nothing (no beers)!&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.andrewsmcmeel.com&#x2F;godsdebris&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.andrewsmcmeel.com&#x2F;godsdebris&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;--&lt;&#x2F;p&gt;
&lt;p&gt;I know because he sent me his &lt;a href=&quot;http:&#x2F;&#x2F;www.dilbert.com&#x2F;comics&#x2F;dilbert&#x2F;dnrc&#x2F;html&#x2F;newsletter62.html&quot;&gt;newsletter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>article: micro$oft battles for survival of office</title>
        <published>2005-11-10T00:00:00+00:00</published>
        <updated>2005-11-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/11/10/slashdot-journal-121807-article-microoft-battles-for-survival-of-office/"/>
        <id>https://0x5.uk/2005/11/10/slashdot-journal-121807-article-microoft-battles-for-survival-of-office/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/11/10/slashdot-journal-121807-article-microoft-battles-for-survival-of-office/">&lt;p&gt;Microsoft is in real danger of losing its office monopoly, which is currently perpetuated by the &quot;I need office to send files to so and so&quot; argument.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;searchopensource.techtarget.com&#x2F;originalContent&#x2F;0,289142,sid39_gci1144104,00.html&quot;&gt;http:&#x2F;&#x2F;searchopensource.techtarget.com&#x2F;originalContent&#x2F;0,289142,sid39_gci1144104,00.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>geek here</title>
        <published>2005-11-09T00:00:00+00:00</published>
        <updated>2005-11-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/11/09/slashdot-journal-121708-geek-here/"/>
        <id>https://0x5.uk/2005/11/09/slashdot-journal-121708-geek-here/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/11/09/slashdot-journal-121708-geek-here/">&lt;p&gt;My second note on code project:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.codeproject.com&#x2F;script&#x2F;profile&#x2F;whos_who.asp?id=1037965&quot;&gt;http:&#x2F;&#x2F;www.codeproject.com&#x2F;script&#x2F;profile&#x2F;whos_who.asp?id=1037965&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Code project is possibly the slowest site ever.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>warning: geek entry - vim</title>
        <published>2005-11-04T00:00:00+00:00</published>
        <updated>2005-11-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/11/04/slashdot-journal-121333-warning-geek-entry---vim/"/>
        <id>https://0x5.uk/2005/11/04/slashdot-journal-121333-warning-geek-entry---vim/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/11/04/slashdot-journal-121333-warning-geek-entry---vim/">&lt;p&gt;I&#x27;ve got to grips with the basics of emacs&#x2F;xemacs, so I thought it was time I got up to speed with this ubiquitous vi thing.&lt;&#x2F;p&gt;
&lt;p&gt;I found a tutorial on my linux box (courtesy of &lt;a href=&quot;http:&#x2F;&#x2F;www.linuxquestions.org&#x2F;&quot;&gt;linuxquestions&lt;&#x2F;a&gt;). It&#x27;s under and hour, and I feel like I understand how to do basic editing now.&lt;&#x2F;p&gt;
&lt;p&gt;Fire up your trusty linux box, switch to a console (ctrl+alt+f1), login, then type &#x27;vimtutor&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;Super, ~800 lines of interactivity that will have you up in no time...&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hurricane Wilma</title>
        <published>2005-10-21T00:00:00+00:00</published>
        <updated>2005-10-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/10/21/slashdot-journal-120313-hurricane-wilma/"/>
        <id>https://0x5.uk/2005/10/21/slashdot-journal-120313-hurricane-wilma/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/10/21/slashdot-journal-120313-hurricane-wilma/">&lt;p&gt;A live view of the progress of hurricane Wilma:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;earth.google.com&#x2F;downloads.html&quot;&gt;Google Earth&lt;&#x2F;a&gt; plus &lt;a href=&quot;http:&#x2F;&#x2F;bbs.keyhole.com&#x2F;ubb&#x2F;placemarks&#x2F;110283-Hurri.kmz&quot;&gt;http:&#x2F;&#x2F;bbs.keyhole.com&#x2F;ubb&#x2F;placemarks&#x2F;110283-Hurri.kmz&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once you&#x27;ve looked at this, take a look at the spectral overlay (in Places on left hand side)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>trackback</title>
        <published>2005-10-11T00:00:00+00:00</published>
        <updated>2005-10-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/10/11/slashdot-journal-119447-trackback/"/>
        <id>https://0x5.uk/2005/10/11/slashdot-journal-119447-trackback/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/10/11/slashdot-journal-119447-trackback/">&lt;p&gt;posted comment here:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;evilsoft.blogspot.com&#x2F;2005&#x2F;04&#x2F;whats-in-box.html#comments&quot;&gt;http:&#x2F;&#x2F;evilsoft.blogspot.com&#x2F;2005&#x2F;04&#x2F;whats-in-box.html#comments&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>copying all (hidden) files in linux with cp</title>
        <published>2005-09-29T00:00:00+00:00</published>
        <updated>2005-09-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/09/29/slashdot-journal-118511-copying-all-hidden-files-in-linux-with-cp/"/>
        <id>https://0x5.uk/2005/09/29/slashdot-journal-118511-copying-all-hidden-files-in-linux-with-cp/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/09/29/slashdot-journal-118511-copying-all-hidden-files-in-linux-with-cp/">&lt;p&gt;One of my old pet hates in Windoze is the default explorer setting to hide system files, which means you don&#x27;t get everything when copying stuff.&lt;&#x2F;p&gt;
&lt;p&gt;In linux, a hidden a file or directory is anything that starts with a dot.&lt;br&gt;So, I want to take a copy of my ~&#x2F; (home, like windoze profile), hidden files and all.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt; &lt;tt&gt;cd&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;home&#x2F;tim&lt;br&gt;cp -r&lt;nobr&gt; &lt;&#x2F;nobr&gt;.&#x2F;*&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;mnt&#x2F;otherhdd&#x2F;stuff&#x2F;timshome&#x2F;&lt;&#x2F;tt&gt;&lt;&#x2F;p&gt;&lt;&#x2F;div&gt; &lt;&#x2F;blockquote&gt;
&lt;p&gt;Look with ls -l, no hidden files. hrmm.&lt;&#x2F;p&gt;
&lt;p&gt;Only thing I could find was this:&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.redhat.com&#x2F;archives&#x2F;fedora-list&#x2F;2004-October&#x2F;msg01760.html&quot;&gt;https:&#x2F;&#x2F;www.redhat.com&#x2F;archives&#x2F;fedora-list&#x2F;2004-October&#x2F;msg01760.html&lt;&#x2F;a&gt; &lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt; &lt;tt&gt;cp -r&lt;nobr&gt; &lt;&#x2F;nobr&gt;.??*&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;mnt&#x2F;otherhdd&#x2F;stuff&#x2F;timshome&#x2F;&lt;&#x2F;tt&gt;&lt;&#x2F;p&gt;&lt;&#x2F;div&gt; &lt;&#x2F;blockquote&gt;
&lt;p&gt;Seems a bit clunky to me.&lt;br&gt;Anyone know a better way? Like cp -rh or summat.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>microsoft office clipart</title>
        <published>2005-09-06T00:00:00+00:00</published>
        <updated>2005-09-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/09/06/slashdot-journal-116467-microsoft-office-clipart/"/>
        <id>https://0x5.uk/2005/09/06/slashdot-journal-116467-microsoft-office-clipart/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/09/06/slashdot-journal-116467-microsoft-office-clipart/">&lt;p&gt;take a look at &lt;a href=&quot;http:&#x2F;&#x2F;office.microsoft.com&#x2F;clipart&#x2F;preview.aspx?AssetID=MMj0309727&amp;amp;Query=j0309727&amp;amp;Scope=MC,MM,MP,MS&amp;amp;CTT=1&amp;amp;Origin=EC790000121033&amp;amp;QueryID=p918HLJml&amp;amp;AssetCol=MMj0309727&quot;&gt;this clipart preview&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t know why it&#x27;s interesting (cough), b3ta.com pointed it out.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>marketing? grrrrrrr! oh, and greenbelt this weekend</title>
        <published>2005-08-22T00:00:00+00:00</published>
        <updated>2005-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/08/22/slashdot-journal-115092-marketing-grrrrrrr-oh-and-greenbelt-this-weekend/"/>
        <id>https://0x5.uk/2005/08/22/slashdot-journal-115092-marketing-grrrrrrr-oh-and-greenbelt-this-weekend/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/08/22/slashdot-journal-115092-marketing-grrrrrrr-oh-and-greenbelt-this-weekend/">&lt;p&gt;My mobile just rang.&lt;br&gt;No signal as usual so couldn&#x27;t hear anything.&lt;br&gt;Looked up the &lt;a href=&quot;http:&#x2F;&#x2F;www2.bt.com&#x2F;localarea&quot;&gt;area code&lt;&#x2F;a&gt;, was for Swansea. Ah, thinks me. might be tom. Tried to phone back, piece of crap phone promptly crashed. Turn it on again, swear at the &quot;Vodafone - How are you&quot; greeting (How am I? Pissed off cos the phone crashed, duh. That&#x27;s the only time I ever see that message). Tried again, only to find it&#x27;s not tom&lt;nobr&gt; &lt;&#x2F;nobr&gt;:( but some marketing company. Ugh. Cue registration on the &lt;a href=&quot;http:&#x2F;&#x2F;www.tpsonline.org.uk&#x2F;tps&#x2F;&quot;&gt;Telephone Preference Service&lt;&#x2F;a&gt;, and a pissy journal entry.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;&#x2F;p&gt;
&lt;p&gt;In other news, plan is to do a day trip to &lt;a href=&quot;http:&#x2F;&#x2F;www.greenbelt.org.uk&#x2F;&quot;&gt;greenbelt&lt;&#x2F;a&gt; on the saturday. All welcome.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>funky technology</title>
        <published>2005-08-19T00:00:00+00:00</published>
        <updated>2005-08-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/08/19/slashdot-journal-114890-funky-technology/"/>
        <id>https://0x5.uk/2005/08/19/slashdot-journal-114890-funky-technology/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/08/19/slashdot-journal-114890-funky-technology/">&lt;p&gt;get down to the groove of the new HDD storage science!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.hitachigst.com&#x2F;hdd&#x2F;research&#x2F;recording_head&#x2F;pr&#x2F;PerpendicularAnimation.html&quot;&gt;http:&#x2F;&#x2F;www.hitachigst.com&#x2F;hdd&#x2F;research&#x2F;recording_head&#x2F;pr&#x2F;PerpendicularAnimation.html&lt;&#x2F;a&gt;&lt;br&gt;flash movie, with hip sound track.&lt;&#x2F;p&gt;
&lt;p&gt;Source:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;hardware.slashdot.org&#x2F;article.pl?sid=05&#x2F;08&#x2F;19&#x2F;0027237&quot;&gt;http:&#x2F;&#x2F;hardware.slashdot.org&#x2F;article.pl?sid=05&#x2F;08&#x2F;19&#x2F;0027237&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>tim&#x27;s technical ramblings</title>
        <published>2005-08-10T00:00:00+00:00</published>
        <updated>2005-08-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/08/10/slashdot-journal-114172-tims-technical-ramblings/"/>
        <id>https://0x5.uk/2005/08/10/slashdot-journal-114172-tims-technical-ramblings/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/08/10/slashdot-journal-114172-tims-technical-ramblings/">&lt;p&gt;I&#x27;ll probably post all technical comments to my space on code project now.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.codeproject.com&#x2F;script&#x2F;profile&#x2F;whos_who.asp?id=1037965&quot;&gt;http:&#x2F;&#x2F;www.codeproject.com&#x2F;script&#x2F;profile&#x2F;whos_who.asp?id=1037965&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>google wos ere</title>
        <published>2005-08-10T00:00:00+00:00</published>
        <updated>2005-08-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/08/10/slashdot-journal-114178-google-wos-ere/"/>
        <id>https://0x5.uk/2005/08/10/slashdot-journal-114178-google-wos-ere/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/08/10/slashdot-journal-114178-google-wos-ere/">&lt;p&gt;Google has cached a visit to my header display page, which is cool (if you have a clue what planet I&#x27;m on)&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;216.239.59.104&#x2F;search?q=cache:rJkIzyKroCYJ:www.timwise.co.uk&#x2F;userdetails.asp+site:timwise.co.uk&amp;amp;hl=en&quot;&gt;http:&#x2F;&#x2F;216.239.59.104&#x2F;search?q=cache:rJkIzyKroCYJ:www.timwise.co.uk&#x2F;userdetails.asp+site:timwise.co.uk&amp;amp;hl=en&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>funky flash game</title>
        <published>2005-07-30T00:00:00+00:00</published>
        <updated>2005-07-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/07/30/slashdot-journal-113239-funky-flash-game/"/>
        <id>https://0x5.uk/2005/07/30/slashdot-journal-113239-funky-flash-game/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/07/30/slashdot-journal-113239-funky-flash-game/">&lt;p&gt;Don&#x27;t let the little dude catch your cursor!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.onemorelevel.com&#x2F;games&#x2F;avoider.html&quot;&gt;http:&#x2F;&#x2F;www.onemorelevel.com&#x2F;games&#x2F;avoider.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;brought to you by b3ta.com (of course) issue 191&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>yacht</title>
        <published>2005-07-27T00:00:00+00:00</published>
        <updated>2005-07-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/07/27/slashdot-journal-112954-yacht/"/>
        <id>https://0x5.uk/2005/07/27/slashdot-journal-112954-yacht/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/07/27/slashdot-journal-112954-yacht/">&lt;p&gt;Me on a boat with work people earlier this month. Hurrah.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.no2.co.uk&#x2F;gallery&#x2F;view_album.php?set_albumName=eMapSite-com-Sailing-Weekend-10th-July-2005&amp;amp;page=1&quot;&gt;http:&#x2F;&#x2F;www.no2.co.uk&#x2F;gallery&#x2F;view_album.php?set_albumName=eMapSite-com-Sailing-Weekend-10th-July-2005&amp;amp;page=1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>corolla</title>
        <published>2005-07-27T00:00:00+00:00</published>
        <updated>2005-07-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/07/27/slashdot-journal-113005-corolla/"/>
        <id>https://0x5.uk/2005/07/27/slashdot-journal-113005-corolla/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/07/27/slashdot-journal-113005-corolla/">&lt;p&gt;bit sad, but i&#x27;ve joined the &lt;a href=&quot;http:&#x2F;&#x2F;toyotaownersclub.com&#x2F;&quot;&gt;toyota owner&#x27;s club&lt;&#x2F;a&gt; website&lt;&#x2F;p&gt;
&lt;p&gt;here&#x27;s some of my posts:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;toyotaownersclub.com&#x2F;forums&#x2F;index.php?showtopic=38971&amp;amp;st=0&amp;amp;p=395831&quot;&gt;http:&#x2F;&#x2F;toyotaownersclub.com&#x2F;forums&#x2F;index.php?showtopic=38971&amp;amp;st=0&amp;amp;p=395831&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>post-relational databases in the real world</title>
        <published>2005-07-20T00:00:00+00:00</published>
        <updated>2005-07-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/07/20/slashdot-journal-112339-post-relational-databases-in-the-real-world/"/>
        <id>https://0x5.uk/2005/07/20/slashdot-journal-112339-post-relational-databases-in-the-real-world/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/07/20/slashdot-journal-112339-post-relational-databases-in-the-real-world/">&lt;p&gt;A Simpler Way of Getting&lt;nobr&gt; &lt;&#x2F;nobr&gt;.NET Objects out of ADO.NET&lt;br&gt;By Benjamin Hautefeuille&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.15seconds.com&#x2F;Issue&#x2F;031013.htm&quot;&gt;http:&#x2F;&#x2F;www.15seconds.com&#x2F;Issue&#x2F;031013.htm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A very informative article on the practical isssues and advantages of using a real object database (Matisse) versus the de-facto relational + object mapping solutions.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>no patents on software!!</title>
        <published>2005-07-06T00:00:00+00:00</published>
        <updated>2005-07-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/07/06/slashdot-journal-111220-no-patents-on-software/"/>
        <id>https://0x5.uk/2005/07/06/slashdot-journal-111220-no-patents-on-software/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/07/06/slashdot-journal-111220-no-patents-on-software/">&lt;p&gt;Woo!&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;technology&#x2F;4655955.stm&quot;&gt;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;technology&#x2F;4655955.stm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;see also&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;ffii.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;ffii.org&#x2F;&lt;&#x2F;a&gt;&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.eff.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.eff.org&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>i still hate sundays</title>
        <published>2005-07-03T00:00:00+00:00</published>
        <updated>2005-07-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/07/03/slashdot-journal-110984-i-still-hate-sundays/"/>
        <id>https://0x5.uk/2005/07/03/slashdot-journal-110984-i-still-hate-sundays/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/07/03/slashdot-journal-110984-i-still-hate-sundays/">&lt;p&gt;having worked another six day week, I discover that I now can&#x27;t do anything I had to do on my day off. Namely involving post office for ebay (shut), barclays for a new account (shut) and registering at the health centre (open 9-5 mon-fri, which is no frickin good at all). piss. guess I&#x27;ll just go buy shoes at the oracle cos that&#x27;s all that&#x27;s open. maybe I&#x27;ll try to move my hours to work sunday. not.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Java!=javascript (geek entry)</title>
        <published>2005-06-30T00:00:00+00:00</published>
        <updated>2005-06-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/06/30/slashdot-journal-110732-javajavascript-geek-entry/"/>
        <id>https://0x5.uk/2005/06/30/slashdot-journal-110732-javajavascript-geek-entry/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/06/30/slashdot-journal-110732-javajavascript-geek-entry/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.vsj.co.uk&#x2F;dotnet&#x2F;display.asp?id=296&quot;&gt;http:&#x2F;&#x2F;www.vsj.co.uk&#x2F;dotnet&#x2F;display.asp?id=296&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Just goes to show you can have a degree &lt;i&gt;and&lt;&#x2F;i&gt; an MCSD and &lt;i&gt;still&lt;&#x2F;i&gt; not know the difference between Java and javascript!&lt;&#x2F;p&gt;
&lt;p&gt;(see section &quot;Whistles and Bells&quot;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>eBay &#x2F; iRiver</title>
        <published>2005-06-23T00:00:00+00:00</published>
        <updated>2005-06-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/06/23/slashdot-journal-110112-ebay--iriver/"/>
        <id>https://0x5.uk/2005/06/23/slashdot-journal-110112-ebay--iriver/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/06/23/slashdot-journal-110112-ebay--iriver/">&lt;p&gt;Gosh I really was annoyed on sunday!&lt;&#x2F;p&gt;
&lt;p&gt;Having said all that, buy my stuff on eBay (again)!&lt;br&gt;I&#x27;ll figure out an alternative another day, but it&#x27;s gonna be tricky when eBay have market share and a fat advertising budget.&lt;br&gt;Never trust a company with a large advertising budget, they tend to discover advertising budget has a better ROI than investing in the product, motivating staff, providing customer support etc etc.&lt;&#x2F;p&gt;
&lt;p&gt;In other news, the new iRiver H10 looks nice but appears to be missing all of the advatages of the older H300. Damn. Thought it was about to kick iPod&#x27;s shiny backside.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;search.ebay.co.uk&#x2F;_W0QQfgtpZ1QQfrppZ25QQsassZtimQ5fabell&quot;&gt;http:&#x2F;&#x2F;search.ebay.co.uk&#x2F;_W0QQfgtpZ1QQfrppZ25QQsassZtimQ5fabell&lt;&#x2F;a&gt;&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.iriver.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.iriver.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>firefox bookmark synch extension</title>
        <published>2005-06-23T00:00:00+00:00</published>
        <updated>2005-06-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/06/23/slashdot-journal-110184-firefox-bookmark-synch-extension/"/>
        <id>https://0x5.uk/2005/06/23/slashdot-journal-110184-firefox-bookmark-synch-extension/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/06/23/slashdot-journal-110184-firefox-bookmark-synch-extension/">&lt;p&gt;after an earlier post saying the synchroniser was broken on firefox 1.0.4 (which it was!) it appears to have mysteriously started working again.&lt;br&gt;I&#x27;m not aware of having perfoermed any updates.&lt;&#x2F;p&gt;
&lt;p&gt;wierd.&lt;&#x2F;p&gt;
&lt;p&gt;so in short;&lt;br&gt;the bookmarks on timwise.co.uk will be up to date once more.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I hate ebay because...</title>
        <published>2005-06-12T00:00:00+00:00</published>
        <updated>2005-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/06/12/slashdot-journal-109161-i-hate-ebay-because/"/>
        <id>https://0x5.uk/2005/06/12/slashdot-journal-109161-i-hate-ebay-because/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/06/12/slashdot-journal-109161-i-hate-ebay-because/">&lt;ul&gt; &lt;li&gt;their website is soooo slow.&lt;&#x2F;li&gt;
&lt;li&gt;You can&#x27;t change a listing in the last  24hrs, but there&#x27;s nothing to say so&lt;&#x2F;li&gt;
&lt;li&gt;You can&#x27;t see anything before 60 days ago&lt;&#x2F;li&gt;
&lt;li&gt;You can&#x27;t change your invoices if you make a mistake&lt;&#x2F;li&gt;
&lt;li&gt;they really stress me out every time i try to use their stupid website.&lt;&#x2F;li&gt;
&lt;li&gt;the whole thing is really counter intuitive&lt;&#x2F;li&gt;
&lt;li&gt;there is no competition, so they can be as shit as they want and people will still use it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&#x2F; unashamed rant&lt;&#x2F;p&gt;
&lt;p&gt;Ps I&#x27;ve had a shitty cold for the last few days.&lt;br&gt;Yes, I&#x27;m currently a bad mood bear. Did I mention I hate sundays too? Why does everything shut by the time I&#x27;m up? (4pm) If they&#x27;ve even bothered opening at all.&lt;&#x2F;p&gt;
&lt;p&gt;Someone find me a beer.&lt;&#x2F;p&gt;
&lt;p&gt;edit:&lt;br&gt;ok, having read this&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;forums.ebay.com&#x2F;db2&#x2F;thread.jspa?threadID=2231811&amp;amp;tstart=0&amp;amp;mod=1114654773979&quot;&gt;http:&#x2F;&#x2F;forums.ebay.com&#x2F;db2&#x2F;thread.jspa?threadID=2231811&amp;amp;tstart=0&amp;amp;mod=1114654773979&lt;&#x2F;a&gt;&lt;br&gt;I&#x27;m never using ebay again. [expletive deleted].&lt;&#x2F;p&gt;
&lt;p&gt;by the way, the reason i&#x27;m so pissed is that they&#x27;ve charged me for two listings which I NEVER GOT PAYMENT FOR. [expletive deleted]&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>and paypal aren&#x27;t looking too hot</title>
        <published>2005-06-12T00:00:00+00:00</published>
        <updated>2005-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/06/12/slashdot-journal-109166-and-paypal-arent-looking-too-hot/"/>
        <id>https://0x5.uk/2005/06/12/slashdot-journal-109166-and-paypal-arent-looking-too-hot/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/06/12/slashdot-journal-109166-and-paypal-arent-looking-too-hot/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.paypalsucks.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.paypalsucks.com&#x2F;&lt;&#x2F;a&gt;&lt;br&gt;erk, think I&#x27;ll extract my money pronto&lt;br&gt;I shall be looking into these alternatives: Amazon,Yahoo,Onsale,2good2toss&lt;&#x2F;p&gt;
&lt;p&gt;Really it seems where ever you go there are scare stories. I&#x27;ve heard of cahoot freezing an account without good reason and being really shit about it when contacted. The whole thing makes me want to keep my cash under the mattress.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Pay as you drive won&#x27;t work because...</title>
        <published>2005-06-06T00:00:00+00:00</published>
        <updated>2005-06-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/06/06/slashdot-journal-108638-pay-as-you-drive-wont-work-because/"/>
        <id>https://0x5.uk/2005/06/06/slashdot-journal-108638-pay-as-you-drive-wont-work-because/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/06/06/slashdot-journal-108638-pay-as-you-drive-wont-work-because/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;uk&#x2F;4610755.stm&quot;&gt;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;uk&#x2F;4610755.stm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;People won&#x27;t fit tracking devices to existing cars - especially if they have to pay for them&lt;&#x2F;li&gt;
&lt;li&gt;Cost of driving is only a dis-incentive if known in advance of the journey.&lt;&#x2F;li&gt;
&lt;li&gt;etc.&lt;&#x2F;li&gt;
&lt;li&gt;rant. grrr.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;edit: more thoughts&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if motorways are higher cost, large vehicles will use A &amp;amp; B roads instead, which is bad for cyclists.&lt;&#x2F;li&gt;
&lt;li&gt;why is congestion such a bad thing anyway? isn&#x27;t it the best incentive for people to seek alternative methods of transport?&lt;&#x2F;li&gt;
&lt;li&gt;why is this any better than the current tax per mile, aka fuel tax? I think perhaps this is a reaction to the revolt against fuel tax rises.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you want to reduce congestion, then apart from sudafed, the best example I&#x27;ve seen is the M25 variable (enforced) speed limit. I&#x27;d be more than happy to see this extended to all motorways.&lt;&#x2F;p&gt;
&lt;p&gt;As usual without decent alternatives reducing congestion is a losing battle. Have you taken a regional bus &#x2F; train service lately? My most recent experience was the Woodley to Reading bus, which took at least half an hour (when it eventually showed up) for a journey I can do in 15 mins on my mountain bike. Add to that no guarantee of a ride home after a few beers and frankly I&#x27;d rather drive and put up with ten minutes in traffic.&lt;&#x2F;p&gt;
&lt;p&gt;grrrr.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe I shouldn&#x27;t listen to the news. Besides, b3ta.com is funnier.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>how to destroy the earth</title>
        <published>2005-06-03T00:00:00+00:00</published>
        <updated>2005-06-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/06/03/slashdot-journal-108484-how-to-destroy-the-earth/"/>
        <id>https://0x5.uk/2005/06/03/slashdot-journal-108484-how-to-destroy-the-earth/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/06/03/slashdot-journal-108484-how-to-destroy-the-earth/">&lt;p&gt;settle in. it&#x27;s a long read...&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;ned.ucam.org&#x2F;~sdh31&#x2F;misc&#x2F;destroy.html&quot;&gt;http:&#x2F;&#x2F;ned.ucam.org&#x2F;~sdh31&#x2F;misc&#x2F;destroy.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;link courtesy of the b3ta newsletter&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>google funds open source development</title>
        <published>2005-06-02T00:00:00+00:00</published>
        <updated>2005-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/06/02/slashdot-journal-108390-google-funds-open-source-development/"/>
        <id>https://0x5.uk/2005/06/02/slashdot-journal-108390-google-funds-open-source-development/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/06/02/slashdot-journal-108390-google-funds-open-source-development/">&lt;p&gt;This is a welcome boost for open source.&lt;br&gt;Shame i&#x27;m no longer a student.&lt;&#x2F;p&gt;
&lt;p&gt;-------- Original Message --------&lt;br&gt;Subject:     Google sponsors Nmap summer student developers&lt;br&gt;Date:     Thu, 2 Jun 2005 02:56:52 -0700&lt;br&gt;From:     Fyodor &lt;br&gt;To:     nmap-hackers@insecure.org&lt;&#x2F;p&gt;
&lt;p&gt;Hello everyone,&lt;&#x2F;p&gt;
&lt;p&gt;Yesterday, Google announced their first Summer of Code program. This&lt;br&gt;innovative and generous program provides $4,500 stipends to each of&lt;br&gt;200 university students to create or enhance open source software&lt;br&gt;during their summer break.  I am pleased to announce that Nmap is one&lt;br&gt;of 40 open source projects that Google selected for this program.  We&lt;br&gt;would be pleased to work with one or more students to extend the power&lt;br&gt;of Nmap.  You get paid, gain valuable experience and a great resume&lt;br&gt;booster, while the Nmap project and users benefit from your valuable&lt;br&gt;contributions.&lt;&#x2F;p&gt;
&lt;p&gt;You have until June 14 to apply if you are interested, though your&lt;br&gt;chances may be better if you apply sooner.  If you do fill out the&lt;br&gt;application, please also send me the project description and a brief&lt;br&gt;bio describing how your experience fits the project.  Also let me know&lt;br&gt;what school you attend.  I have written up some project ideas, though&lt;br&gt;you are free to submit whatever cool idea your heart desires.&lt;&#x2F;p&gt;
&lt;p&gt;Here are the relevant URLs:&lt;&#x2F;p&gt;
&lt;p&gt;Nmap Project Ideas:  &lt;a href=&quot;http:&#x2F;&#x2F;www.insecure.org&#x2F;nmap&#x2F;GoogleGrants.html&quot;&gt;http:&#x2F;&#x2F;www.insecure.org&#x2F;nmap&#x2F;GoogleGrants.html&lt;&#x2F;a&gt;&lt;br&gt;Google&#x27;s Summer of Code Page: &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;summerofcode.html&quot;&gt;http:&#x2F;&#x2F;code.google.com&#x2F;summerofcode.html&lt;&#x2F;a&gt;&lt;br&gt;Participant FAQ: &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;summfaq.html&quot;&gt;http:&#x2F;&#x2F;code.google.com&#x2F;summfaq.html&lt;&#x2F;a&gt;&lt;br&gt;Application Form: &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;soc_application.html&quot;&gt;http:&#x2F;&#x2F;code.google.com&#x2F;soc_application.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Good luck!&lt;br&gt;-Fyodor&lt;&#x2F;p&gt;
&lt;p&gt;_______________________________________________&lt;br&gt;Sent through the nmap-hackers mailing list&lt;br&gt;http:&#x2F;&#x2F;cgi.insecure.org&#x2F;mailman&#x2F;listinfo&#x2F;nmap-hackers&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>waaaah!</title>
        <published>2005-05-31T00:00:00+00:00</published>
        <updated>2005-05-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/05/31/slashdot-journal-108203-waaaah/"/>
        <id>https://0x5.uk/2005/05/31/slashdot-journal-108203-waaaah/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/05/31/slashdot-journal-108203-waaaah/">&lt;p&gt;firefox 1.0.4 broke my favourite extension, the bookmark synchronizer.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:(&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What&#x27;s your political persuasion?</title>
        <published>2005-05-25T00:00:00+00:00</published>
        <updated>2005-05-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/05/25/slashdot-journal-107738-whats-your-political-persuasion/"/>
        <id>https://0x5.uk/2005/05/25/slashdot-journal-107738-whats-your-political-persuasion/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/05/25/slashdot-journal-107738-whats-your-political-persuasion/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.theadvocates.org&#x2F;quiz.html&quot;&gt;http:&#x2F;&#x2F;www.theadvocates.org&#x2F;quiz.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m a liberal lefty. (Surprise)&lt;&#x2F;p&gt;
&lt;p&gt;Post your answers as replies to this post&lt;nobr&gt; &lt;&#x2F;nobr&gt;:-)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>some things I&#x27;m happy about</title>
        <published>2005-05-23T00:00:00+00:00</published>
        <updated>2005-05-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/05/23/slashdot-journal-107567-some-things-im-happy-about/"/>
        <id>https://0x5.uk/2005/05/23/slashdot-journal-107567-some-things-im-happy-about/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/05/23/slashdot-journal-107567-some-things-im-happy-about/">&lt;p&gt;I cycled to work every day since Wednesday. That&#x27;s 4 days now&lt;nobr&gt; &lt;&#x2F;nobr&gt;:) and 72 miles. Also have all the right clips for pump etc now.&lt;&#x2F;p&gt;
&lt;p&gt;Really getting stuck into new project at work, which is good.&lt;&#x2F;p&gt;
&lt;p&gt;Really getting stuck into Linux at home (mostly &lt;a href=&quot;http:&#x2F;&#x2F;fedora.redhat.com&#x2F;&quot;&gt;fedora&lt;&#x2F;a&gt;). Currently trying to figure out what I&#x27;ve done wrong on my attempt at a samba share.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m also making quite a good attempt at keeping &lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;synch&#x2F;xbel.xml&quot;&gt;my bookmarks&lt;&#x2F;a&gt; up to date, and adding new stuff. (link from &lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;&quot;&gt;timwise&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;If you had noticed (unlikely) that my stats pages and are down and that the full size photos are missing it&#x27;s because the little old laptop I&#x27;ve been running them on got hacked and I haven&#x27;t fixed it yet. That&#x27;ll teach me for lapsing on updates! I&#x27;ll probably post interesting details of what I find when I get around to analysing the machine.&lt;&#x2F;p&gt;
&lt;p&gt;x&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>more raucous laughter</title>
        <published>2005-05-17T00:00:00+00:00</published>
        <updated>2005-05-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/05/17/slashdot-journal-107007-more-raucous-laughter/"/>
        <id>https://0x5.uk/2005/05/17/slashdot-journal-107007-more-raucous-laughter/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/05/17/slashdot-journal-107007-more-raucous-laughter/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.turnoffyourtv.com&#x2F;international&#x2F;bbc.havealifead.jpg&quot;&gt;http:&#x2F;&#x2F;www.turnoffyourtv.com&#x2F;international&#x2F;bbc.havealifead.jpg&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;my sentiments precisely&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>unblocked!</title>
        <published>2005-05-13T00:00:00+00:00</published>
        <updated>2005-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/05/13/slashdot-journal-106732-unblocked/"/>
        <id>https://0x5.uk/2005/05/13/slashdot-journal-106732-unblocked/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/05/13/slashdot-journal-106732-unblocked/">&lt;p&gt;finally, I can post messages from home,&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;. have finally removed the block on nthell&#x27;s proxy.&lt;&#x2F;p&gt;
&lt;p&gt;more posts will now follow.&lt;&#x2F;p&gt;
&lt;p&gt;In the mean time, have you seen my bookmarks?&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;&quot;&gt;timwise.co.uk&lt;&#x2F;a&gt; &amp;gt; bookmarks.&lt;&#x2F;p&gt;
&lt;p&gt;swimming? nope, haven&#x27;t been for ages, will do soon. played badminton the other week though.&lt;&#x2F;p&gt;
&lt;p&gt;Don&#x27;t forget to come and meet Sophie if you haven&#x27;t already.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:D&lt;&#x2F;p&gt;
&lt;p&gt;cheers tom &#x27;n kev for keepin up the flow.&lt;&#x2F;p&gt;
&lt;p&gt;x&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>pointless acronyms</title>
        <published>2005-05-13T00:00:00+00:00</published>
        <updated>2005-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/05/13/slashdot-journal-106752-pointless-acronyms/"/>
        <id>https://0x5.uk/2005/05/13/slashdot-journal-106752-pointless-acronyms/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/05/13/slashdot-journal-106752-pointless-acronyms/">&lt;p&gt;to celebrate being unblocked, here&#x27;s a list of interesting acronyms of &quot;timothy abell&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Hot Meaty Bill&lt;br&gt;I&#x27;m the tall boy&lt;br&gt;Ah be tit molly&lt;br&gt;Ah ibm to telly&lt;br&gt;Toby a h millet&lt;br&gt;Thai be my toll&lt;br&gt;Hallo im betty&lt;br&gt;My halo be tilt&lt;br&gt;Bye to ill math&lt;br&gt;Let my hat boil&lt;br&gt;Bet i&#x27;m thy lola&lt;br&gt;Thy lola bit me!&lt;br&gt;Totally be him&lt;br&gt;Me hit tall boy&lt;br&gt;Lay the to limb&lt;br&gt;Am bill the toy&lt;&#x2F;p&gt;
&lt;p&gt;So there.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>laughing my behind off!</title>
        <published>2005-05-13T00:00:00+00:00</published>
        <updated>2005-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/05/13/slashdot-journal-106757-laughing-my-behind-off/"/>
        <id>https://0x5.uk/2005/05/13/slashdot-journal-106757-laughing-my-behind-off/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/05/13/slashdot-journal-106757-laughing-my-behind-off/">&lt;p&gt;Here&#x27;s &lt;a href=&quot;http:&#x2F;&#x2F;slashdot.org&#x2F;comments.pl?sid=147501&amp;amp;cid=12359432&quot;&gt;a reminder&lt;&#x2F;a&gt; to log off.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>April showers came early. MS vendor lock in.</title>
        <published>2005-03-31T00:00:00+00:00</published>
        <updated>2005-03-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/03/31/slashdot-journal-102509-april-showers-came-early-ms-vendor-lock-in/"/>
        <id>https://0x5.uk/2005/03/31/slashdot-journal-102509-april-showers-came-early-ms-vendor-lock-in/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/03/31/slashdot-journal-102509-april-showers-came-early-ms-vendor-lock-in/">&lt;p&gt;So, I went to the pub last night with my neighbour, which was nice. And we went on our bikes, which was nice. And we had a couple of drinks, which was nice. And we went outside to go home, and it was pouring with rain, which was interesting. So we got soaked.&lt;&#x2F;p&gt;
&lt;p&gt;Going to an MSDN evening later. Bit of professional development.&lt;&#x2F;p&gt;
&lt;p&gt;On another topic, it occurs to me that the standard practice in Microsoft.NET is to write software that only runs with MSSQL, this means there is starting to be a lot of code available that won&#x27;t run on anything else. I imagine there are potential optimisations from writing specifically for ms sql, but I can&#x27;t help thinking that it is a typical ms vendor lock in. Whether it was a conscious decision to make this the default or not I couldn&#x27;t say and don&#x27;t really care, the end result is the same. Take a look on codeproject and see how many projects say &quot;only runs with ms sql&quot;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>shock! timwise.co.uk home page updated!</title>
        <published>2005-03-18T00:00:00+00:00</published>
        <updated>2005-03-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/03/18/slashdot-journal-101268-shock-timwisecouk-home-page-updated/"/>
        <id>https://0x5.uk/2005/03/18/slashdot-journal-101268-shock-timwisecouk-home-page-updated/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/03/18/slashdot-journal-101268-shock-timwisecouk-home-page-updated/">&lt;p&gt;About time too.&lt;&#x2F;p&gt;
&lt;p&gt;You can now see my complete set of browser bookmarks from my website. Pretty much updated daily.&lt;br&gt;Still a lot of tidying up to do as I&#x27;ve just shoved all my disparate bookmarks together. It&#x27;s done with a bookmark synching extension for firefox, and it allows to keep all my bookmarks the same across computers &#x2F; OSs profiles.&lt;&#x2F;p&gt;
&lt;p&gt;By the way, if you aren&#x27;t already using it, then you really should give firefox a go. You&#x27;ll never look back.&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.mozilla.org&#x2F;products&#x2F;firefox&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.mozilla.org&#x2F;products&#x2F;firefox&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Anything new your end?&lt;&#x2F;p&gt;
&lt;p&gt;My bebo contact details:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.bebo.com&#x2F;friends&#x2F;138748a653587b22&quot;&gt;http:&#x2F;&#x2F;www.bebo.com&#x2F;friends&#x2F;138748a653587b22&lt;&#x2F;a&gt;&lt;br&gt;&quot;I am using a new service to keep in contact with my friends. Use the link [above] to become part of my address book. In the future I will be able to see any changes in your contact details.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>new year? when was that?</title>
        <published>2005-03-08T00:00:00+00:00</published>
        <updated>2005-03-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/03/08/slashdot-journal-100287-new-year-when-was-that/"/>
        <id>https://0x5.uk/2005/03/08/slashdot-journal-100287-new-year-when-was-that/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/03/08/slashdot-journal-100287-new-year-when-was-that/">&lt;p&gt;I wasn&#x27;t there, I know nothing about it.&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;timwise.co.uk&#x2F;photos&#x2F;newyear05&#x2F;&quot;&gt;http:&#x2F;&#x2F;timwise.co.uk&#x2F;photos&#x2F;newyear05&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ebay - buy my stuff</title>
        <published>2005-03-07T00:00:00+00:00</published>
        <updated>2005-03-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/03/07/slashdot-journal-100196-ebay---buy-my-stuff/"/>
        <id>https://0x5.uk/2005/03/07/slashdot-journal-100196-ebay---buy-my-stuff/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/03/07/slashdot-journal-100196-ebay---buy-my-stuff/">&lt;p&gt;I am currently selling my prized posessions on eBay.&lt;&#x2F;p&gt;
&lt;ul&gt; &lt;li&gt;cd player&lt;&#x2F;li&gt;
&lt;li&gt;barbells (not mine)&lt;&#x2F;li&gt;
&lt;li&gt;scanner&lt;&#x2F;li&gt;
&lt;li&gt;washing machine!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;search.ebay.co.uk&#x2F;_W0QQfgtpZ1QQfrppZ25QQsassZtimQ5fabell&quot;&gt;tim_abell&#x27;s items on eBay&lt;&#x2F;a&gt;&lt;br&gt;No-one&#x27;s bid yet so it&#x27;s bargain basement prices!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>email security &#x2F; lack of</title>
        <published>2005-01-25T00:00:00+00:00</published>
        <updated>2005-01-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/01/25/slashdot-journal-96534-email-security--lack-of/"/>
        <id>https://0x5.uk/2005/01/25/slashdot-journal-96534-email-security--lack-of/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/01/25/slashdot-journal-96534-email-security--lack-of/">&lt;p&gt;I will soon start digitally signing my email for reasons similar to this:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.linuxmafia.com&#x2F;~rick&#x2F;linux-info&#x2F;rant-gpg&quot;&gt;http:&#x2F;&#x2F;www.linuxmafia.com&#x2F;~rick&#x2F;linux-info&#x2F;rant-gpg&lt;&#x2F;a&gt;&lt;br&gt;If it bothers you then I may send you copies of the included rant. And if you don&#x27;t like it then you will lose your right to complain when someone sends email spoofed from your address&lt;nobr&gt; &lt;&#x2F;nobr&gt;:-)&lt;&#x2F;p&gt;
&lt;p&gt;If you want a good alarm clock &#x2F; hifi I can recommend my latest &lt;a href=&quot;http:&#x2F;&#x2F;cgi.ebay.co.uk&#x2F;ws&#x2F;eBayISAPI.dll?ViewItem&amp;amp;rd=1&amp;amp;item=5746472812&amp;amp;ssPageName=STRK:MESE:IT&quot;&gt;eBay listing&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
&lt;p&gt;PS.&lt;&#x2F;p&gt;
&lt;p&gt;Grrrrrrrrrrr.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>update</title>
        <published>2005-01-18T00:00:00+00:00</published>
        <updated>2005-01-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2005/01/18/slashdot-journal-95908-update/"/>
        <id>https://0x5.uk/2005/01/18/slashdot-journal-95908-update/</id>
        
        <content type="html" xml:base="https://0x5.uk/2005/01/18/slashdot-journal-95908-update/">&lt;p&gt;dittons: sold&lt;br&gt;ntl proxy: banned from slashdot - so I shalln&#x27;t be posting very often.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:(&lt;&#x2F;p&gt;
&lt;p&gt;Everyone should now use Bebo, it&#x27;s just what the doctor ordered.&lt;br&gt;You can get my new address and my mob number here:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.bebo.com&#x2F;friends&#x2F;138748a653587b0&quot;&gt;http:&#x2F;&#x2F;www.bebo.com&#x2F;friends&#x2F;138748a653587b0&lt;&#x2F;a&gt;&lt;br&gt;(but only if you give me yours!)&lt;&#x2F;p&gt;
&lt;p&gt;Description: &quot;I am using a service that keeps contact details current, just update your own contact details and then the changes appear in selected friends address books. When I update my contact details you will see them in your address book.&quot;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>let the selling begin</title>
        <published>2004-12-27T00:00:00+00:00</published>
        <updated>2004-12-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/12/27/slashdot-journal-94011-let-the-selling-begin/"/>
        <id>https://0x5.uk/2004/12/27/slashdot-journal-94011-let-the-selling-begin/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/12/27/slashdot-journal-94011-let-the-selling-begin/">&lt;p&gt;I&#x27;ve made my first &lt;a href=&quot;http:&#x2F;&#x2F;cgi.ebay.co.uk&#x2F;ws&#x2F;eBayISAPI.dll?ViewItem&amp;amp;item=5740624016&amp;amp;ssPageName=ADME:B:LC:UK:1&quot;&gt;ebay entry&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s for those gargantuan Dittons that I don&#x27;t have room for. Let me know if you know anyone who might be interested.&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>i don&#x27;t do forwards</title>
        <published>2004-12-25T00:00:00+00:00</published>
        <updated>2004-12-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/12/25/slashdot-journal-93877-i-dont-do-forwards/"/>
        <id>https://0x5.uk/2004/12/25/slashdot-journal-93877-i-dont-do-forwards/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/12/25/slashdot-journal-93877-i-dont-do-forwards/">&lt;p&gt;... but this is a classic&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;community-2.webtv.net&#x2F;@HH!3B!01!109A6273ED6D&#x2F;Babajani1&#x2F;MurphysLaw&#x2F;&quot;&gt;http:&#x2F;&#x2F;community-2.webtv.net&#x2F;@HH!3B!01!109A6273ED6D&#x2F;Babajani1&#x2F;MurphysLaw&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;oh, and merry xmas.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>moved</title>
        <published>2004-12-23T00:00:00+00:00</published>
        <updated>2004-12-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/12/23/slashdot-journal-93713-moved/"/>
        <id>https://0x5.uk/2004/12/23/slashdot-journal-93713-moved/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/12/23/slashdot-journal-93713-moved/">&lt;p&gt;Glad that&#x27;s over.&lt;br&gt;I&#x27;ve moved now. And am still super busy. Life is good though.&lt;br&gt;Left office at 10.30 last night having repatched the network. Then I cleaned the fridge and fixed a few cupboards!&lt;br&gt;Today I have been mostly driving a W-Reg Fiat Uno, which is amusing. (My car failed MOT on its horn.)&lt;&#x2F;p&gt;
&lt;p&gt;Merry xmas one and all, and as Kev said, hope to see you at new year. I think we&#x27;re having curry in the office today to celebrate, which I&#x27;m looking forward to.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>busy</title>
        <published>2004-11-30T00:00:00+00:00</published>
        <updated>2004-11-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/11/30/slashdot-journal-91683-busy/"/>
        <id>https://0x5.uk/2004/11/30/slashdot-journal-91683-busy/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/11/30/slashdot-journal-91683-busy/">&lt;p&gt;i&#x27;ve been real busy lately with rehearsals etc. I&#x27;m moving house soon so gis&#x27; a shout on the old email if you want me new address.&lt;&#x2F;p&gt;
&lt;p&gt;For anyone who doesn&#x27;t know ants is likely to be out of the country soon, call me &#x2F; her for details&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>xmas flash animation</title>
        <published>2004-11-15T00:00:00+00:00</published>
        <updated>2004-11-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/11/15/slashdot-journal-90420-xmas-flash-animation/"/>
        <id>https://0x5.uk/2004/11/15/slashdot-journal-90420-xmas-flash-animation/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/11/15/slashdot-journal-90420-xmas-flash-animation/">&lt;p&gt;just call me dave. [grin]&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;homepage.ntlworld.com&#x2F;david.davies527&#x2F;sheep&#x2F;sheepanims&#x2F;cardxmas2003.htm&quot;&gt;http:&#x2F;&#x2F;homepage.ntlworld.com&#x2F;david.davies527&#x2F;sheep&#x2F;sheepanims&#x2F;cardxmas2003.htm&lt;&#x2F;a&gt;&lt;br&gt;i like it. go look at his other stuff.&lt;&#x2F;p&gt;
&lt;p&gt;Today I went to work, which was novel, having been laid up after the tooth extraction thingy. I was starting to forget what I went for. It&#x27;s definitely more interesting than being at home watching the spiders decorate my house in preparation for christmas. Not that I was, but the comparison is still valid.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>why am i here</title>
        <published>2004-11-13T00:00:00+00:00</published>
        <updated>2004-11-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/11/13/slashdot-journal-90243-why-am-i-here/"/>
        <id>https://0x5.uk/2004/11/13/slashdot-journal-90243-why-am-i-here/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/11/13/slashdot-journal-90243-why-am-i-here/">&lt;p&gt;From the dnrc newsletter. Say bye bye to your eyes for reading this, especially here in my &quot;blog&quot;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;div&gt;
&lt;p&gt; &lt;i&gt;&lt;br&gt;Dear Dogbert,&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Lots of people write blogs, but I&#x27;ve never heard of anyone who actually reads them. What&#x27;s up with that?&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Kurt&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Dear Skirt,&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Blogs exist to fill the important market niche of writing that is so dull that your eyes will burrow out of the back of your head to escape. People do read blogs, usually by accident, sometimes on a dare, but those readers are later mistaken for Mafia victims with what appears to be two holes in the back of their heads. On closer inspection, you might find their eyeballs clinging to the drapes directly behind them. Unless the cat gets them first.&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Sincerely,&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Dogbert&lt;br&gt;&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt; &lt;&#x2F;blockquote&gt;
&lt;p&gt;In other news I feel like a complete c*** today.&lt;br&gt;Where is everybody?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Urgh. Not such a toothy grin now.</title>
        <published>2004-11-12T00:00:00+00:00</published>
        <updated>2004-11-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/11/12/slashdot-journal-90179-urgh-not-such-a-toothy-grin-now/"/>
        <id>https://0x5.uk/2004/11/12/slashdot-journal-90179-urgh-not-such-a-toothy-grin-now/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/11/12/slashdot-journal-90179-urgh-not-such-a-toothy-grin-now/">&lt;p&gt;Had two bottom wisdom teeth extracted on Tuesday and am still recovering. Don&#x27;t think I&#x27;ll post a pic, wouldn&#x27;t want to scare the children! Thanks to my friends in reading for looking after me while I was woozy! Back to my soup now.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve just booked tickets for this &lt;a href=&quot;http:&#x2F;&#x2F;www.delicatessen-reading.org.uk&#x2F;&quot;&gt;Martyn Joseph&lt;&#x2F;a&gt;. Let me know if your gonna come too (£10).&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Weekend</title>
        <published>2004-11-08T00:00:00+00:00</published>
        <updated>2004-11-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/11/08/slashdot-journal-89748-weekend/"/>
        <id>https://0x5.uk/2004/11/08/slashdot-journal-89748-weekend/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/11/08/slashdot-journal-89748-weekend/">&lt;p&gt;Went to Cambridge and relaxed.&lt;br&gt;Was great.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;4A5E0007.jpg&quot;&gt;photo&lt;&#x2F;a&gt; at top of church tower. (Taken with my new toy&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>workworkworkworkworkworkwork...</title>
        <published>2004-11-04T00:00:00+00:00</published>
        <updated>2004-11-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/11/04/slashdot-journal-89346-workworkworkworkworkworkwork/"/>
        <id>https://0x5.uk/2004/11/04/slashdot-journal-89346-workworkworkworkworkworkwork/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/11/04/slashdot-journal-89346-workworkworkworkworkworkwork/">&lt;p&gt;lately I have been mostly writing this website:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.emapsite.com&#x2F;streetsahead&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.emapsite.com&#x2F;streetsahead&#x2F;&lt;&#x2F;a&gt;&lt;br&gt;I worked all weekend and am stretched to the limit, cos tomorrow will be the 13th day of work on the trot without a break.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve managed to get fedora running nicely on my main box now, up2date and add&#x2F;remove took a while to get working, and they seem to have removed mozilla&#x27;s built in mail client in favour of evolution (and thunderbird).&lt;br&gt;I look forward to becoming a hardened linux hacker. Don&#x27;t suppose any of you know if subversion is as good as the promotional material says it is do you?&lt;&#x2F;p&gt;
&lt;p&gt;Once again, I still need to find people who are looking for a place in Reading, if you know anyone then put them in touch with me.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m quite pleased with the progress of the online &lt;a href=&quot;http:&#x2F;&#x2F;slashdot.org&#x2F;~tim_abell&#x2F;friends&quot;&gt;friends list&lt;&#x2F;a&gt;. I&#x27;d really like everyone to be part of this network. Everyone say a big hello to our new addition Chris (old friend from back in the dayz!)&lt;&#x2F;p&gt;
&lt;p&gt;Did I mention how much I dislike clothes washing? I&#x27;ve got to hang it all up now. _sigh_&lt;&#x2F;p&gt;
&lt;p&gt;L8r&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mmmm cake</title>
        <published>2004-11-01T00:00:00+00:00</published>
        <updated>2004-11-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/11/01/slashdot-journal-88851-mmmm-cake/"/>
        <id>https://0x5.uk/2004/11/01/slashdot-journal-88851-mmmm-cake/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/11/01/slashdot-journal-88851-mmmm-cake/">&lt;p&gt;I&#x27;ve got the first cake I&#x27;ve ever made in the oven right now.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:D&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been flat out with work for ages and am knackered. I still haven&#x27;t managed to get all my clocks running on GMT yet. I arrived in an empty field an hour early on Sunday - doh!&lt;&#x2F;p&gt;
&lt;p&gt;Does anyone know of anyone looking to share a place in Reading?&lt;&#x2F;p&gt;
&lt;p&gt;I got a childrens book in my shreddies the other day. At first I thought bah, humbug, another irritating marketing tactic. But now I&#x27;ve finished the cereal, and extracted the book from the packaging and am enjoying it! I guess it&#x27;s inifitely better than the biodegrade-proof waste of hydrocarbons they normally include.&lt;&#x2F;p&gt;
&lt;p&gt;Oooh, five mins till my cake&#x27;s done.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;br&gt;It&#x27;s risen...&lt;br&gt;I&#x27;ll let you know how it tastes.&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mourn</title>
        <published>2004-10-26T00:00:00+00:00</published>
        <updated>2004-10-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/10/26/slashdot-journal-88222-mourn/"/>
        <id>https://0x5.uk/2004/10/26/slashdot-journal-88222-mourn/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/10/26/slashdot-journal-88222-mourn/">&lt;p&gt;It is truly a sad day for music today.&lt;br &#x2F;&gt;
The king of radio is dead.&lt;&#x2F;p&gt;
&lt;p&gt;This leaves a gap in my life.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Edit: John Peel who I listened to with great joy died on 25th Oct 2004 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;peel.fandom.com&#x2F;wiki&#x2F;26_October_2004&quot;&gt;https:&#x2F;&#x2F;peel.fandom.com&#x2F;wiki&#x2F;26_October_2004&lt;&#x2F;a&gt;. I must have been listening to the show he would have been on that day.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>b3ta teddy</title>
        <published>2004-10-24T00:00:00+00:00</published>
        <updated>2004-10-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/10/24/slashdot-journal-87958-b3ta-teddy/"/>
        <id>https://0x5.uk/2004/10/24/slashdot-journal-87958-b3ta-teddy/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/10/24/slashdot-journal-87958-b3ta-teddy/">&lt;p&gt;this is great&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.parachutingtrees.co.uk&#x2F;rushmore.htm&quot;&gt;http:&#x2F;&#x2F;www.parachutingtrees.co.uk&#x2F;rushmore.htm&lt;&#x2F;a&gt;&lt;br&gt;sound required&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>woo!</title>
        <published>2004-10-17T00:00:00+00:00</published>
        <updated>2004-10-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/10/17/slashdot-journal-87160-woo/"/>
        <id>https://0x5.uk/2004/10/17/slashdot-journal-87160-woo/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/10/17/slashdot-journal-87160-woo/">&lt;p&gt;b3ta postage.&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.b3ta.com&#x2F;board&#x2F;3836198&quot;&gt;http:&#x2F;&#x2F;www.b3ta.com&#x2F;board&#x2F;3836198&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;nobr&gt; &lt;&#x2F;nobr&gt;:D&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>website stats</title>
        <published>2004-10-16T00:00:00+00:00</published>
        <updated>2004-10-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/10/16/slashdot-journal-87126-website-stats/"/>
        <id>https://0x5.uk/2004/10/16/slashdot-journal-87126-website-stats/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/10/16/slashdot-journal-87126-website-stats/">&lt;p&gt;apologies to anyone who had noticed &lt;a href=&quot;http:&#x2F;&#x2F;timwise.dyndns.org&#x2F;awstats&#x2F;awstats.pl?config=timwise&amp;amp;configdir=&#x2F;etc&#x2F;awstats&quot;&gt;my stats&lt;&#x2F;a&gt; have been offline since sep 24th.&lt;&#x2F;p&gt;
&lt;p&gt;I had a power failure which upset my linux server &#x2F; knackered old laptop (no battery!), I had to &lt;a href=&quot;http:&#x2F;&#x2F;awstats.sourceforge.net&#x2F;docs&#x2F;awstats_faq.html#OLDLOG&quot;&gt;manually update&lt;&#x2F;a&gt; the entrys for all missed days and have only just got round to it. Should be ok now.&lt;&#x2F;p&gt;
&lt;p&gt;In other news, Kev has promised as a journal, further to putting &lt;a href=&quot;http:&#x2F;&#x2F;homepage.ntlworld.com&#x2F;andy.brook55&#x2F;kev&#x2F;&quot;&gt;some photos&lt;&#x2F;a&gt;. online - good work mr kev. (note at bottom of pic pages a credit to me&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;br&gt;Also Andy has an &lt;a href=&quot;http:&#x2F;&#x2F;homepage.ntlworld.com&#x2F;andy.brook55&#x2F;&quot;&gt;website&lt;&#x2F;a&gt; which is worth a look, check out the uni dessertation.&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nothing much</title>
        <published>2004-10-15T00:00:00+00:00</published>
        <updated>2004-10-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/10/15/slashdot-journal-87058-nothing-much/"/>
        <id>https://0x5.uk/2004/10/15/slashdot-journal-87058-nothing-much/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/10/15/slashdot-journal-87058-nothing-much/">&lt;p&gt;Play was cool, as expected, it&#x27;s your last chance to see it tonight.&lt;&#x2F;p&gt;
&lt;p&gt;I just compiled a C++ program on linux&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;br&gt;well, an example one, but I did change hello world to hello bob. Not a quite a killer app, but a step in the right direction. More to follow I expect.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Offline friends</title>
        <published>2004-10-15T00:00:00+00:00</published>
        <updated>2004-10-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/10/15/slashdot-journal-87059-offline-friends/"/>
        <id>https://0x5.uk/2004/10/15/slashdot-journal-87059-offline-friends/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/10/15/slashdot-journal-87059-offline-friends/">&lt;p&gt;Judging by the&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;. friends list it looks like I&#x27;m failing to persuade people to live online.&lt;&#x2F;p&gt;
&lt;p&gt;Oh well maybe I&#x27;ll just move back into the real world. Good effort mr tom, nothing new today though?&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Lecture, 19th Oct</title>
        <published>2004-10-05T00:00:00+00:00</published>
        <updated>2004-10-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/10/05/slashdot-journal-85935-lecture-19th-oct/"/>
        <id>https://0x5.uk/2004/10/05/slashdot-journal-85935-lecture-19th-oct/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/10/05/slashdot-journal-85935-lecture-19th-oct/">&lt;p&gt;The University of Reading Public Lecture Series 2004-2005&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.rdg.ac.uk&#x2F;publiclectureseries&#x2F;copyright.htm&quot;&gt;http:&#x2F;&#x2F;www.rdg.ac.uk&#x2F;publiclectureseries&#x2F;copyright.htm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Anyone else interested in coming? This is quite close to my work and is of particular interest to me. Txt me if you like cheese. (non sequitur)&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Weekend &#x2F; Talent? &#x2F; Sport &#x2F; Theatre</title>
        <published>2004-10-04T00:00:00+00:00</published>
        <updated>2004-10-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/10/04/slashdot-journal-85850-weekend--talent--sport--theatre/"/>
        <id>https://0x5.uk/2004/10/04/slashdot-journal-85850-weekend--talent--sport--theatre/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/10/04/slashdot-journal-85850-weekend--talent--sport--theatre/">&lt;p&gt;&lt;i&gt;Weekend&lt;&#x2F;i&gt;&lt;br&gt;This weekend involved films, work, drinking and sleeping on sofas (not mine). It did not involve wimbledon.&lt;br&gt;The Importance of Being Earnest is now firmly embedded in my memory as one of the funnier things I have seen, starring Mr D&#x27;Arcy as someone else.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Talent?&lt;&#x2F;i&gt;&lt;br&gt;Just finished an hour of guitar practice with my mentor mr kev, and have now completed excercise 50 in the book (of 150). Not quite the musical heights and fame I was hoping for by now, and still no news of that record deal, hur hur. Only positive outcome has been acquisition of the nickname the axe man courtsey of a close personal friend, who says he&#x27;s inclined to break out the fire axe whenever I play. Thanks for the moral support&lt;nobr&gt; &lt;&#x2F;nobr&gt;;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Sport&lt;&#x2F;i&gt;&lt;br&gt;Started playing badminton again, or at least I&#x27;ve been once! I&#x27;d forgotten how much fun it can be.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;Theatre&lt;&#x2F;i&gt;&lt;br&gt;Oh, and I&#x27;ve booked some tickets for the play, but it doesn&#x27;t look like there will be any problems obtaining a few more. So thank you those of you who declined due to being out of the country or who have work etc, and if anyone else isn&#x27;t sure then you can let me know nearer the time. (Though for now there&#x27;s a whole row with my name on it). For those who are coming, I need to make plans for eating out, and there will be at least some space to crash at mine if reuired.&lt;&#x2F;p&gt;
&lt;p&gt;Luv to all&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>no cycling for me</title>
        <published>2004-09-29T00:00:00+00:00</published>
        <updated>2004-09-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/29/slashdot-journal-85317-no-cycling-for-me/"/>
        <id>https://0x5.uk/2004/09/29/slashdot-journal-85317-no-cycling-for-me/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/29/slashdot-journal-85317-no-cycling-for-me/">&lt;p&gt;So this evening I went for a run.&lt;br&gt;And I ran all the way round the outside of Uni campus in 22mins non-stop (kebab fun to kebab van). This shall hence forth be known as the kebab run.&lt;br&gt;Mr K &amp;amp; AB came too, which was nice.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Play &#x2F; 14th Oct</title>
        <published>2004-09-28T00:00:00+00:00</published>
        <updated>2004-09-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/28/slashdot-journal-85200-play--14th-oct/"/>
        <id>https://0x5.uk/2004/09/28/slashdot-journal-85200-play--14th-oct/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/28/slashdot-journal-85200-play--14th-oct/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;twyrusdrama.org.uk&#x2F;Oct04.htm&quot;&gt;http:&#x2F;&#x2F;twyrusdrama.org.uk&#x2F;Oct04.htm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Hello one and all,&lt;&#x2F;p&gt;
&lt;p&gt;My drama group is putting on a production of Clerical Errors in two weeks time. The script looks to be very amusing and I&#x27;m looking forward to going. Let me know if you want to come with me.&lt;&#x2F;p&gt;
&lt;p&gt;I plan to go on the first night and to involve a meal hopefully at La Fontana. Tickets are £6. I will be putting in the order for tickets this friday so try to let me know by then if you&#x27;re going to make it.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s a hot ticket! Don&#x27;t miss out&lt;nobr&gt; &lt;&#x2F;nobr&gt;;)&lt;&#x2F;p&gt;
&lt;p&gt;If you can&#x27;t make Thursday let me know and I&#x27;ll put together numbers for the other two nights and may go again.&lt;&#x2F;p&gt;
&lt;p&gt;Yours&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
&lt;p&gt;mail me on&lt;br&gt;tim@&lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;&quot;&gt;timwise.co.uk&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;
  ---------------&lt;&#x2F;p&gt;
&lt;p&gt;If you didn&#x27;t get this as an email it either means I don&#x27;t know who you are (hello! mail me&lt;nobr&gt; &lt;&#x2F;nobr&gt;:) or I got your address wrong or never had it, in which case mail me!&lt;&#x2F;p&gt;
&lt;p&gt;Another couple of thoughts on contact details etc:&lt;br&gt;Do you have a website? If so let me know and if you don&#x27;t mind I&#x27;ll post a link to it.&lt;br&gt;Secondly,&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;. has a system for tracking relationships which is quite cool, so can I suggest we all get&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;. accounts and set each other as friends (or foes, mwaa ha ha.) then we won&#x27;t ever have to keep that big list of email addresses. Do it now!&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;slashdot.org&#x2F;login.pl?op=newuserform&quot;&gt;http:&#x2F;&#x2F;slashdot.org&#x2F;login.pl?op=newuserform&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>weekend update</title>
        <published>2004-09-27T00:00:00+00:00</published>
        <updated>2004-09-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/27/slashdot-journal-85072-weekend-update/"/>
        <id>https://0x5.uk/2004/09/27/slashdot-journal-85072-weekend-update/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/27/slashdot-journal-85072-weekend-update/">&lt;p&gt;Ok, it&#x27;s been a while, and between now and then there was a super weekend.&lt;&#x2F;p&gt;
&lt;p&gt;Saturday. Spur of the moment cultural day with my super mate D. We went to see &lt;a href=&quot;http:&#x2F;&#x2F;www.londontown.com&#x2F;LondonEvents&#x2F;Democracy&#x2F;455d7&quot;&gt;Democracy&lt;&#x2F;a&gt; at Wyndham&#x27;s in the West End. The play provided fascinating insight into post war German politics. In the opening scene I thought I was not going to understand anything due to my not exactly perfect knowledge of German history, however it quickly became evident that the substance was a brilliant analysis of the personal feelings and motivations of those governing both West and East Germany up till the fall of the Berlin wall and nothing was presumed of the audience&#x27;s knowledge. A scintillating two and a half hours.&lt;&#x2F;p&gt;
&lt;p&gt;There was also a china town feast, and a trip to see an old friend, which was truly a pleasure. Eventually I got reminded to go home as I was starting to look worse for wear, being somewhat cream crackered, and that, was that.&lt;&#x2F;p&gt;
&lt;p&gt;Sunday involved guitar playing, church going and pub testing with another close friend, who just happens to be next in the alphabet - E!&lt;br&gt;Glad to say my guitar practice is paying off a bit and I wasn&#x27;t too rubbish by musical person&#x27;s standards&lt;nobr&gt; &lt;&#x2F;nobr&gt;;). I had the opportunity to attempt playing flute - now there&#x27;s an experience! Respect to all who have mastered that fine art, I managed to make a noise eventually but it wasn&#x27;t pretty!&lt;&#x2F;p&gt;
&lt;p&gt;kisses to all&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Guitar Book</title>
        <published>2004-09-22T00:00:00+00:00</published>
        <updated>2004-09-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/22/slashdot-journal-84543-guitar-book/"/>
        <id>https://0x5.uk/2004/09/22/slashdot-journal-84543-guitar-book/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/22/slashdot-journal-84543-guitar-book/">&lt;p&gt;I would appear to have finally managed to order &lt;a href=&quot;http:&#x2F;&#x2F;www.amazon.co.uk&#x2F;exec&#x2F;obidos&#x2F;ASIN&#x2F;0825694000&#x2F;026-8427743-1791615&quot;&gt;Solo Guitar Playing&lt;&#x2F;a&gt; from Amazon.co.uk. Hopefully it&#x27;ll turn up soon. I&#x27;ve not been impressed with Amazon, it took me three attempts to persuade them to put my order through properly. I wonder whether their site is broken in &lt;a href=&quot;http:&#x2F;&#x2F;www.mozilla.org&#x2F;&quot;&gt;Mozilla&lt;&#x2F;a&gt;. It was quite a change from the good experiences I had years ago when ordering from them. I was close to actually using a real bookshop. I asked them to find my old account, but it I received no response at all. Hrmmm.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, nuff ranting. I&#x27;m looking forward to continuing the excercises in the book (by Frederick M. Noad) which is very well written and doesn&#x27;t make learning any harder than it needs to be. I borrowed a copy off my neighbour, thank you neighbour, &quot;but that&#x27;s a breach of copyright&quot; I hear you cry... Look I bought the book. OK? Sharing works. End of story. If I didn&#x27;t buy it then stopping someone showing it to me doesn&#x27;t exactly make me more inclined to buy it. I&#x27;ll be expecting a letter from the digital rights people any minute! Oops, that sounded like another rant.&lt;&#x2F;p&gt;
&lt;p&gt;Hrm.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mr C</title>
        <published>2004-09-21T00:00:00+00:00</published>
        <updated>2004-09-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/21/slashdot-journal-84451-mr-c/"/>
        <id>https://0x5.uk/2004/09/21/slashdot-journal-84451-mr-c/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/21/slashdot-journal-84451-mr-c/">&lt;p&gt;Just had word, James is back in Dorking, and is broke!&lt;&#x2F;p&gt;
&lt;p&gt;Mail him. (hyperjames 2003)&lt;&#x2F;p&gt;
&lt;p&gt;Hello James.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Curiosity did _not_ kill the cat. That was the car  &gt;:|</title>
        <published>2004-09-20T00:00:00+00:00</published>
        <updated>2004-09-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/20/slashdot-journal-84305-curiosity-did-not-kill-the-cat-that-was-the-car-/"/>
        <id>https://0x5.uk/2004/09/20/slashdot-journal-84305-curiosity-did-not-kill-the-cat-that-was-the-car-/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/20/slashdot-journal-84305-curiosity-did-not-kill-the-cat-that-was-the-car-/">&lt;p&gt;This is &lt;a href=&quot;http:&#x2F;&#x2F;slashdot.org&#x2F;~mcrbids&quot;&gt;mcrbids&lt;&#x2F;a&gt;&#x27; sig, and I want to show this to all my friends who have ever said &quot;I&#x27;m just curious about stuff&quot;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;&lt;div&gt;&lt;p&gt; &lt;i&gt;I have no special talents. I am only passionately curious.&lt;&#x2F;i&gt;&lt;br&gt;--Albert Einstein&lt;&#x2F;p&gt;&lt;&#x2F;div&gt;&lt;&#x2F;blockquote&gt;
&lt;p&gt;I knew there was nothing magic about knowledge and talent, it&#x27;s all about dedication, and there&#x27;s no better motivation than curiosity.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tonight</title>
        <published>2004-09-20T00:00:00+00:00</published>
        <updated>2004-09-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/20/slashdot-journal-84316-tonight/"/>
        <id>https://0x5.uk/2004/09/20/slashdot-journal-84316-tonight/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/20/slashdot-journal-84316-tonight/">&lt;p&gt;Just made dinner. Fish fingers, left over roast spuds, veggie gravy granules, yummy. Candle lit dinner for one! But that&#x27;s ok, cos life isn&#x27;t that bad, been out for a ride, lovely windy weather down on the lake. Was hoping to get out on a windsurfer, no chance. Have to be this weekend.&lt;&#x2F;p&gt;
&lt;p&gt;And I have new whiteboard which is cool.&lt;br&gt;Pic: &lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;141_4136.JPG&quot;&gt;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;141_4136.JPG&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>more stats!</title>
        <published>2004-09-15T00:00:00+00:00</published>
        <updated>2004-09-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/15/slashdot-journal-83798-more-stats/"/>
        <id>https://0x5.uk/2004/09/15/slashdot-journal-83798-more-stats/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/15/slashdot-journal-83798-more-stats/">&lt;p&gt;Result! My sites been up long enough to get uptime stats from netcraft. That makes me happy.&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;uptime.netcraft.com&#x2F;up&#x2F;graph?site=www.timwise.co.uk&quot;&gt;http:&#x2F;&#x2F;uptime.netcraft.com&#x2F;up&#x2F;graph?site=www.timwise.co.uk&lt;&#x2F;a&gt;&lt;br&gt;&amp;lt;&#x2F;lunchbreak&amp;gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Now I&#x27;m annoyed</title>
        <published>2004-09-14T00:00:00+00:00</published>
        <updated>2004-09-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/14/slashdot-journal-83729-now-im-annoyed/"/>
        <id>https://0x5.uk/2004/09/14/slashdot-journal-83729-now-im-annoyed/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/14/slashdot-journal-83729-now-im-annoyed/">&lt;p&gt;Once again I&#x27;ve been threatened by the BBC.&lt;br&gt;Edited image of the &lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;threat_sm_ed.jpg&quot;&gt;most recent letter&lt;&#x2F;a&gt; [48Kb]&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve reeled of a letter to white dot to see it they can help, or know of people who are similarly irritated.&lt;&#x2F;p&gt;
&lt;p&gt;See also:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.whitedot.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.whitedot.org&#x2F;&lt;&#x2F;a&gt;&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.tvlicensing.co.uk&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.tvlicensing.co.uk&#x2F;&lt;&#x2F;a&gt; -Resizes your browser! Very bad web design.&lt;&#x2F;p&gt;
&lt;p&gt;Letter follows:&lt;br&gt;===============================================&lt;br&gt;To: info&#x2F;at&#x2F;whitedot&#x2F;dot&#x2F;org&lt;br&gt;Subject: uk tv licensing&lt;&#x2F;p&gt;
&lt;p&gt;Hello folks.&lt;&#x2F;p&gt;
&lt;p&gt;I watched your telly program yonks ago (the one on the BBC saying, erm, don&#x27;t watch the BBC!), and had to agree with more or less all your arguments. Bit disappointed you&#x27;ve not updated your site lately (last 12 months), maybe you got distracted by the flickering box in the corner?! I haven&#x27;t had a TV in my flat for the last nine months now, and guess what. I don&#x27;t miss it.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been getting threatening letters regularly from the BBC&#x27;s TV Licensing division since about February, but this latest one has a tone which I find highly offensive as it implies that there can be no doubt I am a criminal. I&#x27;ve checked every letter to make sure there is no legal compulsion to tell them I have no TV, and there doesn&#x27;t seem to be.  I looked through the whole of the HTML on &lt;a href=&quot;http:&#x2F;&#x2F;www.tvlicensing.co.uk&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.tvlicensing.co.uk&#x2F;&lt;&#x2F;a&gt; and found no reference to not having a TV.&lt;&#x2F;p&gt;
&lt;p&gt;I was hoping you might know what other people feel about being threatened this way, and what people have done about it.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d particularly like to draw your attention to the small print at the bottom of the page which says &quot;If you have recently purchased a license, please accept our apologies...&quot;, and the notable absence of any such apology to those of us who dislike television far too much to pay £121 for it.&lt;&#x2F;p&gt;
&lt;p&gt;To be fair, there is actually a reasonable reference to people who do not own a TV on page 12 of this:&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.tvlicensing.co.uk&#x2F;pdfs&#x2F;40115_BBC_Freedom_of_Info.pdf&quot;&gt;http:&#x2F;&#x2F;www.tvlicensing.co.uk&#x2F;pdfs&#x2F;40115_BBC_Freedom_of_Info.pdf&lt;&#x2F;a&gt;&lt;br&gt;though it&#x27;s taken me half an hour to find it and it doesn&#x27;t detract from the fact that I&#x27;ve just been threatened with court action (again) and the £1,000 fine that they go on about.&lt;&#x2F;p&gt;
&lt;p&gt;Latest letter attached.&lt;&#x2F;p&gt;
&lt;p&gt;Yours&lt;&#x2F;p&gt;
&lt;p&gt;Tim Abell&lt;br&gt;Berkshire,&lt;br&gt;UK&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I know where my towel is.</title>
        <published>2004-09-13T00:00:00+00:00</published>
        <updated>2004-09-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/13/slashdot-journal-83600-i-know-where-my-towel-is/"/>
        <id>https://0x5.uk/2004/09/13/slashdot-journal-83600-i-know-where-my-towel-is/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/13/slashdot-journal-83600-i-know-where-my-towel-is/">&lt;p&gt;Ok, this is the best thing ever.&lt;br&gt;Anyone who reads this &lt;b&gt;must&lt;&#x2F;b&gt; listen to the hitch hikers guide to the galaxy. I remember this from when it was first broadcast, and I don&#x27;t think there&#x27;s anything I could say that does it justice.&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.bbc.co.uk&#x2F;radio4&#x2F;hitchhikers&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.bbc.co.uk&#x2F;radio4&#x2F;hitchhikers&#x2F;&lt;&#x2F;a&gt;&lt;br&gt;Episode 1- Tuesday 21 September 2004 6.30pm, repeated Thursday 23 September 11.00pm&lt;br&gt;Don&#x27;t miss it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>stats</title>
        <published>2004-09-11T00:00:00+00:00</published>
        <updated>2004-09-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/11/slashdot-journal-83418-stats/"/>
        <id>https://0x5.uk/2004/09/11/slashdot-journal-83418-stats/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/11/slashdot-journal-83418-stats/">&lt;p&gt;Woo!&lt;br&gt;Mandrake, Apache, AWStats, wget, cron, sleepless nights...&lt;br&gt;&lt;nobr&gt; &lt;&#x2F;nobr&gt;... and now I have up to date stats for &lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;&quot;&gt;timwise.co.uk&lt;&#x2F;a&gt;, updated automatically overnight every night for the previous day&#x27;s usage. Including the cubs site.&lt;br&gt;See the stats link bottom right of the home page.&lt;&#x2F;p&gt;
&lt;p&gt;Joy.&lt;&#x2F;p&gt;
&lt;p&gt;Also, I&#x27;ve started signing into ICQ again, and there&#x27;s a little image on timwise that tells you if I&#x27;m online, which is nice. I&#x27;m not too keen on the standard icq client any more, but that&#x27;s ok because I use &lt;a href=&quot;http:&#x2F;&#x2F;gaim.sourceforge.net&#x2F;&quot;&gt;GAIM&lt;&#x2F;a&gt; these days, which I can highly recommend. If you can&#x27;t be bothered with that, you can click on the online img on my site and send me a message through the icq messaging centre, which is quite a cool feature.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>life continues</title>
        <published>2004-09-10T00:00:00+00:00</published>
        <updated>2004-09-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/10/slashdot-journal-83324-life-continues/"/>
        <id>https://0x5.uk/2004/09/10/slashdot-journal-83324-life-continues/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/10/slashdot-journal-83324-life-continues/">&lt;p&gt;Worked many hours this week, trying to get new work web site finished.&lt;&#x2F;p&gt;
&lt;p&gt;So this evening I cycled to the pool and did an hours training. I&#x27;m now tired and chlorinated, but very relaxed.&lt;br&gt;---&lt;br&gt;My web server went off on one at 2am the other night (just when I was thinking of going to sleep), thrashing its hdd. Think someone was trying to hack into it with a buffer overflow. Here&#x27;s the log:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt; &lt;tt&gt;4.227.111.174 - - [09&#x2F;Sep&#x2F;2004:02:22:01 +0100] &quot;POST http:&#x2F;&#x2F;4.227.111.174:25&#x2F; HTTP&#x2F;1.1&quot; 200 480 &quot;-&quot; &quot;-&quot;&lt;&#x2F;tt&gt;&lt;&#x2F;p&gt;&lt;&#x2F;div&gt; &lt;&#x2F;blockquote&gt;
&lt;p&gt;Sods.&lt;&#x2F;p&gt;
&lt;p&gt;Looking at my logs, the server was subject to a few attempts within hours of it coming online.&lt;br&gt;Much more than my hosted site. Guess it&#x27;s people running &lt;a href=&quot;http:&#x2F;&#x2F;www.insecure.org&#x2F;&quot;&gt;nmap&lt;&#x2F;a&gt; against adsl dial up ip ranges and getting all excited by the prospect of an open port 80.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a classic example:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt; &lt;tt&gt;81.70.101.40 - - [05&#x2F;Sep&#x2F;2004:17:37:46 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;.hash=eb649e3d22cdb034d91b64d4c11215f83a7e2fda HTTP&#x2F;1.1&quot; 404 372 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:26 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;root.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 342 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:28 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;MSADC&#x2F;root.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 340 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:28 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;c&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 350 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:28 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;d&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 350 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:28 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%255c..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 364 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:28 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;_vti_bin&#x2F;..%255c..&#x2F;..%255c..&#x2F;..%255c..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 381 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:28 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;_mem_bin&#x2F;..%255c..&#x2F;..%255c..&#x2F;..%255c..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 381 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:28 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;msadc&#x2F;..%255c..&#x2F;..%255c..&#x2F;..%255c&#x2F;..%c1%1c..&#x2F;..%c1%1c..&#x2F;..%c1%1c..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 397 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:29 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%c1%1c..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 363 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:29 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%c0%2f..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 363 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:29 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%c0%af..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 363 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:29 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%c1%9c..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 363 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:29 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%%35%63..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 400 354 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:29 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%%35c..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 400 354 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:29 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%25%35%63..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 364 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.164.85.239 - - [06&#x2F;Sep&#x2F;2004:18:08:29 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;scripts&#x2F;..%252f..&#x2F;winnt&#x2F;system32&#x2F;cmd.exe?&#x2F;c+dir HTTP&#x2F;1.0&quot; 404 364 &quot;-&quot; &quot;-&quot;&lt;br&gt;81.215.120.25 - - [07&#x2F;Sep&#x2F;2004:12:59:20 +0100] &quot;GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;.hash=cf770b6f55e15660d70f00542bd58efeb7a8487f HTTP&#x2F;1.1&quot; 404 372 &quot;-&quot; &quot;-&quot;&lt;&#x2F;tt&gt;&lt;&#x2F;p&gt;&lt;&#x2F;div&gt; &lt;&#x2F;blockquote&gt;
&lt;p&gt;--&lt;br&gt;By the way, if you think nmap is very uncool to know about, may I direct you to the news article on nmap&#x27;s site which shows Trinity actually doing a real hacking attack in the film Matrix Reloaded&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.insecure.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.insecure.org&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>roxio</title>
        <published>2004-09-02T00:00:00+00:00</published>
        <updated>2004-09-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/02/slashdot-journal-82474-roxio/"/>
        <id>https://0x5.uk/2004/09/02/slashdot-journal-82474-roxio/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/02/slashdot-journal-82474-roxio/">&lt;p&gt;I was just about to have a rant at roxio for forcing me to register to obtain updates when I discovered they&#x27;ve &lt;a href=&quot;http:&#x2F;&#x2F;hardware.mcse.ms&#x2F;message57667.html&quot;&gt;sold out&lt;&#x2F;a&gt; and are likely to be up shit creek anyway. Good luck to them, I hope they pay the artists a fair percentage.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>life update</title>
        <published>2004-09-01T00:00:00+00:00</published>
        <updated>2004-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/09/01/slashdot-journal-82368-life-update/"/>
        <id>https://0x5.uk/2004/09/01/slashdot-journal-82368-life-update/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/09/01/slashdot-journal-82368-life-update/">&lt;p&gt;it&#x27;s late so I&#x27;ll keep it short.&lt;br&gt;I went to greenbelt this weekend, which was fun. Good music, great music, some terrible music. A bearable dose of religion, and quite a nice element of generic spirituality. Plenty of rain outside the tent but I didn&#x27;t get very wet except when I flew my kite.&lt;&#x2F;p&gt;
&lt;p&gt;Dropped in to london town last night to see some old friends and had a great evening. Don&#x27;t think there&#x27;s anything I can relay here though!&lt;&#x2F;p&gt;
&lt;p&gt;urgh. bed.&lt;&#x2F;p&gt;
&lt;p&gt;did I mention I&#x27;m now running an apache webserver on Mandrake Linux? I did? Oh well, never mind then.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Morzine</title>
        <published>2004-08-22T00:00:00+00:00</published>
        <updated>2004-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/22/slashdot-journal-81130-morzine/"/>
        <id>https://0x5.uk/2004/08/22/slashdot-journal-81130-morzine/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/22/slashdot-journal-81130-morzine/">&lt;p&gt;All of the &lt;a href=&quot;http:&#x2F;&#x2F;www.t.abell.dsl.pipex.com&#x2F;photos&#x2F;morzine_aug04&#x2F;&quot;&gt;Morzine   photos&lt;&#x2F;a&gt; are up. [7.83Mb]&lt;&#x2F;p&gt;
&lt;p&gt;Had a top time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>So what _is_ the &quot;internet&quot;?</title>
        <published>2004-08-22T00:00:00+00:00</published>
        <updated>2004-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/22/slashdot-journal-81179-so-what-is-the-internet/"/>
        <id>https://0x5.uk/2004/08/22/slashdot-journal-81179-so-what-is-the-internet/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/22/slashdot-journal-81179-so-what-is-the-internet/">&lt;p&gt;Maybe it&#x27;s a &lt;a href=&quot;http:&#x2F;&#x2F;www.bsd-unix.net&#x2F;seitz&#x2F;funny&#x2F;RvB_NYC2.mov&quot;&gt;movie&lt;&#x2F;a&gt;? [edit: link busted.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:(  ]&lt;br&gt;Thank you &lt;a href=&quot;http:&#x2F;&#x2F;b3ta.com&#x2F;newsletter&#x2F;issue148&#x2F;&quot;&gt;b3ta&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>more pics</title>
        <published>2004-08-19T00:00:00+00:00</published>
        <updated>2004-08-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/19/slashdot-journal-80837-more-pics/"/>
        <id>https://0x5.uk/2004/08/19/slashdot-journal-80837-more-pics/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/19/slashdot-journal-80837-more-pics/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;IMG_4042.JPG&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Picture-skew</title>
        <published>2004-08-17T00:00:00+00:00</published>
        <updated>2004-08-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/17/slashdot-journal-80582-picture-skew/"/>
        <id>https://0x5.uk/2004/08/17/slashdot-journal-80582-picture-skew/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/17/slashdot-journal-80582-picture-skew/">&lt;p&gt;Nice &lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;IMG_3919.JPG&quot;&gt;here&lt;&#x2F;a&gt;, and &lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;IMG_3955.JPG&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bonjour</title>
        <published>2004-08-16T00:00:00+00:00</published>
        <updated>2004-08-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/16/slashdot-journal-80470-bonjour/"/>
        <id>https://0x5.uk/2004/08/16/slashdot-journal-80470-bonjour/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/16/slashdot-journal-80470-bonjour/">&lt;p&gt;Today, I have mostly been riding a &lt;a href=&quot;http:&#x2F;&#x2F;www.santacruzmtb.com&#x2F;bicycles&#x2F;vpfree.php&quot;&gt;vp free&lt;&#x2F;a&gt;, down mountains. Most excellent. Some rain, some sun, lots of stunning &lt;a href=&quot;http:&#x2F;&#x2F;www.timwise.co.uk&#x2F;images&#x2F;IMG_3894.JPG&quot;&gt;scenery&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Facial Fuzz</title>
        <published>2004-08-16T00:00:00+00:00</published>
        <updated>2004-08-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/16/slashdot-journal-80495-facial-fuzz/"/>
        <id>https://0x5.uk/2004/08/16/slashdot-journal-80495-facial-fuzz/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/16/slashdot-journal-80495-facial-fuzz/">&lt;p&gt;Forgot to mention earlier the thing I meant to say.&lt;&#x2F;p&gt;
&lt;p&gt;Beardy Tim is no more.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Real IT Stories</title>
        <published>2004-08-14T00:00:00+00:00</published>
        <updated>2004-08-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/14/slashdot-journal-80312-real-it-stories/"/>
        <id>https://0x5.uk/2004/08/14/slashdot-journal-80312-real-it-stories/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/14/slashdot-journal-80312-real-it-stories/">&lt;p&gt;Not bad for m$ technical &lt;a href=&quot;http:&#x2F;&#x2F;www.microsoft.com&#x2F;technet&#x2F;abouttn&#x2F;subscriptions&#x2F;flash&#x2F;promo&#x2F;realstories&#x2F;topten.mspx&quot;&gt;comdey&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Biking</title>
        <published>2004-08-14T00:00:00+00:00</published>
        <updated>2004-08-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/14/slashdot-journal-80339-biking/"/>
        <id>https://0x5.uk/2004/08/14/slashdot-journal-80339-biking/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/14/slashdot-journal-80339-biking/">&lt;p&gt;Spent an enjoyable afternoon out on the trails north of henley today. Found lots of mud, nettles rocks and things interspersed with the occasional nice view and a fair amount of sunshine. A fairly injury free day given the size of our group. Tried out the new local &quot;fat fish&quot; shop for dinner. Tasty, would recommend, pleasant staff as well which makes such a difference when you&#x27;re buying cod &#x27;n chips!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Busy busy</title>
        <published>2004-08-10T00:00:00+00:00</published>
        <updated>2004-08-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/08/10/slashdot-journal-79902-busy-busy/"/>
        <id>https://0x5.uk/2004/08/10/slashdot-journal-79902-busy-busy/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/08/10/slashdot-journal-79902-busy-busy/">&lt;p&gt;Life is good.&lt;br&gt;I&#x27;m far too busy to write anything interesting in my journal so instead here&#x27;s the possibly sexist joke that fluffy sent me last week.&lt;&#x2F;p&gt;
&lt;p&gt;Made me laugh anyway. Well I had had quite a few drinks and it was about 1am.&lt;&#x2F;p&gt;
&lt;p&gt;==============&lt;&#x2F;p&gt;
&lt;p&gt;We always hear &quot;the rules&quot; from the female side. Now here are the rules&lt;&#x2F;p&gt;
&lt;p&gt;from the male side.&lt;&#x2F;p&gt;
&lt;p&gt;These are our rules:&lt;&#x2F;p&gt;
&lt;p&gt;Please note... these are all numbered &quot;1&quot; ON PURPOSE!&lt;&#x2F;p&gt;
&lt;p&gt;1. Breasts are for looking at and that is why we do it. Don&#x27;t try to&lt;&#x2F;p&gt;
&lt;p&gt;change that.&lt;&#x2F;p&gt;
&lt;p&gt;1. Learn to work the toilet seat. You&#x27;re a big girl. If it&#x27;s up, put it&lt;&#x2F;p&gt;
&lt;p&gt;down. We need it up, you need it down. You don&#x27;t hear us complaining&lt;&#x2F;p&gt;
&lt;p&gt;about you leaving it down.&lt;&#x2F;p&gt;
&lt;p&gt;1. Saturday = sports. It&#x27;s like the full moon or the changing of the&lt;&#x2F;p&gt;
&lt;p&gt;tides. Let it be.&lt;&#x2F;p&gt;
&lt;p&gt;1. Shopping is NOT a sport. And no, we are never going to think of it&lt;&#x2F;p&gt;
&lt;p&gt;that way.&lt;&#x2F;p&gt;
&lt;p&gt;1. Crying is blackmail.&lt;&#x2F;p&gt;
&lt;p&gt;1. Ask for what you want. Let us be clear on this one: Subtle hints do&lt;&#x2F;p&gt;
&lt;p&gt;not work! Strong hints do not work! Obvious hints do not work! Just say&lt;&#x2F;p&gt;
&lt;p&gt;it!&lt;&#x2F;p&gt;
&lt;p&gt;1. Yes and No are perfectly acceptable answers to almost every question.&lt;&#x2F;p&gt;
&lt;p&gt;1. Come to us with a problem only if you want help solving it. That&#x27;s&lt;&#x2F;p&gt;
&lt;p&gt;what we do. Sympathy is what your girlfriends are for.&lt;&#x2F;p&gt;
&lt;p&gt;1. A headache that lasts for 17 months is a problem. See a doctor.&lt;&#x2F;p&gt;
&lt;p&gt;1. Anything we said 6 months ago is inadmissible in an argument. In&lt;&#x2F;p&gt;
&lt;p&gt;fact, all comments become null and void after 7 days.&lt;&#x2F;p&gt;
&lt;p&gt;1. If you think you&#x27;re fat, you probably are. Don&#x27;t ask us.&lt;&#x2F;p&gt;
&lt;p&gt;1. If something we said can be interpreted two ways, and one of the ways&lt;&#x2F;p&gt;
&lt;p&gt;makes you sad or angry, we meant the other one.&lt;&#x2F;p&gt;
&lt;p&gt;1. You can either ask us to do something or tell us how you want it&lt;&#x2F;p&gt;
&lt;p&gt;done. Not both._ If you already know best how to do it, just do it&lt;&#x2F;p&gt;
&lt;p&gt;yourself.&lt;&#x2F;p&gt;
&lt;p&gt;1. Whenever possible, please say whatever you have to say during&lt;&#x2F;p&gt;
&lt;p&gt;commercials.&lt;&#x2F;p&gt;
&lt;p&gt;1. Christopher Columbus did not need directions and neither do we.&lt;&#x2F;p&gt;
&lt;p&gt;1. ALL men see in only 16 colours, like Windows default settings. Peach,&lt;&#x2F;p&gt;
&lt;p&gt;for example, is a fruit, not a colour. Pumpkin is also a fruit. We have&lt;&#x2F;p&gt;
&lt;p&gt;no idea what mauve is.&lt;&#x2F;p&gt;
&lt;p&gt;1. If it itches, it will be scratched. We do that.&lt;&#x2F;p&gt;
&lt;p&gt;1. If we ask what is wrong and you say &quot;nothing,&quot; we will act like&lt;&#x2F;p&gt;
&lt;p&gt;nothing&#x27;s wrong. We know you are lying, but it is just not worth the&lt;&#x2F;p&gt;
&lt;p&gt;hassle.&lt;&#x2F;p&gt;
&lt;p&gt;1. If you ask a question you don&#x27;t want an answer to, expect an answer&lt;&#x2F;p&gt;
&lt;p&gt;you don&#x27;t want to hear.&lt;&#x2F;p&gt;
&lt;p&gt;1. When we have to go somewhere, absolutely anything you wear is fine.&lt;&#x2F;p&gt;
&lt;p&gt;Really.&lt;&#x2F;p&gt;
&lt;p&gt;1. Don&#x27;t ask us what we&#x27;re thinking about unless you are prepared to&lt;&#x2F;p&gt;
&lt;p&gt;discuss such topics as Sex, Sport, or Cars.&lt;&#x2F;p&gt;
&lt;p&gt;1. You have enough clothes.&lt;&#x2F;p&gt;
&lt;p&gt;1. You have too many shoes.&lt;&#x2F;p&gt;
&lt;p&gt;1. I am in shape. Round is a shape.&lt;&#x2F;p&gt;
&lt;p&gt;1. Thank you for reading this; Yes, I know, I have to sleep on the couch&lt;&#x2F;p&gt;
&lt;p&gt;tonight, but did you know men really don&#x27;t mind that, it&#x27;s like camping.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>paris who?</title>
        <published>2004-07-30T00:00:00+00:00</published>
        <updated>2004-07-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/07/30/slashdot-journal-78957-paris-who/"/>
        <id>https://0x5.uk/2004/07/30/slashdot-journal-78957-paris-who/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/07/30/slashdot-journal-78957-paris-who/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.banterist.com&#x2F;archivefiles&#x2F;000125.html&quot;&gt;oh!&lt;&#x2F;a&gt; I&#x27;ve been wondering what the fuss was about.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>swimming</title>
        <published>2004-07-28T00:00:00+00:00</published>
        <updated>2004-07-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/07/28/slashdot-journal-78736-swimming/"/>
        <id>https://0x5.uk/2004/07/28/slashdot-journal-78736-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/07/28/slashdot-journal-78736-swimming/">&lt;p&gt;went swimming. now really tired.&lt;br&gt;on phone to australia now, relaying all the gossip that I couldn&#x27;t possibly put on a public website!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>an evenings work</title>
        <published>2004-07-27T00:00:00+00:00</published>
        <updated>2004-07-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/07/27/slashdot-journal-78638-an-evenings-work/"/>
        <id>https://0x5.uk/2004/07/27/slashdot-journal-78638-an-evenings-work/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/07/27/slashdot-journal-78638-an-evenings-work/">&lt;p&gt;late in from work&lt;br&gt;bolognese from scratch&lt;br&gt;guitair&lt;br&gt;sleep&lt;br&gt;hapiness&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>taff tour</title>
        <published>2004-07-24T00:00:00+00:00</published>
        <updated>2004-07-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/07/24/slashdot-journal-78327-taff-tour/"/>
        <id>https://0x5.uk/2004/07/24/slashdot-journal-78327-taff-tour/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/07/24/slashdot-journal-78327-taff-tour/">&lt;p&gt;the &lt;a href=&quot;http:&#x2F;&#x2F;www.t.abell.dsl.pipex.com&#x2F;photos&#x2F;wales_20040715&#x2F;&quot;&gt;pics &lt;&#x2F;a&gt;are up.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Commuting by Bike</title>
        <published>2004-07-12T00:00:00+00:00</published>
        <updated>2004-07-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/07/12/slashdot-journal-77152-commuting-by-bike/"/>
        <id>https://0x5.uk/2004/07/12/slashdot-journal-77152-commuting-by-bike/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/07/12/slashdot-journal-77152-commuting-by-bike/">&lt;p&gt;Hello.&lt;&#x2F;p&gt;
&lt;p&gt;I just got in from work. This is the first time I&#x27;ve ridden to my new job. It&#x27;s 9.9 miles each way, and reasonably flat except for a few sharp rises and drops. All this fitness stuff is really starting to pay off, I averaged 18.5mph on the way to work (32 mins) and 19mph on the way home (31 mins). That&#x27;s by far the best speeds I have ever attained. I did once manage 20mph but it was over a much shorter distance and I probably had the wind with me (parp).&lt;&#x2F;p&gt;
&lt;p&gt;My cycling has been really important to me ever since my first trike. I let it slip once not long after I got a car, laziness ruled and I didn&#x27;t go out for ages. The final straw was one christmas when I went for a short ride to relieve the boredom. I didn&#x27;t even make it a mile up the road, and I was so annoyed with myself that I haven&#x27;t stopped since.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wow. I&#x27;ve never had it so good.</title>
        <published>2004-07-11T00:00:00+00:00</published>
        <updated>2004-07-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/07/11/slashdot-journal-77075-wow-ive-never-had-it-so-good/"/>
        <id>https://0x5.uk/2004/07/11/slashdot-journal-77075-wow-ive-never-had-it-so-good/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/07/11/slashdot-journal-77075-wow-ive-never-had-it-so-good/">&lt;p&gt;Life could not be better.&lt;&#x2F;p&gt;
&lt;p&gt;I haven&#x27;t been this happy for many years. It really hit me when I was driving home tonight from seeing andy &#x27;n co. I was half way home when I felt this huge wave of happiness course through my veins and I broke into a huge uncontrollable smile. It lasted for ages, and I&#x27;m still glowing.   (&lt;nobr&gt; &lt;&#x2F;nobr&gt;:^D)&lt;&#x2F;p&gt;
&lt;p&gt;Right now I&#x27;m listening to the streets on bbc radio 1, and even though it&#x27;s one of the saddest most moving songs I&#x27;ve ever heard, nothing could bring me down now. I love that tune.&lt;&#x2F;p&gt;
&lt;p&gt;I started my new job at &lt;a href=&quot;http:&#x2F;&#x2F;www.emapsite.com&#x2F;&quot;&gt;emapsite&lt;&#x2F;a&gt; last monday and have been thoroughly enjoying it. The people are great and I&#x27;m relishing the challenge of a new beginning. I was even happy to head to London on company business!&lt;&#x2F;p&gt;
&lt;p&gt;Which... was the start of a blinding weekend. Sat finished with me rolling into Twyford station at around half ten this morning (Sunday). I&#x27;ve never missed the last train before but I was way to busy living life to worry about little things like that! Besides it was a good opportunity to see my best mate over in sunny croyden. Most appreciated, thanks a mil darling, I owe you big time (again!).&lt;&#x2F;p&gt;
&lt;p&gt;I regained a close friend this weekend who I had so carelessly lost. I hope there&#x27;s no hard feelings and I&#x27;m looking forward to making up for lost time. I really appreciated being able to talk so freely, like I haven&#x27;t for a long time. By the way, I have to give a huge thank you to all of my wonderful friends who have stuck by me through hard times, especially ants, coz, kev, andy, ellie, tom, &#x27;laine, and some of my newer friends who probably won&#x27;t read this! No regrets. Looking forward to more good times. And congrats to Anna, I wish you all the best.&lt;&#x2F;p&gt;
&lt;p&gt;Woah, that was a bit heavy. On a lighter note, I had a great day today helping to build a cardboard kiddy house with andy and &#x27;lainey, pictures will follow after tuesday. I also managed to just about play the first few bars of new tune on the keyboard. I really think I might get somewhere with this music thing.&lt;&#x2F;p&gt;
&lt;p&gt;In other timmy news, I&#x27;m looking forward to a forthcoming triathlon relay race, in a kind of nervous way. I feel really good from all the fitness I&#x27;ve gained in the last nine months.&lt;&#x2F;p&gt;
&lt;p&gt;Time for sleep. Wish me luck for everything this week throws at me, and I wish you happiness where ever and who ever you are. Thanks for reading.&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Pringles</title>
        <published>2004-07-05T00:00:00+00:00</published>
        <updated>2004-07-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/07/05/slashdot-journal-76506-pringles/"/>
        <id>https://0x5.uk/2004/07/05/slashdot-journal-76506-pringles/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/07/05/slashdot-journal-76506-pringles/">&lt;p&gt;Yay! My relations &lt;a href=&quot;http:&#x2F;&#x2F;www.pringle.demon.co.uk&#x2F;&quot;&gt;on film&lt;&#x2F;a&gt; &#x2F; now on the&lt;br&gt;net.&lt;&#x2F;p&gt;
&lt;p&gt;Super challenge too. Worthy of b3ta methinks.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Another rung on the ladder</title>
        <published>2004-07-05T00:00:00+00:00</published>
        <updated>2004-07-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/07/05/slashdot-journal-76532-another-rung-on-the-ladder/"/>
        <id>https://0x5.uk/2004/07/05/slashdot-journal-76532-another-rung-on-the-ladder/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/07/05/slashdot-journal-76532-another-rung-on-the-ladder/">&lt;p&gt;Today I passed microsoft exam &lt;a href=&quot;http:&#x2F;&#x2F;www.microsoft.com&#x2F;learning&#x2F;exams&#x2F;70-270.asp&quot;&gt;70-270&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So you can call me&lt;br&gt;Tim Abell BSc MCP&lt;br&gt;Woo!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>SBR</title>
        <published>2004-06-23T00:00:00+00:00</published>
        <updated>2004-06-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/06/23/slashdot-journal-75235-sbr/"/>
        <id>https://0x5.uk/2004/06/23/slashdot-journal-75235-sbr/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/06/23/slashdot-journal-75235-sbr/">&lt;p&gt;SBR = Swim, Bike, Run. It&#x27;s a triathlon thing.&lt;&#x2F;p&gt;
&lt;p&gt;On monday, I biked to work as per, very unstrenuous. Then I went training in the evening. Went for a proper training run, which I was just jogging back from when the heaveans opened and I got soaked. The water then turned to slush, like being sprayed with a slush puppy.&lt;&#x2F;p&gt;
&lt;p&gt;Then I swam, very very slowwwly (urgh, gurgle).&lt;&#x2F;p&gt;
&lt;p&gt;Spent tuesday moaning about how much my legs hurt and how tired I was. It&#x27;s good to be a brit.&lt;&#x2F;p&gt;
&lt;p&gt;Today I woke up with a start thinking I&#x27;d slept through my alarm. But it was half an hour too early. Must&#x27;ve got enough sleep for once.&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>**No Title**</title>
        <published>2004-06-18T00:00:00+00:00</published>
        <updated>2004-06-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/06/18/slashdot-journal-74860-/"/>
        <id>https://0x5.uk/2004/06/18/slashdot-journal-74860-/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/06/18/slashdot-journal-74860-/">&lt;p&gt;Just read something Ellen wrote for me years ago whilst going through some of my paper.&lt;&#x2F;p&gt;
&lt;p&gt;Made me think.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m really very lonely at the moment.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s so many things I tried to ignore at the time, I didn&#x27;t read half the things she gave me at the time because it was all a bit much, now going back is very strange.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Windsurfing</title>
        <published>2004-06-16T00:00:00+00:00</published>
        <updated>2004-06-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/06/16/slashdot-journal-74626-windsurfing/"/>
        <id>https://0x5.uk/2004/06/16/slashdot-journal-74626-windsurfing/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/06/16/slashdot-journal-74626-windsurfing/">&lt;p&gt;Excellent evening out on the lake today.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s been ages since I was out last on a board, and I was rubbish then! But with a little help from my friends, and a fair breeze I don&#x27;t think I did too badly.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t half ache now.&lt;&#x2F;p&gt;
&lt;p&gt;Cheers for dinner A, much appreciated.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Blollogs</title>
        <published>2004-06-14T00:00:00+00:00</published>
        <updated>2004-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/06/14/slashdot-journal-74343-blollogs/"/>
        <id>https://0x5.uk/2004/06/14/slashdot-journal-74343-blollogs/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/06/14/slashdot-journal-74343-blollogs/">&lt;p&gt;Sloth gets a &lt;a href=&quot;http:&#x2F;&#x2F;dwiseman.blogspot.com&#x2F;&quot;&gt;blog&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>This is a local village</title>
        <published>2004-06-14T00:00:00+00:00</published>
        <updated>2004-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/06/14/slashdot-journal-74396-this-is-a-local-village/"/>
        <id>https://0x5.uk/2004/06/14/slashdot-journal-74396-this-is-a-local-village/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/06/14/slashdot-journal-74396-this-is-a-local-village/">&lt;p&gt;Heard today that my x is now engaged to fb. Had it rubbed in my face as usual.&lt;&#x2F;p&gt;
&lt;p&gt;Oh well.&lt;&#x2F;p&gt;
&lt;p&gt;Good luck to them. I guess.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Wall</title>
        <published>2004-06-12T00:00:00+00:00</published>
        <updated>2004-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/06/12/slashdot-journal-74212-the-wall/"/>
        <id>https://0x5.uk/2004/06/12/slashdot-journal-74212-the-wall/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/06/12/slashdot-journal-74212-the-wall/">&lt;p&gt;Mountain biking exploits&lt;br&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.t.abell.dsl.pipex.com&#x2F;photos&#x2F;wales_20040610&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Photos</title>
        <published>2004-05-13T00:00:00+00:00</published>
        <updated>2004-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/05/13/slashdot-journal-71345-photos/"/>
        <id>https://0x5.uk/2004/05/13/slashdot-journal-71345-photos/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/05/13/slashdot-journal-71345-photos/">&lt;p&gt;A friend just put me on to a rather nifty image hosting service called &lt;a href=&quot;http:&#x2F;&#x2F;www.photobucket.com&#x2F;&quot;&gt;Photo bucket&lt;&#x2F;a&gt;.&lt;br&gt;I got a registration to have a look round. You can see what I get up to on &lt;a href=&quot;http:&#x2F;&#x2F;img66.photobucket.com&#x2F;albums&#x2F;v202&#x2F;tim_abell&#x2F;&quot;&gt;my album&lt;&#x2F;a&gt; page. The service resizes images for you which is handy for the non technically minded of us.&lt;&#x2F;p&gt;
&lt;p&gt;Not that I need it given that I pay for web space.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>swimming</title>
        <published>2004-05-11T00:00:00+00:00</published>
        <updated>2004-05-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/05/11/slashdot-journal-71130-swimming/"/>
        <id>https://0x5.uk/2004/05/11/slashdot-journal-71130-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/05/11/slashdot-journal-71130-swimming/">&lt;p&gt;Hello again.&lt;&#x2F;p&gt;
&lt;p&gt;Success of the week (Mon eve):&lt;br&gt;Swimming 400m in (more or less) one attempt.&lt;br&gt;Time taken: 12mins&lt;br&gt;Lengths: 16.&lt;&#x2F;p&gt;
&lt;p&gt;Yay.&lt;&#x2F;p&gt;
&lt;p&gt;Also, for all who didn&#x27;t know I was the butler (and no, I didn&#x27;t do it; yawn), I very much enjoyed my stage debut.&lt;&#x2F;p&gt;
&lt;p&gt;I even got recognised in the chinese on sat night by a young lady who had seen the friday night show - joy.&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sleep is for wusses</title>
        <published>2004-05-02T00:00:00+00:00</published>
        <updated>2004-05-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/05/02/slashdot-journal-70152-sleep-is-for-wusses/"/>
        <id>https://0x5.uk/2004/05/02/slashdot-journal-70152-sleep-is-for-wusses/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/05/02/slashdot-journal-70152-sleep-is-for-wusses/">&lt;p&gt;My debut performance draws near! I have my picture in the twyford advertiser and the henley standard which is cool. I stood outside Waitrose for an hour publicising the play and got slightly nervous as to the number of people who actually sounded interested. So I made an extra effort in the technical rehearsal and only got some of it completely wrong. Oh well, guess it&#x27;s called amateur dramatics for a reason!&lt;&#x2F;p&gt;
&lt;p&gt;As for the swimming, I&#x27;m pleased with the improvement in my technique, soon I may even be able to swim the required distances in one go. I&#x27;ve also been doing a bit of running. The new shoes still aren&#x27;t quite right - they rub a bit, and it&#x27;s going to be a long time before I can run ten kilometers. Maybe I&#x27;ll wait till next year before attempting to race, I wouldn&#x27;t want all the marshals to have to wait for me before the can go home!&lt;&#x2F;p&gt;
&lt;p&gt;And now, a word about coz.&lt;br&gt;The other day I was sitting with my friends in her old house, and it was quiet, so I said &quot;everyone point at coz&quot;, and everyone pointed at the floor, and laughed. Then we discussed whether coz would have gone coy even when so far away&lt;nobr&gt; &lt;&#x2F;nobr&gt;:D&lt;&#x2F;p&gt;
&lt;p&gt;Now I&#x27;m going to have another go at re-encoding DV video into XviD. Then it&#x27;s time for some sleep.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Own a domain? Then Fear the &quot;Joe Job&quot;</title>
        <published>2004-04-08T00:00:00+00:00</published>
        <updated>2004-04-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/04/08/slashdot-journal-67777-own-a-domain-then-fear-the-joe-job/"/>
        <id>https://0x5.uk/2004/04/08/slashdot-journal-67777-own-a-domain-then-fear-the-joe-job/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/04/08/slashdot-journal-67777-own-a-domain-then-fear-the-joe-job/">&lt;p&gt;Just read &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepoint.com&#x2F;article&#x2F;sabotage-coping-joe-job&quot;&gt;this&lt;&#x2F;a&gt;  article on &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepoint.com&#x2F;&quot;&gt;sitepoint&lt;&#x2F;a&gt; whilst looking into php mysql.&lt;br&gt;I received the fear.&lt;&#x2F;p&gt;
&lt;p&gt;--&lt;&#x2F;p&gt;
&lt;p&gt;Synopsis:&lt;br&gt;You upset someone, they send thousands of emails to your customers and anyone else with an email address, using your email address.&lt;br&gt;You drown under the response, taking your business with you.&lt;br&gt;This article is the survival tactics.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>File manager of fun</title>
        <published>2004-04-05T00:00:00+00:00</published>
        <updated>2004-04-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/04/05/slashdot-journal-67358-file-manager-of-fun/"/>
        <id>https://0x5.uk/2004/04/05/slashdot-journal-67358-file-manager-of-fun/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/04/05/slashdot-journal-67358-file-manager-of-fun/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.forchheimer.se&#x2F;bfm&#x2F;&quot;&gt;1st Person&lt;&#x2F;a&gt; file management.&lt;br&gt;Didn&#x27;t bother trying it, it&#x27;s still funny even if it isn&#x27;t true.&lt;br&gt;(&lt;a href=&quot;http:&#x2F;&#x2F;slashdot.org&#x2F;article.pl?sid=04&#x2F;04&#x2F;04&#x2F;1621251&quot;&gt;Slashdotted&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>swimming</title>
        <published>2004-04-02T00:00:00+00:00</published>
        <updated>2004-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/04/02/slashdot-journal-67200-swimming/"/>
        <id>https://0x5.uk/2004/04/02/slashdot-journal-67200-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/04/02/slashdot-journal-67200-swimming/">&lt;p&gt;It&#x27;s been two weeks, but I was back in the pool for training this week, and I cycled there (admittedly not entirely through choice - temporary absence of car was prime motivation). Swam 0.9km in the hour and surprisingly not that tired.&lt;&#x2F;p&gt;
&lt;p&gt;Unrelatedly, just so you know my current desktop at work is picture of v cute &amp;lt;1 month old kittens.&lt;&#x2F;p&gt;
&lt;p&gt;Never got any further with usb key thing, too much else on, and being a true programmer I&#x27;d hate to actually finish something once I&#x27;ve started it!&lt;&#x2F;p&gt;
&lt;p&gt;And J says &lt;a href=&quot;http:&#x2F;&#x2F;www.dlink.co.uk&#x2F;pages&#x2F;products&#x2F;DBT-900AP.asp&quot;&gt;bluetooth for LAN&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>beer, linux &amp; aaar.</title>
        <published>2004-03-24T00:00:00+00:00</published>
        <updated>2004-03-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/03/24/slashdot-journal-66222-beer-linux-aaar/"/>
        <id>https://0x5.uk/2004/03/24/slashdot-journal-66222-beer-linux-aaar/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/03/24/slashdot-journal-66222-beer-linux-aaar/">&lt;p&gt;Was going to write yesterday but things have been on code &quot;aaaaaarrr&quot; lately due to absence of J.&lt;&#x2F;p&gt;
&lt;p&gt;Exercise this week: nil (apart from commutating)&lt;br&gt;Beer this week: (b)(b)(b)(b)(b)(b)(b)(b)(b)&lt;&#x2F;p&gt;
&lt;p&gt;I was going to say that I&#x27;d nearly succeeded in booting a computer into linux from a usb key memory device, using &lt;a href=&quot;http:&#x2F;&#x2F;rz-obrian.rz.uni-karlsruhe.de&#x2F;knoppix-usb&#x2F;&quot;&gt;this&lt;&#x2F;a&gt; reference. And damn small linux as stated, which I already knew about.&lt;&#x2F;p&gt;
&lt;p&gt;Struggling to recompile the kernel image on my SuSE 9 box.&lt;br&gt;Why do it? Because I should be able to. And it&#x27;s satisfying. Who needs sleep anyway?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2004-03-20T00:00:00+00:00</published>
        <updated>2004-03-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/03/20/slashdot-journal-65813-swimming/"/>
        <id>https://0x5.uk/2004/03/20/slashdot-journal-65813-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/03/20/slashdot-journal-65813-swimming/">&lt;p&gt;Not a bad week on the excercise front. Was planning to swim all five days. Managed four, but failed on wed due to brain failure leading to lack of trunks at swimming pool (and no, I was not going to swim without them, or in my boxers as some have suggested). Got back in and went for a two and a half mile run, which was good, then Miss S came over and was person number two to grace my new sofa (not in the bed configuration I might add), number one was Mr T (a good friend of Miss C). Persons three and four were the folks, (hello folks!) Mr &amp;amp; Mrs A during random visit for cup of  tea and curry.&lt;&#x2F;p&gt;
&lt;p&gt;Weather: Pissy.&lt;br&gt;Motivation: Food and sleep.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Dodgy DELL drivers</title>
        <published>2004-03-17T00:00:00+00:00</published>
        <updated>2004-03-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/03/17/slashdot-journal-65483-dodgy-dell-drivers/"/>
        <id>https://0x5.uk/2004/03/17/slashdot-journal-65483-dodgy-dell-drivers/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/03/17/slashdot-journal-65483-dodgy-dell-drivers/">&lt;p&gt;Came home to find laptop with its fan on full and running at 100% cpu usage. Not good.&lt;br&gt;Culprit process was pctspk.&lt;br&gt;Found that it is related to modem drivers &lt;a href=&quot;http:&#x2F;&#x2F;www.liutilities.com&#x2F;products&#x2F;wintaskspro&#x2F;processlibrary&#x2F;pctspk&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;, and discovered this problem is &lt;a href=&quot;http:&#x2F;&#x2F;support.packardbell.dk&#x2F;pri&#x2F;index.php?PibItemNr=topic_01895&quot;&gt;known&lt;&#x2F;a&gt; to packard bell (shudder).&lt;&#x2F;p&gt;
&lt;p&gt;So I&#x27;ve dropped a support query to DELL. Wait and see time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2004-03-15T00:00:00+00:00</published>
        <updated>2004-03-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/03/15/slashdot-journal-65294-swimming/"/>
        <id>https://0x5.uk/2004/03/15/slashdot-journal-65294-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/03/15/slashdot-journal-65294-swimming/">&lt;p&gt;Swim swim swim swim. Glug splutter. Pant pant. Swim swim swim.&lt;br&gt;Ouch.&lt;&#x2F;p&gt;
&lt;p&gt;Curry&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>This weekend</title>
        <published>2004-03-14T00:00:00+00:00</published>
        <updated>2004-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/03/14/slashdot-journal-65206-this-weekend/"/>
        <id>https://0x5.uk/2004/03/14/slashdot-journal-65206-this-weekend/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/03/14/slashdot-journal-65206-this-weekend/">&lt;p&gt;This weekend went extremely well.&lt;br&gt;Friday night me and Mr T had an excellent curry at the &lt;a href=&quot;http:&#x2F;&#x2F;www.readingrestaurants.com&#x2F;Haweli&#x2F;&quot;&gt;Hawelli&lt;&#x2F;a&gt;, shame no one else came but it was good anyway,  hospitality was excellent as usual, and Juggy was down there, which was nice.&lt;br&gt;Saturday morning = sleep. Got up in time to go outside and get hailed on. (ow,  ow ow ow, ouch!). Then I cycled into Reading and bought some new shoes (-:   (pwetty dress - &lt;a href=&quot;http:&#x2F;&#x2F;www.weebl.jolt.co.uk&#x2F;shoes.htm&quot;&gt;[context]&lt;&#x2F;a&gt;).&lt;br&gt;Karaoke at the local - yay, much drunkenness.&lt;&#x2F;p&gt;
&lt;p&gt;Today, pub lunch with folks. A quick jog in the new shoes, then more sleep.&lt;&#x2F;p&gt;
&lt;p&gt;Congratulations to Joel &amp;amp; Ritu:&lt;br&gt;See &lt;a href=&quot;http:&#x2F;&#x2F;www.jmansford.f2s.com&#x2F;Jai&#x2F;&quot;&gt;this&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;www.photobox.co.uk&#x2F;public&#x2F;detail.html?c_album=612927&quot;&gt;this&lt;&#x2F;a&gt;.&lt;br&gt;Utterly adoreable.&lt;br&gt;(I work with Joel, for those who don&#x27;t know)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cycling</title>
        <published>2004-03-08T00:00:00+00:00</published>
        <updated>2004-03-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/03/08/slashdot-journal-64581-cycling/"/>
        <id>https://0x5.uk/2004/03/08/slashdot-journal-64581-cycling/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/03/08/slashdot-journal-64581-cycling/">&lt;p&gt;Went cycling with HG, Steve, Crash and Spud yesterday down in Dorking. Was super. Inlcuded in our tour a pub (of course), many miles of trail, and of note, a 30ft drop off which I probably wouldn&#x27;t have done without the encouragement of the local beer (:&lt;&#x2F;p&gt;
&lt;p&gt;Am now suitably tired. Regretted taking tonight of swimming as was bored instead, still, got some coding done and had dinner for a change. Have made up mind to go to pool super early tomorrow and do as much as possible.&lt;&#x2F;p&gt;
&lt;p&gt;Currently trying to Learn XP Pro, C# for windows apps, ASP.NET, Linux stuff and a play all at once. Struggling a little, unsurprisingly. Work is about to get even busier for me I fear, if that&#x27;s possible.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>morning</title>
        <published>2004-02-26T00:00:00+00:00</published>
        <updated>2004-02-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/02/26/slashdot-journal-63297-morning/"/>
        <id>https://0x5.uk/2004/02/26/slashdot-journal-63297-morning/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/02/26/slashdot-journal-63297-morning/">&lt;p&gt;urgh. I&#x27;m up already, going swimming today.&lt;br&gt;I&#x27;m going to have to start running soon, not looking forward to that at all.&lt;br&gt;I&#x27;ve heard that Ellen has sorted herself out and is about to get married. Go girl!&lt;br&gt;Smoking is a filthy habit and it&#x27;s starting to annoy me when people smoke in my space, guess I&#x27;d better go find my slippers and look after that comb-over.&lt;br&gt;Right. I&#x27;m off to shower.&lt;br&gt;xx&lt;br&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>swimming</title>
        <published>2004-02-26T00:00:00+00:00</published>
        <updated>2004-02-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/02/26/slashdot-journal-63307-swimming/"/>
        <id>https://0x5.uk/2004/02/26/slashdot-journal-63307-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/02/26/slashdot-journal-63307-swimming/">&lt;p&gt;well, that wasn&#x27;t too bad at all.&lt;br&gt;did 500m in first half hour (definitely not non-stop though) and then i did another couple of lengths. (35 mins in all).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>good for nothing script kiddies</title>
        <published>2004-02-26T00:00:00+00:00</published>
        <updated>2004-02-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/02/26/slashdot-journal-63429-good-for-nothing-script-kiddies/"/>
        <id>https://0x5.uk/2004/02/26/slashdot-journal-63429-good-for-nothing-script-kiddies/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/02/26/slashdot-journal-63429-good-for-nothing-script-kiddies/">&lt;p&gt;Just been looking at the web logs for my cubs website (twyfordcubs.org.uk). Some one tried to get into the admin section, they found it though google, interesting.&lt;&#x2F;p&gt;
&lt;p&gt;The log entry:&lt;br&gt;2004-02-13 06:27:21 202.152.11.98 GET&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;cubs&#x2F;admin.asp 200 2587 484 266 Mozilla&#x2F;4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0)+Opera+7.11++[en] http:&#x2F;&#x2F;www.google.com&#x2F;search?q=allinurl:.co.uk+admin.asp&amp;amp;hl=en&amp;amp;lr=&amp;amp;ie=UTF-8&amp;amp;oe=utf-8&amp;amp;start=80&amp;amp;sa=N&lt;&#x2F;p&gt;
&lt;p&gt;then, sure enough, entry in my log-on log:&lt;br&gt;login: &#x27; or 1=1--&lt;br&gt;13&#x2F;02&#x2F;2004 06:27:29     202.152.11.98     Mozilla&#x2F;4.0 (compatible; MSIE 6.0; Windows NT 5.0) Opera 7.11 [en]&lt;br&gt;Logged in: False&lt;&#x2F;p&gt;
&lt;p&gt;Pathetic attempt, but I&#x27;ll bet they get in somewhere. My company&#x27;s site for example - guess I&#x27;d better check up on that.&lt;br&gt;At least they&#x27;re using a decent browser.&lt;&#x2F;p&gt;
&lt;p&gt;backtrace:&lt;br&gt;Tracing route to sisfo2.idola.net.id [202.152.11.98]&lt;br&gt;over a maximum of 30 hops:&lt;&#x2F;p&gt;
&lt;p&gt;
    1    1 ms    1 ms    1 ms  my.router [192.168.1.1]&lt;br&gt;
    2    16 ms    16 ms    14 ms  81-86-71-1.dsl.pipex.com [81.86.72.1]&lt;br&gt;
    3    16 ms    16 ms    16 ms  62-241-161-41.dsl.pipex.com [62.241.161.41]&lt;br&gt;
    4    18 ms    16 ms    16 ms  POS4-0.GW2.LND9.ALTER.NET [146.188.56.97]&lt;br&gt;
    5    15 ms    16 ms    17 ms  so-4-0-0.xr1.lnd9.alter.net [158.43.150.157]&lt;br&gt;
    6    16 ms    15 ms    16 ms  so-0-1-0.TR1.LND9.ALTER.NET [146.188.15.33]&lt;br&gt;
    7    94 ms    93 ms    94 ms  so-7-0-0.IR1.NYC12.ALTER.NET [146.188.8.197]&lt;br&gt;
    8    94 ms    94 ms    95 ms  0.so-1-0-0.IL1.NYC9.ALTER.NET [152.63.23.61]&lt;br&gt;
    9   158 ms   160 ms   157 ms  0.so-1-1-0.TL1.SAC1.ALTER.NET [152.63.10.78]&lt;br&gt;
  10   158 ms   157 ms   157 ms  0.so-7-0-0.XL1.SAC1.ALTER.NET [152.63.53.249]&lt;br&gt;
  11   158 ms   158 ms   157 ms  0.so-3-0-0.XR1.SAC1.ALTER.NET [152.63.53.238]&lt;br&gt;
  12   157 ms   158 ms   158 ms  POS6-0.IG2.SAC1.ALTER.NET [152.63.54.113]&lt;br&gt;
  13     *        *        *     Request timed out.&lt;br&gt;
  14     *        *        *     Request timed out.&lt;&#x2F;p&gt;
&lt;p&gt;PS: I wonder if password hashing is a bit extreme for a cubs website.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Star gazing</title>
        <published>2004-02-16T00:00:00+00:00</published>
        <updated>2004-02-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/02/16/slashdot-journal-62113-star-gazing/"/>
        <id>https://0x5.uk/2004/02/16/slashdot-journal-62113-star-gazing/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/02/16/slashdot-journal-62113-star-gazing/">&lt;p&gt;I&#x27;ve got a &lt;a href=&quot;http:&#x2F;&#x2F;news.bbc.co.uk&#x2F;1&#x2F;hi&#x2F;sci&#x2F;tech&#x2F;3490657.stm&quot;&gt;galaxy cluster&lt;&#x2F;a&gt; [bbc] in my name!!! Woo yay!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>M$</title>
        <published>2004-02-16T00:00:00+00:00</published>
        <updated>2004-02-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/02/16/slashdot-journal-62169-m/"/>
        <id>https://0x5.uk/2004/02/16/slashdot-journal-62169-m/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/02/16/slashdot-journal-62169-m/">&lt;p&gt;Look, &lt;a href=&quot;http:&#x2F;&#x2F;www.microsoft.com&#x2F;technet&#x2F;treeview&#x2F;default.asp?url=&#x2F;technet&#x2F;ScriptCenter&#x2F;Tools&#x2F;twkmatic.asp&quot;&gt;comedy &lt;&#x2F;a&gt; from Micro$oft!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Balls!</title>
        <published>2004-02-14T00:00:00+00:00</published>
        <updated>2004-02-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/02/14/slashdot-journal-61964-balls/"/>
        <id>https://0x5.uk/2004/02/14/slashdot-journal-61964-balls/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/02/14/slashdot-journal-61964-balls/">&lt;p&gt;Yay! My snooker table is here. Anyone fancy a game? Shame I haven&#x27;t got room to put it up at the moment.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>swimming</title>
        <published>2004-02-13T00:00:00+00:00</published>
        <updated>2004-02-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/02/13/slashdot-journal-61917-swimming/"/>
        <id>https://0x5.uk/2004/02/13/slashdot-journal-61917-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/02/13/slashdot-journal-61917-swimming/">&lt;p&gt;Looks like i&#x27;m turning into a fitness phreak. Since I started I have been swimming: Mon eve, Tue am, Wed eve, Thur am, Mon eve, Tue am, Wed eve, Mon eve, Wed eve, Thur am and this evening (Fri).&lt;br&gt;Now I&#x27;m knackered. Should be a &#x27;large&#x27; weekend though&lt;nobr&gt; &lt;&#x2F;nobr&gt;;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hulloa</title>
        <published>2004-02-05T00:00:00+00:00</published>
        <updated>2004-02-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/02/05/slashdot-journal-60927-hulloa/"/>
        <id>https://0x5.uk/2004/02/05/slashdot-journal-60927-hulloa/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/02/05/slashdot-journal-60927-hulloa/">&lt;p&gt;Gosh, it&#x27;s 7 days since i wrote here.&lt;br&gt;I&#x27;m back to my nocturnal ways - such is the way of the geek.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve joined our friendly local &lt;a href=&quot;http:&#x2F;&#x2F;www.thamesvalleytri.f9.co.uk&#x2F;&quot;&gt;triathletes&lt;&#x2F;a&gt;, who have been teaching me to &quot;swim&quot;, I can nearly front crawl now. This is why I&#x27;ve given up logging my distances for the moment, I need to get the technique sussed before I worry too  much about the fitness. Having said that I believe I managed 20+ lengths (25m) on wed eve in the hour&#x27;s training, mostly in front crawl which was an achievement for me. (Bear in mind I only started swimming in Nov &#x27;03.&lt;&#x2F;p&gt;
&lt;p&gt;right, back to attempt 4 at suse linux&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
&lt;p&gt;ps:&lt;br&gt;Coz beat me in oz:&lt;br&gt;42 lengths of 51.5 meters in 1.5 hours&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Things + lycra swimwear &amp; goggles</title>
        <published>2004-01-29T00:00:00+00:00</published>
        <updated>2004-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/29/slashdot-journal-60096-things--lycra-swimwear-goggles/"/>
        <id>https://0x5.uk/2004/01/29/slashdot-journal-60096-things--lycra-swimwear-goggles/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/29/slashdot-journal-60096-things--lycra-swimwear-goggles/">&lt;p&gt;Given up counting lengths. Working on technique now (think - &quot;I like your style!&quot;). That&#x27;s not to say I&#x27;ve missed any sessions, in fact quite the opposite, I&#x27;ve been four times this week. Met up with the Triathletes on Monday, swam tues am practicing what I&#x27;d been taught, back with the triathletes wed eve (after drama tues night, first rehearsal) got more help from Mark (thnks mark, much appreciated) and could feel I was getting closer, if not faster, then usual thur am session for more practice, with some degree of success. Been at jongleurs tonight for laughs and cavorting, a good night was had by all (I think).&lt;&#x2F;p&gt;
&lt;p&gt;Back to town for proper session tomorrow with A and others, should be messy&lt;nobr&gt; &lt;&#x2F;nobr&gt;;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>You, yes you, reading my &#x2F;. journal</title>
        <published>2004-01-29T00:00:00+00:00</published>
        <updated>2004-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/29/slashdot-journal-60097-you-yes-you-reading-my--journal/"/>
        <id>https://0x5.uk/2004/01/29/slashdot-journal-60097-you-yes-you-reading-my--journal/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/29/slashdot-journal-60097-you-yes-you-reading-my--journal/">&lt;p&gt;Drop me a line, any line. I want to know who reads this. You could add a comment if you don&#x27;t mind everyone else seeing.&lt;&#x2F;p&gt;
&lt;p&gt;xx&lt;&#x2F;p&gt;
&lt;p&gt;Tim&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Morning</title>
        <published>2004-01-20T00:00:00+00:00</published>
        <updated>2004-01-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/20/slashdot-journal-58959-morning/"/>
        <id>https://0x5.uk/2004/01/20/slashdot-journal-58959-morning/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/20/slashdot-journal-58959-morning/">&lt;p&gt;Look, I&#x27;m up. At 6AM, just to go swimming.&lt;&#x2F;p&gt;
&lt;p&gt;Wierd.&lt;&#x2F;p&gt;
&lt;p&gt;Might as well download Mandrake &lt;a href=&quot;http:&#x2F;&#x2F;www.mandrakelinux.com&#x2F;en&#x2F;mandrakemove&#x2F;&quot;&gt;Move&lt;&#x2F;a&gt; while I&#x27;m at it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2004-01-20T00:00:00+00:00</published>
        <updated>2004-01-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/20/slashdot-journal-58974-swimming/"/>
        <id>https://0x5.uk/2004/01/20/slashdot-journal-58974-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/20/slashdot-journal-58974-swimming/">&lt;p&gt;26 lengths today, 45 mins. Then a bacon sarny in the local caf.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Drama</title>
        <published>2004-01-19T00:00:00+00:00</published>
        <updated>2004-01-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/19/slashdot-journal-58867-drama/"/>
        <id>https://0x5.uk/2004/01/19/slashdot-journal-58867-drama/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/19/slashdot-journal-58867-drama/">&lt;p&gt;I am now associated with this bunch of &lt;a href=&quot;http:&#x2F;&#x2F;www.twyrusdrama.org.uk&#x2F;&quot;&gt;t.a.r.t.s&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Having helped out backstage with Treasure Island. Which was great fun.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2004-01-15T00:00:00+00:00</published>
        <updated>2004-01-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/15/slashdot-journal-58405-swimming/"/>
        <id>https://0x5.uk/2004/01/15/slashdot-journal-58405-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/15/slashdot-journal-58405-swimming/">&lt;p&gt;20 lengths today. In 45 mins. Did quite a lot in front crawl today so am quite pleased, then I used one of those float things so I could just use my legs. Apparently my kicking for front crawl adds nothing to my forwards movement but still wears me out, that might explain why I have such difficulty with front crawl. Think I&#x27;ll need to work on that one. My legs seem quite good at breast stroke style swimming as I can quite easily do a length that way. I did do a couple of really fast lengths (by my standards), one in front crawl, the other in breast stroke. Oh, and just because I like being a bit sad sometimes, I counted some of the lengths in binary.&lt;nobr&gt; &lt;&#x2F;nobr&gt;:D&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2004-01-13T00:00:00+00:00</published>
        <updated>2004-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/13/slashdot-journal-58121-swimming/"/>
        <id>https://0x5.uk/2004/01/13/slashdot-journal-58121-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/13/slashdot-journal-58121-swimming/">&lt;p&gt;1km, I did it! 40 lengths. In 50 mins. Must&#x27;ve been the new trunks that did it, so much more comfortable, and so much less hastle, even if they  are slightly embarrasing.&lt;br&gt;I did drive in mind. But I shall still be on my bike to work, just had to come back here in between to get the car picked up.&lt;&#x2F;p&gt;
&lt;p&gt;I am sooo tired. I&#x27;ve been &quot;helping&quot; the local drama bunch lately, so I was out till late last night again, then I had to go to Asda coz my cupboards were bear. Not without going to the pub first of course!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bloody Banks</title>
        <published>2004-01-13T00:00:00+00:00</published>
        <updated>2004-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/13/slashdot-journal-58139-bloody-banks/"/>
        <id>https://0x5.uk/2004/01/13/slashdot-journal-58139-bloody-banks/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/13/slashdot-journal-58139-bloody-banks/">&lt;p&gt;Cahoot just managed to cost me 80 pounds, in a day.&lt;&#x2F;p&gt;
&lt;p&gt;==============================&lt;br&gt;To: service.relationship.team@cahoot.com&lt;br&gt;Subject: Banking error.&lt;&#x2F;p&gt;
&lt;p&gt;Hello,&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ve bounced three transactions on my current account and charged me £60 all on the 12th Jan. Despite there being a transfer to cover the whole amount made on the same day.&lt;&#x2F;p&gt;
&lt;p&gt;I am very annoyed and will be leaving cahoot unless this is resolved to my satisfaction.&lt;&#x2F;p&gt;
&lt;p&gt;Please refund the £60 to my account immediately and make arrangements to cover charges I will receive for the three failed transactions, plus a small sum to cover the expenses I will incur in dealing with BT, Egg &amp;amp; Student Loans Co.&lt;&#x2F;p&gt;
&lt;p&gt;Egg will charge £20.&lt;br&gt;I have yet to contact BT and Student Loans Co, but doubtless sorting this out will be a problem.&lt;&#x2F;p&gt;
&lt;p&gt;Yours&lt;&#x2F;p&gt;
&lt;p&gt;Tim Abell.&lt;&#x2F;p&gt;
&lt;p&gt;--------------------&lt;br&gt;Edit:&lt;br&gt;After much email ping pong they finally refunded the 60 quid they charged me. Still moving banks tho.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2004-01-08T00:00:00+00:00</published>
        <updated>2004-01-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/08/slashdot-journal-57574-swimming/"/>
        <id>https://0x5.uk/2004/01/08/slashdot-journal-57574-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/08/slashdot-journal-57574-swimming/">&lt;p&gt;24 lengths today, but in a slightly dismal 40 minutes.&lt;&#x2F;p&gt;
&lt;p&gt;Still I am getting better. Did much more front crawl today (still mostly half lengths) but did swallow&#x2F;breath a fairly significant amount of chlorinated water.&lt;&#x2F;p&gt;
&lt;p&gt;From the 3 lengths I managed on the 2nd Dec 03, in an hour. That&#x27;s much better.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been : Tue &amp;amp; Thur 2,4,9,11,16,18,23rd Dec, Sat 3rd Jan, Tue &amp;amp; Thur 6, 8th Jan.&lt;br&gt;That&#x27;s.... 10 times! Yay.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2004-01-06T00:00:00+00:00</published>
        <updated>2004-01-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/06/slashdot-journal-57382-swimming/"/>
        <id>https://0x5.uk/2004/01/06/slashdot-journal-57382-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/06/slashdot-journal-57382-swimming/">&lt;p&gt;Did exactly 20 lengths today in just 35 mins. then cycled all the way home to sort out this laptop.&lt;&#x2F;p&gt;
&lt;p&gt;Good timing on the laptop, I&#x27;d just brought it home when the system partition on my only other box just completely failed. The system then wouldn&#x27;t boot at all. So I chucked in a small disk with a working 2k install as a primary master, check disk then kindly removed 70% of the files on my main system partition. Woop. Hello linux.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2004-01-03T00:00:00+00:00</published>
        <updated>2004-01-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2004/01/03/slashdot-journal-57000-swimming/"/>
        <id>https://0x5.uk/2004/01/03/slashdot-journal-57000-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2004/01/03/slashdot-journal-57000-swimming/">&lt;p&gt;Got up this morning and cycled to the pool. Swam 20 lengths (I think) in about 40 mins, at which point some french fish like people turned up and put me to shame. The mum dived in one end and covered half the length of the pool before even taking a stroke (or surfacing) then covered the rest in what seemed like three strokes. Bet she had no idea how hard it is for me to cover that distance.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe I need lessons. I spotted a Reading Swimming Club bag in the changing rooms which is a bit of a clue.&lt;&#x2F;p&gt;
&lt;p&gt;Then I cycled back via the bike shop, which wasn&#x27;t even open yet, so my gear changer is still bust. Though I did discover the &lt;a href=&quot;http:&#x2F;&#x2F;www.slimsmith.com&#x2F;rcc&#x2F;home.html&quot;&gt;reading cycling bunch&lt;&#x2F;a&gt; have a stand in Reading market on the first Saturday of the month, which is today I think.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Music - bad response</title>
        <published>2003-12-28T00:00:00+00:00</published>
        <updated>2003-12-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/28/slashdot-journal-56467-music---bad-response/"/>
        <id>https://0x5.uk/2003/12/28/slashdot-journal-56467-music---bad-response/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/28/slashdot-journal-56467-music---bad-response/">&lt;p&gt;There&#x27;s a reason fruityloops shouldn&#x27;t have a free demo... and it sounds like &lt;a href=&quot;http:&#x2F;&#x2F;www.t.abell.dsl.pipex.com&#x2F;music&#x2F;unlit-ted1.mp3&quot;&gt;this&lt;&#x2F;a&gt; (consider this copylefted).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2003-12-23T00:00:00+00:00</published>
        <updated>2003-12-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/23/slashdot-journal-56056-swimming/"/>
        <id>https://0x5.uk/2003/12/23/slashdot-journal-56056-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/23/slashdot-journal-56056-swimming/">&lt;p&gt;Yay! Personal best.&lt;br&gt;36 lengths in one hour. That&#x27;s 900 metres.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2003-12-19T00:00:00+00:00</published>
        <updated>2003-12-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/19/slashdot-journal-55743-swimming/"/>
        <id>https://0x5.uk/2003/12/19/slashdot-journal-55743-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/19/slashdot-journal-55743-swimming/">&lt;p&gt;Didn&#x27;t remember to write entry on Thur as had manic morning at work (what&#x27;s new?) then xmas drinks in the afternoon (and we won&#x27;t talk about the evening other than saying I regret it... urrrgh).&lt;br&gt;In other news, I made it into the pool in time for 35 mins swimming and managed 22 lengths I think. Including two not very successful attempts at a front crawl &#x2F; breathing water.&lt;&#x2F;p&gt;
&lt;p&gt;Irrelevantly: I just got vnc viewer working on my P800 and can actually see these words in this form on it. Woo! Cool, but not useful (sorry Negi).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2003-12-16T00:00:00+00:00</published>
        <updated>2003-12-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/16/slashdot-journal-55282-swimming/"/>
        <id>https://0x5.uk/2003/12/16/slashdot-journal-55282-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/16/slashdot-journal-55282-swimming/">&lt;p&gt;Been swimming again this morning. Got up in time today so had 45mins in the pool, and managed a staggering 25 lengths (625 metres).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m quite pleased with that. And as usual celebrated with a cup of tea in the local cafe. This morning I was joined by my gorgeous assistant, R.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Anargams</title>
        <published>2003-12-12T00:00:00+00:00</published>
        <updated>2003-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/12/slashdot-journal-54879-anargams/"/>
        <id>https://0x5.uk/2003/12/12/slashdot-journal-54879-anargams/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/12/slashdot-journal-54879-anargams/">&lt;p&gt;Anagrams of Timothy Abell (yes, that&#x27;s me.)&lt;br&gt;Can&#x27;t remember where I got it. some link off b3ta I expect.&lt;&#x2F;p&gt;
&lt;p&gt;Hot Meaty Bill&lt;br&gt;I&#x27;m the tall boy&lt;br&gt;AH BE TIT MOLLY&lt;br&gt;AH IBM TO TELLY&lt;br&gt;TOBY A H MILLET&lt;br&gt;THAI BE MY TOLL&lt;br&gt;HALLO IM BETTY&lt;br&gt;MY HALO BE TILT&lt;br&gt;BYE TO ILL MATH&lt;br&gt;LET MY HAT BOIL&lt;br&gt;BET I&#x27;M THY LOLA&lt;br&gt;THY LOLA BIT ME!&lt;br&gt;TOTALLY BE HIM&lt;br&gt;ME HIT TALL BOY&lt;br&gt;LAY THE TO LIMB&lt;br&gt;AM BILL THE TOY&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Also - music</title>
        <published>2003-12-12T00:00:00+00:00</published>
        <updated>2003-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/12/slashdot-journal-54880-also---music/"/>
        <id>https://0x5.uk/2003/12/12/slashdot-journal-54880-also---music/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/12/slashdot-journal-54880-also---music/">&lt;p&gt;I wrote a song to be played by &lt;a href=&quot;http:&#x2F;&#x2F;www.sr.se&#x2F;cgi-bin&#x2F;p1&#x2F;src&#x2F;sing&#x2F;default.asp&quot;&gt;&lt;&#x2F;a&gt;&lt;br&gt;this singing thing&lt;br&gt;&lt;i&gt;&lt;br&gt;be happy, don&#x27;t worry.&lt;br&gt;feel glad, it&#x27;s not that bad&lt;br&gt;the sun shines,&lt;br&gt;our friends are close to us&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;i&gt;all the fear is far away&lt;br&gt;so be happy and be gay&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2003-12-11T00:00:00+00:00</published>
        <updated>2003-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/11/slashdot-journal-54782-swimming/"/>
        <id>https://0x5.uk/2003/12/11/slashdot-journal-54782-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/11/slashdot-journal-54782-swimming/">&lt;p&gt;16 lengths in half hour. not bad. (400m)&lt;br&gt;still haven&#x27;t had enough sleep.&lt;&#x2F;p&gt;
&lt;p&gt;boo for Quake 3 keeping me up.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Eddie Izzard</title>
        <published>2003-12-05T00:00:00+00:00</published>
        <updated>2003-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/05/slashdot-journal-54225-eddie-izzard/"/>
        <id>https://0x5.uk/2003/12/05/slashdot-journal-54225-eddie-izzard/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/05/slashdot-journal-54225-eddie-izzard/">&lt;p&gt;Yay for eddie izzard at the Birmingham NIA.&lt;br&gt;Yay for not enough sleep.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Splash</title>
        <published>2003-12-04T00:00:00+00:00</published>
        <updated>2003-12-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/04/slashdot-journal-54069-splash/"/>
        <id>https://0x5.uk/2003/12/04/slashdot-journal-54069-splash/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/04/slashdot-journal-54069-splash/">&lt;p&gt;Yay! I did TWENTY! lengths of the pool this morning. It&#x27;s a 25 metre pool so that&#x27;s half a kilometer! Did take 3&#x2F;4 hour mind, with lots of panting between lengths.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>WhoIs Privacy</title>
        <published>2003-12-04T00:00:00+00:00</published>
        <updated>2003-12-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/04/slashdot-journal-54070-whois-privacy/"/>
        <id>https://0x5.uk/2003/12/04/slashdot-journal-54070-whois-privacy/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/04/slashdot-journal-54070-whois-privacy/">&lt;p&gt;Just came accross &lt;a href=&quot;http:&#x2F;&#x2F;www.internetprivacyadvocate.org&#x2F;ProtectYourPersonalInfo.htm&quot;&gt; this&lt;&#x2F;a&gt;. Network Solutions wants to end publicising who owns domain names. My response follow:&lt;&#x2F;p&gt;
&lt;p&gt;[x] I am not a Network Solutions customer&lt;br&gt;[x] The privacy of my personal data is important to me.&lt;br&gt;[ ] I support WHOIS rules that would limit online access to my personal information.&lt;br&gt;[ ] I offer strong support to proposals that promote personal privacy and rules that restrict providing my information to third-party organizations. This includes Network Solutions&#x27; proposal to the Internet Corporation for Assigned Names and Numbers (ICANN) to eliminate the Bulk WHOIS access obligation.&lt;&#x2F;p&gt;
&lt;p&gt;Comments&lt;br&gt;---------&lt;br&gt;I think it is important that such information remain publically available. If you don&#x27;t like what people use it for then persue that line instead of trying to hide who you are. If enough people put effort into preventing abuse (ambiguous I know) of &quot;the internet&quot; then the problems of abuse will be diminished.&lt;&#x2F;p&gt;
&lt;p&gt;Pretending you don&#x27;t exist will leave us all worse off, and make tracking down abuse harder.&lt;&#x2F;p&gt;
&lt;p&gt;------------&lt;br&gt;I think the second point is there just to achieve a good number so they can skew the meaning later.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sooooo long</title>
        <published>2003-12-03T00:00:00+00:00</published>
        <updated>2003-12-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/03/slashdot-journal-53994-sooooo-long/"/>
        <id>https://0x5.uk/2003/12/03/slashdot-journal-53994-sooooo-long/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/03/slashdot-journal-53994-sooooo-long/">&lt;p&gt;Twenty Eight Days till they&#x27;re out of my life.&lt;&#x2F;p&gt;
&lt;p&gt;&amp;gt;:(&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;dictionary.reference.com&#x2F;search?r=2&amp;amp;q=treachery&quot;&gt;Treachery&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Swimming</title>
        <published>2003-12-02T00:00:00+00:00</published>
        <updated>2003-12-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/12/02/slashdot-journal-53812-swimming/"/>
        <id>https://0x5.uk/2003/12/02/slashdot-journal-53812-swimming/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/12/02/slashdot-journal-53812-swimming/">&lt;p&gt;Yay! I swam this morning. Well done me.&lt;br&gt;I managed about three complete lengths, in 45 mins.&lt;br&gt;My god I&#x27;m soo unfit. Well, at least the only way is up.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nigerian Scam</title>
        <published>2003-11-29T00:00:00+00:00</published>
        <updated>2003-11-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/11/29/slashdot-journal-53554-nigerian-scam/"/>
        <id>https://0x5.uk/2003/11/29/slashdot-journal-53554-nigerian-scam/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/11/29/slashdot-journal-53554-nigerian-scam/">&lt;p&gt;Edit: Apparently indiatimes is genuine. (sorry! India Times) must&#x27;ve been just a webmail account. Couldn&#x27;t see half the site from home. Oh well. Maybe this isn&#x27;t so exciting then. -4&#x2F;12&#x2F;03&lt;br&gt;------------------------------------------&lt;&#x2F;p&gt;
&lt;p&gt;Thought I&#x27;d do some detective work today.&lt;br&gt;This is a bit of an obtuse one, but here goes anyway.&lt;&#x2F;p&gt;
&lt;p&gt;I received a copy of the negeria scam via email (Appendix 1).&lt;&#x2F;p&gt;
&lt;p&gt;Facts:&lt;&#x2F;p&gt;
&lt;p&gt;source IP address: 192.116.66.219&lt;br&gt;spam sourced using a &lt;a href=&quot;http:&#x2F;&#x2F;www.nyc.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.nyc.com&#x2F;&lt;&#x2F;a&gt; mail account&lt;br&gt;reply address 1: vinobi2000@go.com&lt;br&gt;reply address 2: applefamily@indiatimes.com&lt;&#x2F;p&gt;
&lt;p&gt;Analysis:&lt;&#x2F;p&gt;
&lt;p&gt;Interesting trace, the source IP Address is owned by SKY2Net ltd. (GILAT-SATCOM-BLOCK-31-32-40-46)&lt;br&gt;Are the spammers using satellite technology to avoid being tracked down?&lt;&#x2F;p&gt;
&lt;p&gt;I had a look at nyc.com and it appears to have a valid web-mail service&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;nyc-mail.nyc.com&#x2F;cgi-bin&#x2F;signup&#x2F;signup.pl&quot;&gt;https:&#x2F;&#x2F;nyc-mail.nyc.com&#x2F;cgi-bin&#x2F;signup&#x2F;signup.pl&lt;&#x2F;a&gt;&lt;br&gt;Think I sent them a mail to their abuse section.&lt;&#x2F;p&gt;
&lt;p&gt;Go.com is valid and provides a web based email service which can be gained online&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;register.go.com&#x2F;go&#x2F;register&quot;&gt;https:&#x2F;&#x2F;register.go.com&#x2F;go&#x2F;register&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I looked at &lt;a href=&quot;http:&#x2F;&#x2F;www.indiatimes.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.indiatimes.com&#x2F;&lt;&#x2F;a&gt;&lt;br&gt;There&#x27;s a reasonably convincing first page (plenty of adverts - if we can&#x27;t be conned then I suppose a bit of advertising kick-back will do!), however you can&#x27;t get many other pages and the &quot;site&quot; quickly looks flaky. I reckon this was set up by the spammers to convince people the address was valid.&lt;br&gt;The site seems to exists on multiple IP addresses. See: &lt;a href=&quot;http:&#x2F;&#x2F;uptime.netcraft.com&#x2F;up&#x2F;graph?site=www.indiatimes.com&quot;&gt;http:&#x2F;&#x2F;uptime.netcraft.com&#x2F;up&#x2F;graph?site=www.indiatimes.com&lt;&#x2F;a&gt; where all the IP addresses seem to be listed. Which address you get changes regularly (minutes apart) - see Appendix 6&lt;br&gt;Appendix 3 contains one of the traces, which finishes with an unreachable domain name. Very odd.&lt;&#x2F;p&gt;
&lt;p&gt;looking up the MX records reveals the mail server to be smtp.indiatimes.com (Appendix 4)&lt;&#x2F;p&gt;
&lt;p&gt;smtp.indiatimes.com (203.199.93.5) seems to work but is hosted somewhere else,  couldn&#x27;t get any useful info out of tracert or ripe.net. (Appendices 2 and 5)&lt;&#x2F;p&gt;
&lt;p&gt;Conclusions?&lt;br&gt;None&lt;br&gt;I hate people who exploit other people. Through whatever means &amp;amp; medium.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt; &lt;i&gt;Appendices:&lt;&#x2F;i&gt; &lt;&#x2F;b&gt;&lt;br&gt;&lt;b&gt;1) The received email (with headers)&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From:     - Tue Nov 25 07:46:47 2003&lt;br&gt;X-UIDL:     &amp;lt;1618.192.116.66.219.1069698616.squirrel@mail-nyc.nyc.com&amp;gt;&lt;br&gt;X-Mozilla-Status:     1001&lt;br&gt;X-Mozilla-Status2:     00000000&lt;br&gt;Return-Path:     &amp;lt;mabacha@nyc.com&amp;gt;&lt;br&gt;Received:     from nyc-mail.nyc.com ([66.111.12.66]) by mta6-svc.business.ntl.com (InterMail vM.4.01.03.37&lt;br&gt;201-229-121-137-20020806) with SMTP id &amp;lt;20031124183749.KMRS21828.mta6-svc.business.ntl.com@nyc-mail.nyc.com&amp;gt; for&lt;br&gt;&amp;lt;t.abell@virgin.net&amp;gt;; Mon, 24 Nov 2003 18:37:49 +0000&lt;br&gt;Received:     (qmail 45052 invoked by uid 79); 24 Nov 2003 18:30:17 -0000&lt;br&gt;Received:     from 192.116.66.219 (NYC.com Mail authenticated user mabacha@nyc.com) by mail-nyc.nyc.com with HTTP; Tue, 25&lt;br&gt;Nov 2003 02:30:16 +0800 (SGT)&lt;br&gt;Message-ID:     &amp;lt;1618.192.116.66.219.1069698616.squirrel@mail-nyc.nyc.com&amp;gt;&lt;br&gt;Date:     Tue, 25 Nov 2003 02:30:16 +0800 (SGT)&lt;br&gt;Subject:     REPLY URGENTLY&lt;br&gt;From:     Muhammed &amp;lt;mabacha@nyc.com&amp;gt;&lt;br&gt;To:     applefamily@indiatimes.com&lt;br&gt;User-Agent:     NYC.com Mail&#x2F;1.4.2&lt;br&gt;MIME-Version:     1.0&lt;br&gt;Content-Type:     text&#x2F;plain;charset=iso-8859-1&lt;br&gt;Content-Transfer-Encoding:     8bit&lt;&#x2F;p&gt;
&lt;p&gt;VERY URGENT AND STRICTLY CONFIDENTIAL BUSINESS PROPOSAL.&lt;&#x2F;p&gt;
&lt;p&gt;PLEASE I WANT YOU TO RELPY ME THIS MAIL TO MY ALTERNATIVE EMAIL ADDRESSES&lt;br&gt;vinobi2000@go.com and applefamily@indiatimes.com&lt;&#x2F;p&gt;
&lt;p&gt;Dear Sir,&lt;&#x2F;p&gt;
&lt;p&gt;I am MR. MOHAMMED ABACHA the son of the late Gen. Sani Abacha, former head&lt;br&gt;of State of Nigeria who died on 8th June 1998 while in office. Since the&lt;br&gt;death of my father the present Government of Chief Olusegun Obasanjo has&lt;br&gt;been tormenting members of the Abachas family including family friends.&lt;br&gt;All businesses and property owned by the Abachas have been confiscated by&lt;br&gt;the Government and all our Bank Account in Nigeria and abroad have been&lt;br&gt;frozen. A quick reference of Newsweek publication of March 13th 1999 were&lt;br&gt;88million dollars was taken from us will give you an insight of what I&lt;br&gt;have gone through. After a short while I was arrested and detained in&lt;br&gt;prison custody,  the government came up with a trump up charge against me&lt;br&gt;and honestly speaking I have been in detention since November 1999 and I&lt;br&gt;was only released on Thursdays (11-07-02) by the supreme court of Nigeria&lt;br&gt;who passed judgment in my favor.&lt;&#x2F;p&gt;
&lt;p&gt;During the reign of my father as the president of this country, an&lt;br&gt;Aluminum Smelter Company of Nigeria (Alscom) contract was revealed. The&lt;br&gt;contract was for the construction of plant, at Ikuta Abasi in Akwa Ibom&lt;br&gt;State of Nigeria, for production of ingots and billets required as raw&lt;br&gt;material for Aluminum and Allied Industries, Reynolds Incorporated of&lt;br&gt;America, Phoenix and M&amp;amp;F Companies of Switzerland conducted the&lt;br&gt;feasibility studies. The contract was awarded to Ferrostall AG of Germany.&lt;br&gt;However, after the revaluation of the contract, Ferrostall AG collected&lt;br&gt;its own share of the increment in project cost, while my father&#x27;s share of&lt;br&gt;fifty-eight Million U.S. Dollars (US$58,000,000:00) was deposited on my&lt;br&gt;name with a security company here in Nigeria for safety keep and I know&lt;br&gt;that my father was planning of how to send this money abroad before his&lt;br&gt;sudden death in June 8 1998. Since then the money has been with the&lt;br&gt;security company up till date. This US$58M was secretly packaged in a&lt;br&gt;trunk box and the certificate of deposit where on my name and is still in&lt;br&gt;my possession.&lt;&#x2F;p&gt;
&lt;p&gt;Hence all plane is to ship this money abroad through a diplomatic means&lt;br&gt;without the knowledge of anybody from outside knowing my involvement in&lt;br&gt;this money, to avoid be seized due to my presently situation and also I am&lt;br&gt;handicapped as what next to do since I am not conversant with&lt;br&gt;international monitory policies. Hence I am contacting you as a reputable&lt;br&gt;and trustworthy person, with a well experience and able hand to help. This&lt;br&gt;was to bit the security system in Nigeria Because I want you to claim the&lt;br&gt;money on my behalf. I have declared to the security company that the&lt;br&gt;consignment belongs to (YOU) as my foreign business partners.  Actually I&lt;br&gt;got your contact from a reliable source, and also I believe you are in a&lt;br&gt;good position to assist me to transfer this fund for good investment.&lt;&#x2F;p&gt;
&lt;p&gt;Upon receipt of your willingness to assist me claim this money I will then&lt;br&gt;contact my personal attorney to draft a power of attorney that will&lt;br&gt;authorize you as the beneficially of this money so that you can handle&lt;br&gt;this transaction on my behalf. And as soon as this money leaves Nigeria I&lt;br&gt;will travel out to seek asylum either in Europe or America. My contract&lt;br&gt;with APEX FINANCE AND SECURITIES GROUP remains few weeks to expire and I&lt;br&gt;am down broke to renew the duration with the Security Company.&lt;&#x2F;p&gt;
&lt;p&gt;As a matter of urgency, I will like you to send to me immediately your&lt;br&gt;telephone and fax number. I shall send you all the clearance documents by&lt;br&gt;fax. I will then forward your name as the beneficiary and my foreign&lt;br&gt;business partner to the Security Company. You will be entitled to 20% of&lt;br&gt;the total sum involved for your assistance, 5% will be set aside for&lt;br&gt;reimbursement to you for any incidental expenses that may be incurred in&lt;br&gt;the course of the transaction. Your URGENT response is needed. I want you&lt;br&gt;to call my Attorney Mr. Lawrence Daniel on 234 1 7765468 for more detailed&lt;br&gt;directives information and the nest required step of how we have to make&lt;br&gt;move immediately as i have told him about you and he is to handle all the&lt;br&gt;processing with you on my behalf.  All your REPLY must go through these&lt;br&gt;our family private email address: vinobi2000@go.com and&lt;br&gt;applefamily@indiatimes.com , I will also need your private and direct&lt;br&gt;telephone and fax number for easy reach.&lt;&#x2F;p&gt;
&lt;p&gt;Please this is a very confidential matter, you don&#x27;t disclose to anybody&lt;br&gt;for us to have success.&lt;&#x2F;p&gt;
&lt;p&gt;Best regard&lt;&#x2F;p&gt;
&lt;p&gt;MR MOHAMMED ABACHA&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;2) The smtp server ehlo&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
&lt;p&gt;telnet smtp.indiatimes.com 25&lt;&#x2F;p&gt;
&lt;p&gt;ehlo me&lt;br&gt;220 Sat, ESMTP 29 Nov 2003 19:49:07 +0530&lt;br&gt;250-localhost.localdomain Hello 81-86-251-237.dsl.pipex.com [81.86.251.237], pleased to meet you&lt;br&gt;250-8BITMIME&lt;br&gt;250-SIZE&lt;br&gt;250-DSN&lt;br&gt;250-ONEX&lt;br&gt;250-ETRN&lt;br&gt;250-XUSR&lt;br&gt;250 HELP&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;3) A trace route to www.indiatimes.com (one of a varying set)&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;tracert www.indiatimes.com&lt;&#x2F;p&gt;
&lt;p&gt;Tracing route to indiatime.speedera.net [195.50.97.131]&lt;br&gt;over a maximum of 30 hops:&lt;&#x2F;p&gt;
&lt;p&gt;
    1    21 ms   &amp;lt;10 ms    10 ms  my.router [192.168.1.1]&lt;br&gt;
    2    20 ms    20 ms    10 ms  81-86-240-1.dsl.pipex.com [81.86.240.1]&lt;br&gt;
    3     *        *        *     Request timed out.&lt;br&gt;
    4    20 ms    20 ms    20 ms  POS4-0.GW1.LND9.ALTER.NET [146.188.63.105]&lt;br&gt;
    5    20 ms    20 ms    20 ms  so-3-0-0.xr1.lnd9.alter.net [158.43.150.141]&lt;br&gt;
    6    20 ms    20 ms    20 ms  so-0-1-0.TR1.LND9.ALTER.NET [146.188.15.33]&lt;br&gt;
    7    20 ms    20 ms    20 ms  POS1-0.BR1.LND9.ALTER.NET [146.188.7.242]&lt;br&gt;
    8    20 ms    20 ms    20 ms  146.188.68.210&lt;br&gt;
    9    10 ms    10 ms    20 ms  ge-7-0.ipcolo1.London1.Level3.net [212.187.131.131]&lt;br&gt;
  10    20 ms    20 ms    20 ms  195.50.117.22&lt;br&gt;
  11    20 ms    20 ms    30 ms  www.crone-corkhill.co.uk [195.50.97.131]&lt;&#x2F;p&gt;
&lt;p&gt;Trace complete.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;4) mx nslookup of indiatimes.com&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;nslookup&lt;br&gt;Default Server:  cache0005.ns.eu.uu.net&lt;br&gt;Address:  158.43.240.3&lt;&#x2F;p&gt;
&lt;p&gt;&amp;gt; set type=mx&lt;br&gt;&amp;gt; indiatimes.com&lt;br&gt;Server:  cache0005.ns.eu.uu.net&lt;br&gt;Address:  158.43.240.3&lt;&#x2F;p&gt;
&lt;p&gt;Non-authoritative answer:&lt;br&gt;indiatimes.com  MX preference = 5, mail exchanger = smtp.indiatimes.com&lt;&#x2F;p&gt;
&lt;p&gt;indiatimes.com  nameserver = timesgate2.toi.co.in&lt;br&gt;indiatimes.com  nameserver = ulka.timesgroup.com&lt;br&gt;indiatimes.com  nameserver = ethome.dhakdhak.com&lt;br&gt;indiatimes.com  nameserver = timesgate.toi.co.in&lt;br&gt;timesgate2.toi.co.in    internet address = 203.200.77.20&lt;br&gt;ulka.timesgroup.com     internet address = 203.199.42.201&lt;br&gt;ethome.dhakdhak.com     internet address = 203.199.70.133&lt;br&gt;timesgate.toi.co.in     internet address = 203.200.107.162&lt;br&gt;&amp;gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;5) Trace to smtp.indiatimes.com server&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;tracert smtp.indiatimes.com&lt;&#x2F;p&gt;
&lt;p&gt;Tracing route to smtp.indiatimes.com [203.199.93.5]&lt;br&gt;over a maximum of 30 hops:&lt;&#x2F;p&gt;
&lt;p&gt;
    1    20 ms   &amp;lt;10 ms   &amp;lt;10 ms  my.router [192.168.1.1]&lt;br&gt;
    2    10 ms    20 ms    20 ms  81-86-240-1.dsl.pipex.com [81.86.240.1]&lt;br&gt;
    3     *        *        *     Request timed out.&lt;br&gt;
    4    20 ms    30 ms    20 ms  POS5-0.GW2.LND9.ALTER.NET [146.188.56.101]&lt;br&gt;
    5    20 ms    20 ms    21 ms  so-4-0-0.xr1.lnd9.alter.net [158.43.150.157]&lt;br&gt;
    6     *       20 ms    30 ms  so-0-1-0.TR1.LND9.ALTER.NET [146.188.15.33]&lt;br&gt;
    7   101 ms   100 ms    90 ms  so-6-0-0.IR1.NYC12.ALTER.NET [146.188.15.50]&lt;br&gt;
    8   100 ms    91 ms   100 ms  0.so-0-0-0.IL1.NYC9.ALTER.NET [152.63.23.57]&lt;br&gt;
    9   100 ms    90 ms    90 ms  0.so-3-0-0.TL1.NYC9.ALTER.NET [152.63.9.246]&lt;br&gt;
  10    90 ms   100 ms   100 ms  0.so-7-0-0.XL1.NYC4.ALTER.NET [152.63.10.21]&lt;br&gt;
  11   101 ms   100 ms    90 ms  POS7-1.IG3.NYC4.ALTER.NET [152.63.24.41]&lt;br&gt;
  12   350 ms   361 ms   350 ms  vsnlnetin-gw.customer.alter.net [208.192.183.150]&lt;br&gt;
  13   350 ms     *      351 ms  LVSB-VSB-stm-3.Bbone.vsnl.net.in [202.54.2.10]&lt;br&gt;
  14   350 ms   351 ms   360 ms  203.199.112.34&lt;br&gt;
  15     *        *        *     Request timed out.&lt;br&gt;
  16     *        *        *     Request timed out.&lt;br&gt;
  17     *        *        *     Request timed out.&lt;br&gt;
  18     *        *        *     Request timed out.&lt;br&gt;
  19     *        *        *     Request timed out.&lt;br&gt;
  20     *        *        *     Request timed out.&lt;br&gt;
  21     *        *        *     Request timed out.&lt;br&gt;
  22     *        *        *     Request timed out.&lt;br&gt;
  23     *        *        *     Request timed out.&lt;br&gt;
  24     *        *        *     Request timed out.&lt;br&gt;
  25     *        *        *     Request timed out.&lt;br&gt;
  26     *        *        *     Request timed out.&lt;br&gt;
  27     *        *        *     Request timed out.&lt;br&gt;
  28     *        *        *     Request timed out.&lt;br&gt;
  29     *        *        *     Request timed out.&lt;br&gt;
  30     *        *        *     Request timed out.&lt;&#x2F;p&gt;
&lt;p&gt;Trace complete.&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;6) Repeated pings to www.indiatimes.com&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:03&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [195.50.97.132] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Reply from 195.50.97.132: bytes=32 time=40ms TTL=55&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 195.50.97.132:&lt;br&gt;
        Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 40ms, Maximum =  40ms, Average =  40ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:03&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [195.50.97.132] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Reply from 195.50.97.132: bytes=32 time=40ms TTL=55&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 195.50.97.132:&lt;br&gt;
        Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 40ms, Maximum =  40ms, Average =  40ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:03&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [195.50.97.132] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Reply from 195.50.97.132: bytes=32 time=40ms TTL=55&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 195.50.97.132:&lt;br&gt;
        Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 40ms, Maximum =  40ms, Average =  40ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:04&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [195.50.97.131] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Reply from 195.50.97.131: bytes=32 time=40ms TTL=55&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 195.50.97.131:&lt;br&gt;
        Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 40ms, Maximum =  40ms, Average =  40ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:05&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [195.50.97.131] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Reply from 195.50.97.131: bytes=32 time=40ms TTL=55&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 195.50.97.131:&lt;br&gt;
        Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 40ms, Maximum =  40ms, Average =  40ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:05&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [195.50.97.131] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Reply from 195.50.97.131: bytes=32 time=50ms TTL=55&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 195.50.97.131:&lt;br&gt;
        Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 50ms, Maximum =  50ms, Average =  50ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:05&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [195.50.97.131] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Request timed out.&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 195.50.97.131:&lt;br&gt;
        Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 0ms, Maximum =  0ms, Average =  0ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:07&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [80.15.238.69] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Reply from 80.15.238.69: bytes=32 time=40ms TTL=56&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 80.15.238.69:&lt;br&gt;
        Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 40ms, Maximum =  40ms, Average =  40ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;it&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;date&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;Sat 29&#x2F;11&#x2F;2003&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;time&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;t&lt;br&gt;14:10&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;ping www.indiatimes.com -n 1&lt;&#x2F;p&gt;
&lt;p&gt;Pinging indiatime.speedera.net [80.15.238.71] with 32 bytes of data:&lt;&#x2F;p&gt;
&lt;p&gt;Reply from 80.15.238.71: bytes=32 time=50ms TTL=56&lt;&#x2F;p&gt;
&lt;p&gt;Ping statistics for 80.15.238.71:&lt;br&gt;
        Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),&lt;br&gt;Approximate round trip times in milli-seconds:&lt;br&gt;
        Minimum = 50ms, Maximum =  50ms, Average =  50ms&lt;&#x2F;p&gt;
&lt;p&gt;C:\&amp;gt;&lt;&#x2F;p&gt;
&lt;p&gt;-end-&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Yawn</title>
        <published>2003-11-27T00:00:00+00:00</published>
        <updated>2003-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/11/27/slashdot-journal-53402-yawn/"/>
        <id>https://0x5.uk/2003/11/27/slashdot-journal-53402-yawn/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/11/27/slashdot-journal-53402-yawn/">&lt;p&gt;Not getting enough sleep.&lt;br&gt;Too much stress.&lt;br&gt;Must learn&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;.NET&lt;br&gt;Failing to spend required hours.&lt;br&gt;Arrr, downhill spiral.&lt;br&gt;Think I&#x27;ll make up for it with a shopping trip.&lt;br&gt;arr, the b3ta(.com) beast just disappeared 20mins of my life&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>bluetooth headset &amp; old pc with new cable modem</title>
        <published>2003-11-22T00:00:00+00:00</published>
        <updated>2003-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/11/22/slashdot-journal-52940-bluetooth-headset-old-pc-with-new-cable-modem/"/>
        <id>https://0x5.uk/2003/11/22/slashdot-journal-52940-bluetooth-headset-old-pc-with-new-cable-modem/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/11/22/slashdot-journal-52940-bluetooth-headset-old-pc-with-new-cable-modem/">&lt;p&gt;Hello my loyal fanbase. (of me reading my own journal - hello me).&lt;&#x2F;p&gt;
&lt;p&gt;Voice dialling seems to be working on my headset now. Woo. Still not sure it&#x27;s acting quite how it should.&lt;&#x2F;p&gt;
&lt;p&gt;Fixed internet connection on my P800. Turned off secure thingy in the connection settings. All started working again. (Wonder if that&#x27;s bad?)&lt;br&gt;Used about 1&#x2F;4 Mb today, but thanks to fone tariff obfuscation I have no idea what that cost me.&lt;&#x2F;p&gt;
&lt;p&gt;the old pc....&lt;br&gt;A&#x27;s got cable installed now. How do I download a firewall? I connect the unprotected pc to the internet! Aarggh. Stressful. Getting there now.&lt;br&gt;Should have brought my install disks with me. Never mind.&lt;&#x2F;p&gt;
&lt;p&gt;T.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>light</title>
        <published>2003-11-17T00:00:00+00:00</published>
        <updated>2003-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/11/17/slashdot-journal-52384-light/"/>
        <id>https://0x5.uk/2003/11/17/slashdot-journal-52384-light/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/11/17/slashdot-journal-52384-light/">&lt;p&gt;Yay for daily &lt;a href=&quot;http:&#x2F;&#x2F;www.dilbert.com&#x2F;comics&#x2F;dilbert&#x2F;archive&#x2F;&quot;&gt;dilbert&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>message to motorola support</title>
        <published>2003-11-17T00:00:00+00:00</published>
        <updated>2003-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/11/17/slashdot-journal-52397-message-to-motorola-support/"/>
        <id>https://0x5.uk/2003/11/17/slashdot-journal-52397-message-to-motorola-support/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/11/17/slashdot-journal-52397-message-to-motorola-support/">&lt;p&gt;to: mcrc@ei.css.mot.co.uk&lt;br&gt;subject: support request&lt;&#x2F;p&gt;
&lt;p&gt;Dear Sirs,&lt;&#x2F;p&gt;
&lt;p&gt;I spoke to one of your people on the phone and she recommended I mail details of the three issues I&#x27;m having with my new Motorola bluetooth headset.&lt;&#x2F;p&gt;
&lt;p&gt;I own a Sony Ericsson P800&lt;br&gt;(Firmware details: Phone: CXC162002 R2D, Bluetooth: CXC12529 R5A)&lt;&#x2F;p&gt;
&lt;p&gt;I have purchased (yesterday) a Motorola HS810 Bluetooth headset to use with it. (From car phone wharehouse)&lt;br&gt;It paired up correctly and I have successfully made &amp;amp; received calls using it.&lt;&#x2F;p&gt;
&lt;p&gt;I am now having difficulty with voice dialling features. When I press the multifunction button on the side of the headset (which does work for answering calls and hanging up) in order to begin a call using voice dialling, the phone picks up the bluetooth connection, but does not then look up any voice commands as it should. I have tested this functionality without the headset and it works as follows: hold down jog dial, speak name, number is dialled.&lt;br&gt;Any ideas?&lt;&#x2F;p&gt;
&lt;p&gt;Probably a separate issue: I don&#x27;t hear the recorded name that the phone plays when I receive an incoming call from a number which has a voice recording attached (the phone says &quot;playing voice command&quot; but the headset doesn&#x27;t have sound at that point).&lt;&#x2F;p&gt;
&lt;p&gt;The other thing was: the manual says if you press both volume buttons then the LEDs will stop flashing. But they don&#x27;t, which is odd.&lt;&#x2F;p&gt;
&lt;p&gt;I look forward to any help you can give me with these queries.&lt;&#x2F;p&gt;
&lt;p&gt;Yours&lt;&#x2F;p&gt;
&lt;p&gt;Tim Abell&lt;br&gt;077** ******&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>motorola</title>
        <published>2003-11-17T00:00:00+00:00</published>
        <updated>2003-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/11/17/slashdot-journal-52399-motorola/"/>
        <id>https://0x5.uk/2003/11/17/slashdot-journal-52399-motorola/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/11/17/slashdot-journal-52399-motorola/">&lt;p&gt;apparently their mailservers are down. have been for a week.&lt;&#x2F;p&gt;
&lt;p&gt;Hoorah for leading edge technical firms.&lt;&#x2F;p&gt;
&lt;p&gt;Talked to the next guy in their call farm, he got arsey and said that they couldn&#x27;t really support their product on a different manufacturer&#x27;s phone.&lt;&#x2F;p&gt;
&lt;p&gt;Tossers.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>warble</title>
        <published>2003-11-14T00:00:00+00:00</published>
        <updated>2003-11-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/11/14/slashdot-journal-52210-warble/"/>
        <id>https://0x5.uk/2003/11/14/slashdot-journal-52210-warble/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/11/14/slashdot-journal-52210-warble/">&lt;p&gt;yada yada&lt;&#x2F;p&gt;
&lt;p&gt;nothing doing today.&lt;&#x2F;p&gt;
&lt;p&gt;Hello James, if you see this hope the weather&#x27;s nice in whichever part of the world you&#x27;re in today!&lt;&#x2F;p&gt;
&lt;p&gt;Suppose I might as well post that my domain is timwise.co.uk, and that it currently contains a cub web site! (Which I&#x27;m v proud of. - tho you can&#x27;t see most of the interesting bits because that&#x27;s the admin pages.)&lt;&#x2F;p&gt;
&lt;p&gt;Just wondering whether to upload the code to freshmeat or summat, and if I should start using GPL &#x27;n things.&lt;&#x2F;p&gt;
&lt;p&gt;Ooh, and I bought some to way radios&lt;nobr&gt; &lt;&#x2F;nobr&gt;:)&lt;br&gt;Binatone 0503, 30 quid the pair from B&amp;amp;Q&lt;br&gt;(Yes I did reallly need them)&lt;&#x2F;p&gt;
&lt;p&gt;And a cordless drill (oops!)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hello reader</title>
        <published>2003-10-15T00:00:00+00:00</published>
        <updated>2003-10-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/10/15/slashdot-journal-49186-hello-reader/"/>
        <id>https://0x5.uk/2003/10/15/slashdot-journal-49186-hello-reader/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/10/15/slashdot-journal-49186-hello-reader/">&lt;p&gt;I found out what my mysterious payment from egg was this evening.&lt;br&gt;Cashback is now paid straight into current account (I like!)&lt;br&gt;so I am 28 quid richer for spending all my money through egg.&lt;br&gt;woo!&lt;br&gt;I think that&#x27;s way more than I earnt in interest on my savings.&lt;&#x2F;p&gt;
&lt;p&gt;TMF bunch would be proud of me.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wrinkly hands</title>
        <published>2003-10-13T00:00:00+00:00</published>
        <updated>2003-10-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/10/13/slashdot-journal-48982-wrinkly-hands/"/>
        <id>https://0x5.uk/2003/10/13/slashdot-journal-48982-wrinkly-hands/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/10/13/slashdot-journal-48982-wrinkly-hands/">&lt;p&gt;Did the washing up this evening.&lt;&#x2F;p&gt;
&lt;p&gt;woo.&lt;&#x2F;p&gt;
&lt;p&gt;+2 brownie points with gf.&lt;&#x2F;p&gt;
&lt;p&gt;read&lt;nobr&gt; &lt;&#x2F;nobr&gt;&#x2F;. &amp;amp; b3ta this evening.&lt;&#x2F;p&gt;
&lt;p&gt;-20 points with gf&lt;nobr&gt; &lt;&#x2F;nobr&gt;:(&lt;&#x2F;p&gt;
&lt;p&gt;ps.&lt;br&gt;hello Joel.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Vodafone - sucking</title>
        <published>2003-09-16T00:00:00+00:00</published>
        <updated>2003-09-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://0x5.uk/2003/09/16/slashdot-journal-46073-vodafone---sucking/"/>
        <id>https://0x5.uk/2003/09/16/slashdot-journal-46073-vodafone---sucking/</id>
        
        <content type="html" xml:base="https://0x5.uk/2003/09/16/slashdot-journal-46073-vodafone---sucking/">&lt;p&gt;Sent a message to vodafone saying that I wasn&#x27;t too impressed.&lt;br&gt;I know ranting gets you nowhere but I feel better nontheless.&lt;&#x2F;p&gt;
&lt;p&gt;The rant:&lt;br&gt;-------------------------------&lt;br&gt;I have been with vodafoam for about 2 months now and I am SERIOUSLY DISSILUSIONED with every aspect of your business.&lt;&#x2F;p&gt;
&lt;p&gt;Since I joined, you have failed to set up my direct debit, twice, blocked my outgoing calls, twice (including calls to 191, you morons!) - for no good reason. Been unable to answer the most basic questions over the phone, such as what has happened to the money I have sent you. And, been alternately &quot;unable&quot; and &quot;too incompetent&quot; to set up normal voicemail notification.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, your website is one of the worst commercial sites I have seen in a long time. I have never seen a site before where your session expires without even being logged on. Appalling. As you may have guessed, I cannot view my bill online as promised because of you inability to set up a direct debit. And the point of that would be what?&lt;&#x2F;p&gt;
&lt;p&gt;I would normally expect at least some kind of apology and some remedial action, however your corporation appears to have its head so far up its own backside that it has no idea what it&#x27;s like to be one of your customers. I shall look forward to your bland impersonal corporate excuse for a response.&lt;br&gt;--------------------------&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
