{"title":"Jelmer Vernoo\u0133","link":[{"@attributes":{"href":"https:\/\/www.jelmer.uk\/","rel":"alternate"}},{"@attributes":{"href":"https:\/\/www.jelmer.uk\/feeds\/all.atom.xml","rel":"self"}}],"id":"https:\/\/www.jelmer.uk\/","updated":"2025-06-03T18:00:00+02:00","entry":[{"title":"Introducing dissolve: Declarative Deprecations for Python\u00a0APIs","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/dissolve.html","rel":"alternate"}},"published":"2025-06-03T18:00:00+02:00","updated":"2025-06-03T18:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2025-06-03:dissolve.html","summary":"<p>I&#8217;ve published a new tool called <a class=\"reference external\" href=\"https:\/\/pypi.org\/project\/dissolve\/\">dissolve<\/a>. It\u2019s aimed at simplifying how library maintainers communicate <span class=\"caps\">API<\/span> changes \u2014 and how users of those libraries can automate code&nbsp;migrations.<\/p>\n<div class=\"section\" id=\"what-is-it\">\n<h2>What is&nbsp;it?<\/h2>\n<p><tt class=\"docutils literal\">dissolve<\/tt> allows <strong>library maintainers<\/strong> to annotate deprecated functions using a decorator, and lets <strong>library users<\/strong> rewrite old calls in their own codebases using a command-line&nbsp;tool.<\/p>\n<\/div>\n<div class=\"section\" id=\"example-library-maintainer\">\n<h2>Example (library&nbsp;maintainer)<\/h2>\n<p>Mark a function as&nbsp;deprecated:<\/p>\n<pre class=\"literal-block\">\nfrom dissolve import replace_me\n\ndef increment(x):\n    &quot;&quot;&quot;Use this instead.&quot;&quot;&quot;\n    return x + 1\n\n&#64;replace_me(since=&quot;0.1.0&quot;)\ndef inc(x):\n    return increment(x)\n<\/pre>\n<p>When used, this function emits a deprecation warning&nbsp;like:<\/p>\n<pre class=\"literal-block\">\nDeprecationWarning: &lt;function inc&gt; has been deprecated since 0.1.0; use 'increment(3)' instead\n<\/pre>\n<\/div>\n<div class=\"section\" id=\"example-library-user\">\n<h2>Example (library&nbsp;user)<\/h2>\n<p>If your codebase uses deprecated APIs marked with <tt class=\"docutils literal\">&#64;replace_me<\/tt>, you can rewrite those calls&nbsp;automatically:<\/p>\n<pre class=\"literal-block\">\ndissolve migrate path\/to\/your\/code\n<\/pre>\n<p>Options:<\/p>\n<ul class=\"simple\">\n<li><tt class=\"docutils literal\"><span class=\"pre\">--check<\/span><\/tt>: report but don\u2019t&nbsp;modify<\/li>\n<li><tt class=\"docutils literal\"><span class=\"pre\">--write<\/span><\/tt>: apply changes&nbsp;in-place<\/li>\n<\/ul>\n<\/div>\n<div class=\"section\" id=\"removing-old-markers\">\n<h2>Removing old&nbsp;markers<\/h2>\n<p>Once users have migrated, maintainers can clean up deprecated&nbsp;decorators:<\/p>\n<pre class=\"literal-block\">\ndissolve remove --all mylib\/\n<\/pre>\n<p>Or only those deprecated before a specific&nbsp;version:<\/p>\n<pre class=\"literal-block\">\ndissolve remove --before 2.0.0 mylib\/\n<\/pre>\n<\/div>\n<div class=\"section\" id=\"no-hard-dependency-required\">\n<h2>No hard dependency&nbsp;required<\/h2>\n<p>Libraries do <strong>not<\/strong> need to make <tt class=\"docutils literal\">dissolve<\/tt> a hard dependency. They can optionally ship a fallback <tt class=\"docutils literal\">&#64;replace_me<\/tt> decorator that just emits a plain <tt class=\"docutils literal\">DeprecationWarning<\/tt>:<\/p>\n<pre class=\"literal-block\">\ntry:\n    from dissolve import replace_me\nexcept ImportError:\n    import warnings\n    def replace_me(msg, since=None):\n        def decorator(func):\n            def wrapper(*args, **kwargs):\n                warnings.warn(\n                    f&quot;{func.__name__} is deprecated; use {msg} instead&quot;,\n                    DeprecationWarning,\n                    stacklevel=2\n                )\n                return func(*args, **kwargs)\n            return wrapper\n        return decorator\n<\/pre>\n<p>This ensures that users still receive deprecation warnings, even if they don\u2019t have <tt class=\"docutils literal\">dissolve<\/tt> installed.<\/p>\n<\/div>\n<div class=\"section\" id=\"install\">\n<h2>Install<\/h2>\n<p>For&nbsp;users:<\/p>\n<pre class=\"literal-block\">\npip install dissolve\n<\/pre>\n<\/div>\n<div class=\"section\" id=\"source\">\n<h2>Source<\/h2>\n<ul class=\"simple\">\n<li>GitHub: <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/dissolve\">https:\/\/github.com\/jelmer\/dissolve<\/a><\/li>\n<li>PyPI: <a class=\"reference external\" href=\"https:\/\/pypi.org\/project\/dissolve\/\">https:\/\/pypi.org\/project\/dissolve\/<\/a><\/li>\n<\/ul>\n<p>Questions, suggestions, and patches&nbsp;welcome.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"dissolve"}},{"@attributes":{"term":"deprecations"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"library-maintainers"}},{"@attributes":{"term":"code-migrations"}}]},{"title":"Transcontinental Race No\u00a09","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/tcrno9.html","rel":"alternate"}},"published":"2023-09-10T20:00:00+00:00","updated":"2023-09-10T20:00:00+00:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2023-09-10:tcrno9.html","summary":"<p>After cycling the <a class=\"reference external\" href=\"https:\/\/www.northcape4000.com\/\">Northcape 4000<\/a> (from Italy to northern Norway) last year,\nI signed up for the <a class=\"reference external\" href=\"https:\/\/www.transcontinental.cc\">transcontinental race<\/a>\nthis&nbsp;year.<\/p>\n<p>The Transcontinental is bikepacking race across Europe, self-routed (but with some mandatory checkpoints), unsupported and\nwith a distance of usually somewhere around 4000 km. The cut-off time is 15 days, with the winner usually taking 7-10&nbsp;days.<\/p>\n<p>This year, the route went from Belgium to Thessaloniki in Greece, with control points in northern Italy, Slovenia, Albania and\nMeteora&nbsp;(Greece).<\/p>\n<p>The event was great - it was well organised and communication was a lot better than at the Northcape. It did feel\nvery different from the Northcape, though, being a proper race. Participants\nare not allowed to draft off each other or help each other, though a quick chat\nhere or there as you pass people is possible, or when you&#8217;re both stopped at a\nshop or control&nbsp;point.<\/p>\n<img alt=\"\" src=\"\/images\/tcr-rules.jpg\" style=\"width: 408px; height: 307px;\" \/>\n<div class=\"section\" id=\"my-experience\">\n<h2>My&nbsp;experience<\/h2>\n<p>The route was beautiful - the first bit through France was a bit monotonic, but\nespecially the views in the alps were amazing. Like with other long events,\nthe first day or two can be hard but once you get into the rhythm of things\nit&#8217;s a lot&nbsp;easier.<\/p>\n<p>From early on, I lost a lot of time. We started in the rain, and I ran\nseveral flats in a row, just 4 hours in. In addition to that, the thread on my pump\nhad worn so it wouldn&#8217;t fit on some of my spare tubes, and my tubes were all\n<span class=\"caps\">TPU<\/span> - which are hard to patch. So at 3 <span class=\"caps\">AM<\/span> I found myself by the side of an N-road in\nFrance without any usable tubes to put in my rear wheel. I ended up walking 20km\nto the nearest town with a bike shop, where they fortunately had good old butyl\ntubes and a working pump. But overall, this cost me about 12 hours in&nbsp;total.<\/p>\n<p>In addition to that, my time management wasn&#8217;t great. On previous rides, I&#8217;d usually\ngotten about 8 hours of sleep per night while staying in hotels. On the\ntranscontinental I had meant to get less sleep but still stay in hotels most\nnight, but I found that not all hotels accomodated\nwell for that - especially with a bike. So I ended up getting more sleep than I\nhad intended, and spending more time off the bike than I had planned - close to\n11 or 12 hours per day. I hadn&#8217;t scheduled much time off work after the finish either, so\narriving in Greece late wasn&#8217;t really an&nbsp;option.<\/p>\n<p>And then, on an early morning in Croatia (about 2000km in) in heavy fog, I rode into a kerb at 35 km\/h, bending\nthe rim of my front wheel (but fortunately not coming off my bike). While I probably would have been able to continue with\na replacement wheel (and mailing the broken one home), that would have taken\nanother day to sort out and I almost certainly wouldn&#8217;t have been\nable to source a new dynamo wheel in Croatia - which would have made night time riding a lot harder.\nSo I decided to scratch and take the train home from&nbsp;Zagreb.<\/p>\n<p>Overall, I really enjoyed the event and I think I&#8217;ve learned some useful\nlessons. I&#8217;ll probably try again next&nbsp;year.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"cycling"}},{"@attributes":{"term":"race"}}]},{"title":"Porting Python projects to\u00a0Rust","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/port-py-to-rust.html","rel":"alternate"}},"published":"2023-06-02T17:00:00+00:00","updated":"2023-06-02T17:00:00+00:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2023-06-02:port-py-to-rust.html","summary":"<p>I&#8217;ve recently been working on porting some of my Python code to rust, both for performance reasons, and because of the strong typing in the language. As a fan of Haskell, I also just really enjoy using the&nbsp;language.<\/p>\n<p>Porting any large project to a new language can be a challenge. There is a temptation to do a rewrite from the ground-up in idiomatic rust and using all new fancy features of the&nbsp;language.<\/p>\n<div class=\"section\" id=\"porting-in-one-go\">\n<h2>Porting in one&nbsp;go<\/h2>\n<p>However, this is a bit of a&nbsp;trap:<\/p>\n<ul class=\"simple\">\n<li>It blocks other work. It can take a long time to finish the rewrite, during which time there is no good place to make other bug fixes\/feature changes. If you make the change in the python branch, then you may also have to patch the in-progress rust&nbsp;fork.<\/li>\n<li>No immediate return on investment. While the rewrite is happening, all of the investment in it is sunk&nbsp;costs.<\/li>\n<li>Throughout the process, you can only run the tests for subsystems that have already been ported. It&#8217;s common to find subtle bugs later in code ported&nbsp;early.<\/li>\n<li>Understanding existing code, porting it and making it idiomatic rust all at the same time takes more time and post-facto&nbsp;debugging.<\/li>\n<\/ul>\n<\/div>\n<div class=\"section\" id=\"iterative-porting\">\n<h2>Iterative&nbsp;porting<\/h2>\n<p>Instead, we&#8217;ve found that it works much better to take an iterative approach. One of the hidden gems of rust is the excellent PyO3 crate, which allows creating python bindings for rust code in a way that is several times less verbose and less painful than C or <span class=\"caps\">SWIG<\/span>. Because of rust&#8217;s strong ownership model, it&#8217;s also really hard to muck up e.g. reference counts when creating Python bindings for rust&nbsp;code.<\/p>\n<p>We port individual functions or classes to rust one at a time, starting with functionality that doesn&#8217;t have dependencies on other python code and gradually working our way up the call&nbsp;stack.<\/p>\n<p>Each subsystem of the code is converted to two matching rust crates: one with a port of the code to pure rust, and one with python bindings for the rust code. Generally multiple python modules end up being a single pair of rust&nbsp;crates.<\/p>\n<p>The signature for the pure Rust code follow rust conventions, but the business logic is mostly ported as-is (just in rust syntax) and the signatures of the python bindings match that of the original python&nbsp;code.<\/p>\n<p>This then allows running the original python tests to verify that the code still behaves the same way. Changes can also immediately land on the main&nbsp;branch.<\/p>\n<p>A subsequent step is usually to refactor the rust code to be more idiomatic - all the while keeping the tests passing. There is also the potential to e.g. switch to using external rust crates (with perhaps subtly different behaviour), or drop functionality&nbsp;altogether.<\/p>\n<p>At some point, we will also port the tests from python to rust, and potentially drop the python bindings - once all the caller&#8217;s have been converted to&nbsp;rust.<\/p>\n<\/div>\n<div class=\"section\" id=\"example\">\n<h2>Example<\/h2>\n<p>For example, imagine I have a Python module <em>janitor\/mail_filter.py<\/em> with this&nbsp;function:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span>\n<span class=\"normal\">14<\/span>\n<span class=\"normal\">15<\/span>\n<span class=\"normal\">16<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"k\">def<\/span> <span class=\"nf\">parse_plain_text_body<\/span><span class=\"p\">(<\/span><span class=\"n\">text<\/span><span class=\"p\">):<\/span>\n   <span class=\"n\">lines<\/span> <span class=\"o\">=<\/span> <span class=\"n\">text<\/span><span class=\"o\">.<\/span><span class=\"n\">splitlines<\/span><span class=\"p\">()<\/span>\n\n   <span class=\"k\">for<\/span> <span class=\"n\">i<\/span><span class=\"p\">,<\/span> <span class=\"n\">line<\/span> <span class=\"ow\">in<\/span> <span class=\"nb\">enumerate<\/span><span class=\"p\">(<\/span><span class=\"n\">lines<\/span><span class=\"p\">):<\/span>\n       <span class=\"k\">if<\/span> <span class=\"n\">line<\/span> <span class=\"o\">==<\/span> <span class=\"s1\">&#39;Reply to this email directly or view it on GitHub:&#39;<\/span><span class=\"p\">:<\/span>\n           <span class=\"k\">return<\/span> <span class=\"n\">lines<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">]<\/span><span class=\"o\">.<\/span><span class=\"n\">split<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;#&#39;<\/span><span class=\"p\">)[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n       <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">line<\/span> <span class=\"o\">==<\/span> <span class=\"s1\">&#39;For more details, see:&#39;<\/span>\n               <span class=\"ow\">and<\/span> <span class=\"n\">lines<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">]<\/span><span class=\"o\">.<\/span><span class=\"n\">startswith<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;https:\/\/code.launchpad.net\/&#39;<\/span><span class=\"p\">)):<\/span>\n           <span class=\"k\">return<\/span> <span class=\"n\">lines<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n       <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n           <span class=\"p\">(<\/span><span class=\"n\">field<\/span><span class=\"p\">,<\/span> <span class=\"n\">value<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"n\">line<\/span><span class=\"o\">.<\/span><span class=\"n\">split<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;:&#39;<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n       <span class=\"k\">except<\/span> <span class=\"ne\">ValueError<\/span><span class=\"p\">:<\/span>\n           <span class=\"k\">continue<\/span>\n       <span class=\"k\">if<\/span> <span class=\"n\">field<\/span><span class=\"o\">.<\/span><span class=\"n\">lower<\/span><span class=\"p\">()<\/span> <span class=\"o\">==<\/span> <span class=\"s1\">&#39;merge request url&#39;<\/span><span class=\"p\">:<\/span>\n           <span class=\"k\">return<\/span> <span class=\"n\">value<\/span><span class=\"o\">.<\/span><span class=\"n\">strip<\/span><span class=\"p\">()<\/span>\n   <span class=\"k\">return<\/span> <span class=\"kc\">None<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>Porting this to rust naively (in a crate I&#8217;ve called &#8220;mailfilter&#8221;) it might look something like&nbsp;this:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span>\n<span class=\"normal\">14<\/span>\n<span class=\"normal\">15<\/span>\n<span class=\"normal\">16<\/span>\n<span class=\"normal\">17<\/span>\n<span class=\"normal\">18<\/span>\n<span class=\"normal\">19<\/span>\n<span class=\"normal\">20<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"k\">pub<\/span><span class=\"w\"> <\/span><span class=\"k\">fn<\/span><span class=\"w\"> <\/span><span class=\"nf\">parse_plain_text_body<\/span><span class=\"p\">(<\/span><span class=\"n\">text<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kp\">&amp;<\/span><span class=\"kt\">str<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">-&gt;<\/span><span class=\"w\"> <\/span><span class=\"nb\">Option<\/span><span class=\"o\">&lt;<\/span><span class=\"nb\">String<\/span><span class=\"o\">&gt;<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">     <\/span><span class=\"kd\">let<\/span><span class=\"w\"> <\/span><span class=\"n\">lines<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"nb\">Vec<\/span><span class=\"o\">&lt;&amp;<\/span><span class=\"kt\">str<\/span><span class=\"o\">&gt;<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"n\">text<\/span><span class=\"p\">.<\/span><span class=\"n\">lines<\/span><span class=\"p\">().<\/span><span class=\"n\">collect<\/span><span class=\"p\">();<\/span>\n\n<span class=\"w\">     <\/span><span class=\"k\">for<\/span><span class=\"w\"> <\/span><span class=\"p\">(<\/span><span class=\"n\">i<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"n\">line<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"k\">in<\/span><span class=\"w\"> <\/span><span class=\"n\">lines<\/span><span class=\"p\">.<\/span><span class=\"n\">iter<\/span><span class=\"p\">().<\/span><span class=\"n\">enumerate<\/span><span class=\"p\">()<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">         <\/span><span class=\"k\">if<\/span><span class=\"w\"> <\/span><span class=\"n\">line<\/span><span class=\"w\"> <\/span><span class=\"o\">==<\/span><span class=\"w\"> <\/span><span class=\"o\">&amp;<\/span><span class=\"s\">&quot;Reply to this email directly or view it on GitHub:&quot;<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">             <\/span><span class=\"k\">return<\/span><span class=\"w\"> <\/span><span class=\"nb\">Some<\/span><span class=\"p\">(<\/span><span class=\"n\">lines<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"w\"> <\/span><span class=\"o\">+<\/span><span class=\"w\"> <\/span><span class=\"mi\">1<\/span><span class=\"p\">].<\/span><span class=\"n\">split<\/span><span class=\"p\">(<\/span><span class=\"sc\">&#39;#&#39;<\/span><span class=\"p\">).<\/span><span class=\"n\">next<\/span><span class=\"p\">().<\/span><span class=\"n\">unwrap<\/span><span class=\"p\">().<\/span><span class=\"n\">to_string<\/span><span class=\"p\">());<\/span>\n<span class=\"w\">         <\/span><span class=\"p\">}<\/span>\n<span class=\"w\">         <\/span><span class=\"k\">if<\/span><span class=\"w\"> <\/span><span class=\"n\">line<\/span><span class=\"w\"> <\/span><span class=\"o\">==<\/span><span class=\"w\"> <\/span><span class=\"o\">&amp;<\/span><span class=\"s\">&quot;For more details, see:&quot;<\/span>\n<span class=\"w\">             <\/span><span class=\"o\">&amp;&amp;<\/span><span class=\"w\"> <\/span><span class=\"n\">lines<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"w\"> <\/span><span class=\"o\">+<\/span><span class=\"w\"> <\/span><span class=\"mi\">1<\/span><span class=\"p\">].<\/span><span class=\"n\">starts_with<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;https:\/\/code.launchpad.net\/&quot;<\/span><span class=\"p\">)<\/span>\n<span class=\"w\">         <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">             <\/span><span class=\"k\">return<\/span><span class=\"w\"> <\/span><span class=\"nb\">Some<\/span><span class=\"p\">(<\/span><span class=\"n\">lines<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"w\"> <\/span><span class=\"o\">+<\/span><span class=\"w\"> <\/span><span class=\"mi\">1<\/span><span class=\"p\">].<\/span><span class=\"n\">to_string<\/span><span class=\"p\">());<\/span>\n<span class=\"w\">         <\/span><span class=\"p\">}<\/span>\n<span class=\"w\">         <\/span><span class=\"k\">if<\/span><span class=\"w\"> <\/span><span class=\"kd\">let<\/span><span class=\"w\"> <\/span><span class=\"nb\">Some<\/span><span class=\"p\">((<\/span><span class=\"n\">field<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"n\">value<\/span><span class=\"p\">))<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"n\">line<\/span><span class=\"p\">.<\/span><span class=\"n\">split_once<\/span><span class=\"p\">(<\/span><span class=\"sc\">&#39;:&#39;<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">             <\/span><span class=\"k\">if<\/span><span class=\"w\"> <\/span><span class=\"n\">field<\/span><span class=\"p\">.<\/span><span class=\"n\">to_lowercase<\/span><span class=\"p\">()<\/span><span class=\"w\"> <\/span><span class=\"o\">==<\/span><span class=\"w\"> <\/span><span class=\"s\">&quot;merge request url&quot;<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">                 <\/span><span class=\"k\">return<\/span><span class=\"w\"> <\/span><span class=\"nb\">Some<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">.<\/span><span class=\"n\">trim<\/span><span class=\"p\">().<\/span><span class=\"n\">to_string<\/span><span class=\"p\">());<\/span>\n<span class=\"w\">             <\/span><span class=\"p\">}<\/span>\n<span class=\"w\">         <\/span><span class=\"p\">}<\/span>\n<span class=\"w\">     <\/span><span class=\"p\">}<\/span>\n<span class=\"w\">     <\/span><span class=\"nb\">None<\/span>\n<span class=\"w\"> <\/span><span class=\"p\">}<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>Bindings are created in a crate called mailfilter-py, which looks like&nbsp;this:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"k\">use<\/span><span class=\"w\"> <\/span><span class=\"n\">pyo3<\/span><span class=\"p\">::<\/span><span class=\"n\">prelude<\/span><span class=\"p\">::<\/span><span class=\"o\">*<\/span><span class=\"p\">;<\/span>\n\n<span class=\"w\"> <\/span><span class=\"cp\">#[pyfunction]<\/span>\n<span class=\"w\"> <\/span><span class=\"k\">fn<\/span><span class=\"w\"> <\/span><span class=\"nf\">parse_plain_text_body<\/span><span class=\"p\">(<\/span><span class=\"n\">text<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kp\">&amp;<\/span><span class=\"kt\">str<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">-&gt;<\/span><span class=\"w\"> <\/span><span class=\"nb\">Option<\/span><span class=\"o\">&lt;<\/span><span class=\"nb\">String<\/span><span class=\"o\">&gt;<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">     <\/span><span class=\"n\">janitor_mail_filter<\/span><span class=\"p\">::<\/span><span class=\"n\">parse_plain_text_body<\/span><span class=\"p\">(<\/span><span class=\"n\">text<\/span><span class=\"p\">)<\/span>\n<span class=\"w\"> <\/span><span class=\"p\">}<\/span>\n\n<span class=\"w\"> <\/span><span class=\"cp\">#[pymodule]<\/span>\n<span class=\"w\"> <\/span><span class=\"k\">pub<\/span><span class=\"w\"> <\/span><span class=\"k\">fn<\/span><span class=\"w\"> <\/span><span class=\"nf\">_mail_filter<\/span><span class=\"p\">(<\/span><span class=\"n\">py<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"nc\">Python<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"n\">m<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kp\">&amp;<\/span><span class=\"nc\">PyModule<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">-&gt;<\/span><span class=\"w\"> <\/span><span class=\"nc\">PyResult<\/span><span class=\"o\">&lt;<\/span><span class=\"p\">()<\/span><span class=\"o\">&gt;<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span>\n<span class=\"w\">     <\/span><span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">add_function<\/span><span class=\"p\">(<\/span><span class=\"n\">wrap_pyfunction<\/span><span class=\"o\">!<\/span><span class=\"p\">(<\/span><span class=\"n\">parse_plain_text_body<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"n\">m<\/span><span class=\"p\">)<\/span><span class=\"o\">?<\/span><span class=\"p\">)<\/span><span class=\"o\">?<\/span><span class=\"p\">;<\/span>\n\n<span class=\"w\">     <\/span><span class=\"nb\">Ok<\/span><span class=\"p\">(())<\/span>\n<span class=\"w\"> <\/span><span class=\"p\">}<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>The metadata for the crates is what you&#8217;d expect. mailfilter-py uses PyO3 and depends on&nbsp;mailfilter.<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"k\">[package]<\/span>\n<span class=\"w\"> <\/span><span class=\"n\">name<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;mailfilter-py&quot;<\/span>\n<span class=\"w\"> <\/span><span class=\"n\">version<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;0.0.0&quot;<\/span>\n<span class=\"w\"> <\/span><span class=\"n\">authors<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"p\">[<\/span><span class=\"s2\">&quot;Jelmer Vernoo\u0133 &lt;jelmer@jelmer.uk&gt;&quot;<\/span><span class=\"p\">]<\/span>\n<span class=\"w\"> <\/span><span class=\"n\">edition<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;2018&quot;<\/span>\n\n<span class=\"w\"> <\/span><span class=\"k\">[lib]<\/span>\n<span class=\"w\"> <\/span><span class=\"n\">crate-type<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"p\">[<\/span><span class=\"s2\">&quot;cdylib&quot;<\/span><span class=\"p\">]<\/span>\n\n<span class=\"w\"> <\/span><span class=\"k\">[dependencies]<\/span>\n<span class=\"w\"> <\/span><span class=\"n\">janitor-mail-filter<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\"> <\/span><span class=\"n\">path<\/span><span class=\"w\"> <\/span><span class=\"p\">=<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;..\/mailfilter&quot;<\/span><span class=\"w\"> <\/span><span class=\"p\">}<\/span>\n<span class=\"w\"> <\/span><span class=\"n\">pyo3<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\"> <\/span><span class=\"n\">version<\/span><span class=\"w\"> <\/span><span class=\"p\">=<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;&gt;=0.14&quot;<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"n\">features<\/span><span class=\"w\"> <\/span><span class=\"p\">=<\/span><span class=\"w\"> <\/span><span class=\"p\">[<\/span><span class=\"s2\">&quot;extension-module&quot;<\/span><span class=\"p\">]}<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>I use python-setuptools-rust to get the python ecosystem to build the python bindings. Here is what setup.py looks&nbsp;like:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span>\n<span class=\"normal\">5<\/span>\n<span class=\"normal\">6<\/span>\n<span class=\"normal\">7<\/span>\n<span class=\"normal\">8<\/span>\n<span class=\"normal\">9<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"ch\">#!\/usr\/bin\/python3<\/span>\n<span class=\"kn\">from<\/span> <span class=\"nn\">setuptools<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">setup<\/span>\n<span class=\"kn\">from<\/span> <span class=\"nn\">setuptools_rust<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">RustExtension<\/span><span class=\"p\">,<\/span> <span class=\"n\">Binding<\/span>\n\n<span class=\"n\">setup<\/span><span class=\"p\">(<\/span>\n        <span class=\"n\">rust_extensions<\/span><span class=\"o\">=<\/span><span class=\"p\">[<\/span><span class=\"n\">RustExtension<\/span><span class=\"p\">(<\/span>\n        <span class=\"s2\">&quot;janitor._mailfilter&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;crates\/mailfilter-py\/Cargo.toml&quot;<\/span><span class=\"p\">,<\/span>\n        <span class=\"n\">binding<\/span><span class=\"o\">=<\/span><span class=\"n\">Binding<\/span><span class=\"o\">.<\/span><span class=\"n\">PyO3<\/span><span class=\"p\">)],<\/span>\n<span class=\"p\">)<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>And of course, <a class=\"reference external\" href=\"https:\/\/pypi.org\/project\/setuptools-rust\/\">setuptools-rust<\/a> needs to be listed as a setup requirement in <em>pyproject.toml<\/em> or <em>setup.cfg<\/em>.<\/p>\n<p>After that, we can replace the original python code with a simple import and verify that the tests still&nbsp;run:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"kn\">from<\/span> <span class=\"nn\">._mailfilter<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">parse_plain_text_body<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>Of course, not all bindings are as simple as this. Iterators in particular are more complicated, as is code that has a loose idea of ownership in python. But I&#8217;ve found that the time investment is usually well worth the ability to land changes on the development head early and&nbsp;often.<\/p>\n<p>I&#8217;d be curious to hear if people have had success with other approaches to porting Python code to Rust. If you do, please leave a&nbsp;comment.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"rust"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"porting"}}]},{"title":"The Kali\u00a0Janitor","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/kali-janitor.html","rel":"alternate"}},"published":"2023-03-08T22:25:00+01:00","updated":"2023-03-08T22:25:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2023-03-08:kali-janitor.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p><a class=\"reference external\" href=\"https:\/\/www.kali.org\/\">Kali Linux<\/a> have been running their own instance\nof the <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/janitor\/\">Janitor<\/a> for the last year, under\nthe <a class=\"reference external\" href=\"https:\/\/gitlab.com\/kali-bot\">kali-bot<\/a> user on GitLab.\nTheir web site has <a class=\"reference external\" href=\"https:\/\/www.kali.org\/docs\/development\/leveraging-the-kali-bot\/\">some excellent documentation<\/a> explaining how the bot&nbsp;works.<\/p>\n<p>Both projects share some common components - the <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/janitor\">core janitor codebase<\/a>, <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/silver-platter\">Silver-Platter<\/a> and the various codemods\n(<a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> and\n<a class=\"reference external\" href=\"https:\/\/launchpad.net\/brz-debian\">deb-new-upstream<\/a>). The site and some\nof the review logic is different for&nbsp;Kali.<\/p>\n<p>The Kali bot has several&nbsp;campaigns:<\/p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https:\/\/janitor.kali.org\/lintian-fixes\/\">Lintian-Fixes<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/janitor.kali.org\/fresh-releases\/\">Fresh&nbsp;releases<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/janitor.kali.org\/fresh-snapshots\/\">Fresh&nbsp;snapshots<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/janitor.kali.org\/merge-from-debian\/\">Merge from Debian (and other&nbsp;distributions)<\/a><\/li>\n<\/ul>\n<p>The last campaign doesn&#8217;t exist in the Debian janitor, and pulls in new changes from packages that have been imported from other&nbsp;distributions.<\/p>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"kali-janitor"}},{"@attributes":{"term":"kali"}}]},{"title":"Silver Platter Batch\u00a0Mode","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/silver-platter-batch.html","rel":"alternate"}},"published":"2023-02-25T22:44:00+01:00","updated":"2023-02-25T22:44:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2023-02-25:silver-platter-batch.html","summary":"<div class=\"section\" id=\"background\">\n<h2>Background<\/h2>\n<p><a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/silver-platter\">Silver-Platter<\/a> makes it easier to\npublish automated changes to repositories. However, in its default mode, the\nonly option for reviewing changes before publishing them is to run in dry-run mode.\nThis can be quite cumbersome if you have a lot of&nbsp;repositories.<\/p>\n<p>A new &#8220;batch&#8221; mode now makes it possible to generate a large number of changes\nagainst different repositories using a script, review and optionally alter the\ndiffs, and then all publish them (and potentially refresh them later if\nconflicts&nbsp;appear).<\/p>\n<\/div>\n<div class=\"section\" id=\"example-running-pyupgrade\">\n<h2>Example running&nbsp;pyupgrade<\/h2>\n<p>I&#8217;m using the <a class=\"reference external\" href=\"https:\/\/raw.githubusercontent.com\/jelmer\/silver-platter\/master\/examples\/pyupgrade.yaml\">pyupgrade example<\/a> recipe that comes with&nbsp;silver-platter.<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">---<\/span>\n<span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">name<\/span><span class=\"p p-Indicator\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">pyupgrade<\/span>\n<span class=\"w\"> <\/span><span class=\"nt\">command<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s\">&#39;pyupgrade<\/span><span class=\"nv\"> <\/span><span class=\"s\">--exit-zero-even-if-changed<\/span><span class=\"nv\"> <\/span><span class=\"s\">$(find<\/span><span class=\"nv\"> <\/span><span class=\"s\">-name<\/span><span class=\"nv\"> <\/span><span class=\"s\">&quot;test_*.py&quot;)&#39;<\/span>\n<span class=\"w\"> <\/span><span class=\"nt\">mode<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">propose<\/span>\n<span class=\"w\"> <\/span><span class=\"nt\">merge-request<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">   <\/span><span class=\"nt\">commit-message<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Upgrade Python code to a modern version<\/span>\n<\/pre><\/div>\n<p>And a list of candidate repositories to process in <tt class=\"docutils literal\">candidates.yaml<\/tt>.<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">---<\/span>\n<span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">- url<\/span><span class=\"p p-Indicator\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">https:\/\/github.com\/jelmer\/dulwich<\/span>\n<span class=\"w\"> <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">url<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">https:\/\/github.com\/jelmer\/xandikos<\/span>\n<\/pre><\/div>\n<p>With these in place, the updated repositories can be&nbsp;created:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> $ <\/span>svp<span class=\"w\"> <\/span>batch<span class=\"w\"> <\/span>generate<span class=\"w\"> <\/span>--recipe<span class=\"o\">=<\/span>pyupgrade.yaml<span class=\"w\"> <\/span>--candidates<span class=\"o\">=<\/span>candidate.syml<span class=\"w\"> <\/span>pyupgrade\n<\/pre><\/div>\n<\/div>\n<div class=\"section\" id=\"the-intermediate-results\">\n<h2>The intermediate&nbsp;results<\/h2>\n<p>This will create a directory called <tt class=\"docutils literal\">pyupgrade<\/tt>, with a clone of each of the&nbsp;repositories.<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\">$ <\/span>ls<span class=\"w\"> <\/span>pyupgrade\n<span class=\"go\">batch.yaml  dulwich  xandikos<\/span>\n\n<span class=\"gp\">$ <\/span><span class=\"nb\">cd<\/span><span class=\"w\"> <\/span>pyupgrade\/dulwich\n<span class=\"gp\">$ <\/span>git<span class=\"w\"> <\/span>log\n<span class=\"go\">commit 931f9ffb26e9143c56f20e0b85e6ddb0a8eee2eb (HEAD -&gt; master)<\/span>\n<span class=\"go\">Author: Jelmer Vernoo\u0133 &lt;jelmer@jelmer.uk&gt;<\/span>\n<span class=\"go\">Date:   Sat Feb 25 22:28:12 2023 +0000<\/span>\n\n<span class=\"go\">Run pyupgrade<\/span>\n<span class=\"go\">diff --git a\/dulwich\/tests\/compat\/test_client.py b\/dulwich\/tests\/compat\/test_client.py<\/span>\n<span class=\"go\">index 02ab6c0a..9b0661ed 100644<\/span>\n<span class=\"go\">--- a\/dulwich\/tests\/compat\/test_client.py<\/span>\n<span class=\"go\">+++ b\/dulwich\/tests\/compat\/test_client.py<\/span>\n<span class=\"go\">@@ -628,7 +628,7 @@ class HTTPGitServer(http.server.HTTPServer):<\/span>\n<span class=\"go\">         self.server_name = &quot;localhost&quot;<\/span>\n\n<span class=\"go\">     def get_url(self):<\/span>\n<span class=\"go\">-        return &quot;http:\/\/{}:{}\/&quot;.format(self.server_name, self.server_port)<\/span>\n<span class=\"go\">+        return f&quot;http:\/\/{self.server_name}:{self.server_port}\/&quot;<\/span>\n\n\n<span class=\"go\"> class DulwichHttpClientTest(CompatTestCase, DulwichClientTestBase):<\/span>\n<span class=\"go\">...<\/span>\n<\/pre><\/div>\n<p>There is also a file called <tt class=\"docutils literal\">batch.yaml<\/tt> that describes the pending&nbsp;changes:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">pyupgrade<\/span>\n<span class=\"nt\">work<\/span><span class=\"p\">:<\/span>\n<span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">url<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">https:\/\/github.com\/dulwich\/dulwich<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">dulwich<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">description<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Upgrade to modern Python statements<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">commit-message<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Run pyupgrade<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">mode<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">propose<\/span>\n<span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">url<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">https:\/\/github.com\/jelmer\/xandikos<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">xandikos<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">description<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Upgrade to modern Python statements<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">commit-message<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Run pyupgrade<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">mode<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">propose<\/span>\n<span class=\"nt\">recipe<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">..\/pyupgrade.yaml<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>At this point the changes can be reviewed, and <tt class=\"docutils literal\">batch.yaml<\/tt> edited as the user sees fit - they\ncan remove entries that don&#8217;t appear to be correct, edit the metadata for the merge\nrequests, etc. It&#8217;s also possible to make changes to the&nbsp;clones.<\/p>\n<p>Once you&#8217;re happy, publish the&nbsp;results:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\">$ <\/span>svp<span class=\"w\"> <\/span>batch<span class=\"w\"> <\/span>publish<span class=\"w\"> <\/span>pyupgrade\n<\/pre><\/div>\n<p>This will publish all the changes, using the mode and parameters specified in\n<tt class=\"docutils literal\">batch.yaml<\/tt>.<\/p>\n<p><tt class=\"docutils literal\">batch.yaml<\/tt> is automatically stripped of any entries in work that have fully\nlanded, i.e. where the pull request has been merged or where the changes were\npushed to the&nbsp;origin.<\/p>\n<p>To check up on the status of your changes, run <tt class=\"docutils literal\">svp batch status<\/tt>:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\">$ <\/span>svp<span class=\"w\"> <\/span>batch<span class=\"w\"> <\/span>status<span class=\"w\"> <\/span>pyupgrade\n<\/pre><\/div>\n<p>To refresh any merge proposals that may have become out of date, simply run publish&nbsp;again:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"go\">svp batch publish pyupgrade<\/span>\n<\/pre><\/div>\n<\/div>\n","category":[{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"vcs"}},{"@attributes":{"term":"breezy"}},{"@attributes":{"term":"debian"}}]},{"title":"Detecting Package\u00a0Transitions","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/detecting-transitions.html","rel":"alternate"}},"published":"2022-11-29T00:04:00+01:00","updated":"2022-11-29T00:04:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2022-11-29:detecting-transitions.html","summary":"<p>Larger transitions in Debian are usually announced on e.g. debian-devel, but\nit&#8217;s harder to track the current status of all transitions. Having done a lot\nof <span class=\"caps\">QA<\/span> uploads recently, I have on occasion uploaded packages involved in a transition.\nThis can be unhelpful for the people handling the transition, but there&#8217;s also\noften not much point in uploading if your uploads are going to get&nbsp;stuck.<\/p>\n<p>Talking to one of the release managers at a recent <span class=\"caps\">BSP<\/span>, it was great to find out that\nthe <a class=\"reference external\" href=\"https:\/\/release.debian.org\">release team<\/a>\nactually publish <a class=\"reference external\" href=\"https:\/\/release.debian.org\/transitions\/export\/packages.yaml\">a data dump with which packages are\ninvolved in which transitions<\/a>.<\/p>\n<p>Here&#8217;s the script I use to find out about the transitions the package\nin my current working directory is involved&nbsp;in:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span>\n<span class=\"normal\">14<\/span>\n<span class=\"normal\">15<\/span>\n<span class=\"normal\">16<\/span>\n<span class=\"normal\">17<\/span>\n<span class=\"normal\">18<\/span>\n<span class=\"normal\">19<\/span>\n<span class=\"normal\">20<\/span>\n<span class=\"normal\">21<\/span>\n<span class=\"normal\">22<\/span>\n<span class=\"normal\">23<\/span>\n<span class=\"normal\">24<\/span>\n<span class=\"normal\">25<\/span>\n<span class=\"normal\">26<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"ch\">#!\/usr\/bin\/python3<\/span>\n\n<span class=\"kn\">from<\/span> <span class=\"nn\">urllib.request<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">urlopen<\/span>\n\n<span class=\"kn\">import<\/span> <span class=\"nn\">sys<\/span>\n\n<span class=\"kn\">from<\/span> <span class=\"nn\">debian.deb822<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">Deb822<\/span>\n<span class=\"kn\">import<\/span> <span class=\"nn\">yaml<\/span>\n\n<span class=\"k\">with<\/span> <span class=\"nb\">open<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;debian\/control&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;r&#39;<\/span><span class=\"p\">)<\/span> <span class=\"k\">as<\/span> <span class=\"n\">f<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">package<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Deb822<\/span><span class=\"p\">(<\/span><span class=\"n\">f<\/span><span class=\"p\">)[<\/span><span class=\"s1\">&#39;Source&#39;<\/span><span class=\"p\">]<\/span>\n\n<span class=\"k\">with<\/span> <span class=\"n\">urlopen<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;https:\/\/release.debian.org\/transitions\/export\/packages.yaml&quot;<\/span><span class=\"p\">)<\/span> <span class=\"k\">as<\/span> <span class=\"n\">f<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">data<\/span> <span class=\"o\">=<\/span> <span class=\"n\">yaml<\/span><span class=\"o\">.<\/span><span class=\"n\">safe_load<\/span><span class=\"p\">(<\/span><span class=\"n\">f<\/span><span class=\"p\">)<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">find_transitions<\/span><span class=\"p\">(<\/span><span class=\"n\">data<\/span><span class=\"p\">,<\/span> <span class=\"n\">package<\/span><span class=\"p\">):<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">entry<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">data<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">entry<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;name&#39;<\/span><span class=\"p\">]<\/span> <span class=\"o\">!=<\/span> <span class=\"n\">package<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">continue<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">(<\/span><span class=\"n\">entry<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;list&#39;<\/span><span class=\"p\">])<\/span>\n    <span class=\"k\">return<\/span> <span class=\"p\">{}<\/span>\n\n\n<span class=\"n\">transitions<\/span> <span class=\"o\">=<\/span> <span class=\"n\">find_transitions<\/span><span class=\"p\">(<\/span><span class=\"n\">data<\/span><span class=\"p\">,<\/span> <span class=\"n\">package<\/span><span class=\"p\">)<\/span>\n<span class=\"nb\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">transitions<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">exit<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span> <span class=\"k\">if<\/span> <span class=\"s1\">&#39;ongoing&#39;<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">transitions<\/span><span class=\"o\">.<\/span><span class=\"n\">values<\/span><span class=\"p\">()<\/span> <span class=\"k\">else<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>In practice, the output looks something like&nbsp;this:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\">$ <\/span>debcheckout<span class=\"w\"> <\/span>bctoolbox\n<span class=\"go\">git clone https:\/\/salsa.debian.org\/pkg-voip-team\/linphone-stack\/bctoolbox.git bctoolbox ...<\/span>\n<span class=\"go\">Cloning into &#39;bctoolbox&#39;...<\/span>\n<span class=\"go\">...<\/span>\n<span class=\"gp\">$ <\/span><span class=\"nb\">cd<\/span><span class=\"w\"> <\/span>bctoolbox\n<span class=\"gp\">$ <\/span><span class=\"k\">in<\/span>-transition.py\n<span class=\"go\">{&#39;auto-upperlimit-libbctoolbox1&#39;: &#39;ongoing&#39;}<\/span>\n<\/pre><\/div>\n","category":{"@attributes":{"term":"debian"}}},{"title":"Bye bye\u00a0Batavus","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/bye-bye-batavus.html","rel":"alternate"}},"published":"2022-08-27T11:11:00+02:00","updated":"2022-08-27T11:11:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2022-08-27:bye-bye-batavus.html","summary":"<p>After almost 20 years of service and upwards of 50.000km traveled, it&#8217;s finally time to retire my good old&nbsp;Batavus.<\/p>\n<p>I bought this bike in 2003 for less than 1000 euros, but it&#8217;s done surprisingly well. It&#8217;s been across the continent and back a couple of&nbsp;times.<\/p>\n<p>The potholes in England have proved too much though and it&#8217;s developed a fairly large crack in the front&nbsp;tube.<\/p>\n<img alt=\"Before disassembling in Link\u00f6ping\" src=\"\/images\/batavus-linkoping.jpg\" style=\"width: 410px; height: 307px;\" \/>\n","category":[{"@attributes":{"term":"cycling"}},{"@attributes":{"term":"batavus"}}]},{"title":"Personal Streaming Audio\u00a0Server","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/navidrome.html","rel":"alternate"}},"published":"2022-01-04T19:00:00+01:00","updated":"2022-01-04T19:00:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2022-01-04:navidrome.html","summary":"<p>For a while now, I&#8217;ve been looking for a good way to stream music from my home\nmusic collection on my&nbsp;phone.<\/p>\n<p>There are quite a few options for music servers that support streaming. However,\nAndroid apps that can stream music from one of those servers tend to be\nunmaintained, clunky or slow (or more than one of&nbsp;those).<\/p>\n<p>It is possible to use something that runs in a web server, but that means\nno offline caching - which can be quite convenient in spots without\nconnectivity, such as the Underground or other random bits of London with poor\ncell&nbsp;coverage.<\/p>\n<div class=\"section\" id=\"server\">\n<h2>Server<\/h2>\n<p>Most music servers today support some form of the subsonic <span class=\"caps\">API<\/span>.<\/p>\n<p>I&#8217;ve tried a couple, with mixed&nbsp;results:<\/p>\n<blockquote>\n<ul class=\"simple\">\n<li>supysonic; Python. Slow. Ran into some issues with subsonic clients. No real web <span class=\"caps\">UI<\/span>.<\/li>\n<li>gonic; Go. Works well <span class=\"amp\">&amp;<\/span> fast enough. Minimal web <span class=\"caps\">UI<\/span>, i.e. no ability to play music from a&nbsp;browser.<\/li>\n<li>airsonic; Java. Last in a chain of (abandoned) forks. More effort to get to work, and resource&nbsp;intensive.<\/li>\n<\/ul>\n<\/blockquote>\n<p>Eventually, I&#8217;ve settled on <a class=\"reference external\" href=\"https:\/\/www.navidrome.org\/\">Navidrome<\/a>. It&#8217;s got a\ncouple of things going for&nbsp;it:<\/p>\n<blockquote>\n<ul class=\"simple\">\n<li>Good subsonic implementation that worked with all the Android apps I used it&nbsp;with.<\/li>\n<li>Great Web <span class=\"caps\">UI<\/span> for use in a&nbsp;browser<\/li>\n<\/ul>\n<\/blockquote>\n<p>I run Navidrome in Kubernetes. It&#8217;s surprisingly easy to get going. Here&#8217;s the\ndeployment I&#8217;m&nbsp;using:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span>\n<span class=\"normal\">14<\/span>\n<span class=\"normal\">15<\/span>\n<span class=\"normal\">16<\/span>\n<span class=\"normal\">17<\/span>\n<span class=\"normal\">18<\/span>\n<span class=\"normal\">19<\/span>\n<span class=\"normal\">20<\/span>\n<span class=\"normal\">21<\/span>\n<span class=\"normal\">22<\/span>\n<span class=\"normal\">23<\/span>\n<span class=\"normal\">24<\/span>\n<span class=\"normal\">25<\/span>\n<span class=\"normal\">26<\/span>\n<span class=\"normal\">27<\/span>\n<span class=\"normal\">28<\/span>\n<span class=\"normal\">29<\/span>\n<span class=\"normal\">30<\/span>\n<span class=\"normal\">31<\/span>\n<span class=\"normal\">32<\/span>\n<span class=\"normal\">33<\/span>\n<span class=\"normal\">34<\/span>\n<span class=\"normal\">35<\/span>\n<span class=\"normal\">36<\/span>\n<span class=\"normal\">37<\/span>\n<span class=\"normal\">38<\/span>\n<span class=\"normal\">39<\/span>\n<span class=\"normal\">40<\/span>\n<span class=\"normal\">41<\/span>\n<span class=\"normal\">42<\/span>\n<span class=\"normal\">43<\/span>\n<span class=\"normal\">44<\/span>\n<span class=\"normal\">45<\/span>\n<span class=\"normal\">46<\/span>\n<span class=\"normal\">47<\/span>\n<span class=\"normal\">48<\/span>\n<span class=\"normal\">49<\/span>\n<span class=\"normal\">50<\/span>\n<span class=\"normal\">51<\/span>\n<span class=\"normal\">52<\/span>\n<span class=\"normal\">53<\/span>\n<span class=\"normal\">54<\/span>\n<span class=\"normal\">55<\/span>\n<span class=\"normal\">56<\/span>\n<span class=\"normal\">57<\/span>\n<span class=\"normal\">58<\/span>\n<span class=\"normal\">59<\/span>\n<span class=\"normal\">60<\/span>\n<span class=\"normal\">61<\/span>\n<span class=\"normal\">62<\/span>\n<span class=\"normal\">63<\/span>\n<span class=\"normal\">64<\/span>\n<span class=\"normal\">65<\/span>\n<span class=\"normal\">66<\/span>\n<span class=\"normal\">67<\/span>\n<span class=\"normal\">68<\/span>\n<span class=\"normal\">69<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">apps\/v1<\/span>\n<span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Deployment<\/span>\n<span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span>\n<span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome<\/span>\n<span class=\"nt\">spec<\/span><span class=\"p\">:<\/span>\n<span class=\"w\"> <\/span><span class=\"nt\">replicas<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">1<\/span>\n<span class=\"w\"> <\/span><span class=\"nt\">selector<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">   <\/span><span class=\"nt\">matchLabels<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">     <\/span><span class=\"nt\">app<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome<\/span>\n<span class=\"w\"> <\/span><span class=\"nt\">template<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">   <\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">     <\/span><span class=\"nt\">labels<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">       <\/span><span class=\"nt\">app<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome<\/span>\n<span class=\"w\">   <\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">     <\/span><span class=\"nt\">containers<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">       <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome<\/span>\n<span class=\"w\">         <\/span><span class=\"nt\">image<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">deluan\/navidrome:latest<\/span>\n<span class=\"w\">         <\/span><span class=\"nt\">imagePullPolicy<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Always<\/span>\n<span class=\"w\">         <\/span><span class=\"nt\">resources<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">           <\/span><span class=\"nt\">limits<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">cpu<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s\">&quot;.5&quot;<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">memory<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s\">&quot;2Gi&quot;<\/span>\n<span class=\"w\">           <\/span><span class=\"nt\">requests<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">cpu<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s\">&quot;0.1&quot;<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">memory<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s\">&quot;10M&quot;<\/span>\n<span class=\"w\">         <\/span><span class=\"nt\">ports<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">           <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">containerPort<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">4533<\/span>\n<span class=\"w\">         <\/span><span class=\"nt\">volumeMounts<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">           <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome-data-volume<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">mountPath<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">\/data<\/span>\n<span class=\"w\">           <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome-music-volume<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">mountPath<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">\/music<\/span>\n<span class=\"w\">         <\/span><span class=\"nt\">env<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">           <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">ND_SCANSCHEDULE<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">value<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">1h<\/span>\n<span class=\"w\">           <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">ND_LOGLEVEL<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">value<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">info<\/span>\n<span class=\"w\">           <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">ND_SESSIONTIMEOUT<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">value<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">24h<\/span>\n<span class=\"w\">           <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">ND_BASEURL<\/span>\n<span class=\"w\">             <\/span><span class=\"nt\">value<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">\/navidrome<\/span>\n<span class=\"w\">         <\/span><span class=\"nt\">livenessProbe<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">            <\/span><span class=\"nt\">httpGet<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">              <\/span><span class=\"nt\">path<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">\/navidrome\/app<\/span>\n<span class=\"w\">              <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">4533<\/span>\n<span class=\"w\">            <\/span><span class=\"nt\">initialDelaySeconds<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">30<\/span>\n<span class=\"w\">            <\/span><span class=\"nt\">periodSeconds<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">3<\/span>\n<span class=\"w\">            <\/span><span class=\"nt\">timeoutSeconds<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">90<\/span>\n<span class=\"w\">     <\/span><span class=\"nt\">volumes<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">        <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome-data-volume<\/span>\n<span class=\"w\">          <\/span><span class=\"nt\">hostPath<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">           <\/span><span class=\"nt\">path<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">\/srv\/navidrome<\/span>\n<span class=\"w\">           <\/span><span class=\"nt\">type<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Directory<\/span>\n<span class=\"w\">        <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome-music-volume<\/span>\n<span class=\"w\">          <\/span><span class=\"nt\">hostPath<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">            <\/span><span class=\"nt\">path<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">\/srv\/media\/music<\/span>\n<span class=\"w\">            <\/span><span class=\"nt\">type<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Directory<\/span>\n<span class=\"nn\">---<\/span>\n<span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">v1<\/span>\n<span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Service<\/span>\n<span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome<\/span>\n<span class=\"nt\">spec<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">ports<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">    <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">4533<\/span>\n<span class=\"w\">      <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">web<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">selector<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">    <\/span><span class=\"nt\">app<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">type<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">ClusterIP<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>At the moment, this deployment is still tied to the machine with my music\non it since it relies on <tt class=\"docutils literal\">hostPath<\/tt> volumes, but I&#8217;m planning to move that to\nceph in the&nbsp;future.<\/p>\n<p>I then expose this service on <em>\/navidrome<\/em> on my private domain (here replaced\nwith <em>example.com<\/em>) using an&nbsp;Ingress:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span>\n<span class=\"normal\">14<\/span>\n<span class=\"normal\">15<\/span>\n<span class=\"normal\">16<\/span>\n<span class=\"normal\">17<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">networking.k8s.io\/v1<\/span>\n<span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Ingress<\/span>\n<span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome<\/span>\n<span class=\"nt\">spec<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">ingressClassName<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">nginx<\/span>\n<span class=\"w\">  <\/span><span class=\"nt\">rules<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">  <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">host<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">example.com<\/span>\n<span class=\"w\">    <\/span><span class=\"nt\">http<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">      <\/span><span class=\"nt\">paths<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">      <\/span><span class=\"p p-Indicator\">-<\/span><span class=\"w\"> <\/span><span class=\"nt\">backend<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">          <\/span><span class=\"nt\">service<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">            <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">navidrome<\/span>\n<span class=\"w\">            <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span>\n<span class=\"w\">              <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">web<\/span>\n<span class=\"w\">        <\/span><span class=\"nt\">path<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">\/navidrome(\/|$)(.*)<\/span>\n<span class=\"w\">        <\/span><span class=\"nt\">pathType<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">Prefix<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<\/div>\n<div class=\"section\" id=\"client\">\n<h2>Client<\/h2>\n<p>On the desktop, I usually just use navidrome&#8217;s web interface. Clementine&#8217;s support\nfor subsonic is also okay. sublime-music is meant to be a music player\nspecifically for Subsonic, but I&#8217;ve not really found it stable enough for\nday-to-day&nbsp;usage.<\/p>\n<p>There are various Android clients for Subsonic, but I&#8217;ve only really considered the\nOpen Source ones that are hosted on F-Droid. Most of those are\nabandoned, but D-Sub works pretty well - as does my preferred option, <a class=\"reference external\" href=\"https:\/\/f-droid.org\/en\/packages\/com.subtracks\/\">Subtracks<\/a>.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"navidrome"}},{"@attributes":{"term":"subsonic"}},{"@attributes":{"term":"k8s"}}]},{"title":"Web Hooks for the\u00a0Janitor","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-webhooks.html","rel":"alternate"}},"published":"2021-09-06T22:00:00+02:00","updated":"2021-09-06T22:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2021-09-06:janitor-webhooks.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>As covered in <a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/fresh-builds.html\">my post from last week<\/a>, the Janitor now regularly tries to\nimport new upstream git snapshots or upstream releases into packages in <a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/DebianUnstable\">Sid<\/a>.<\/p>\n<div class=\"section\" id=\"moving-parts\">\n<h2>Moving&nbsp;parts<\/h2>\n<p>There are about 30,000 packages in sid, and it usually takes a couple of weeks\nfor the janitor to cycle through all of them. Generally speaking, there are up\nto three moving targets for each&nbsp;package:<\/p>\n<ul class=\"simple\">\n<li>The packaging repository; <a class=\"reference external\" href=\"https:\/\/qa.debian.org\/cgi-bin\/vcswatch\">vcswatch<\/a> regularly scans this for changes,\nand notifies the janitor when a repository has changed. For <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\">salsa<\/a>\nrepositories it is instantly notified through a web&nbsp;hook<\/li>\n<li>The upstream release tarballs; the <span class=\"caps\">QA<\/span> watch service regularly polls these,\nand the janitor scans for changes in the <span class=\"caps\">UDD<\/span> tables with watch data (used for\n<a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/fresh-releases\/\">fresh-releases<\/a>)<\/li>\n<li>The upstream repository; there is no service in Debian that watches this at\nthe moment (used for\n<a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/fresh-snapshots\/\">fresh-snapshots<\/a>)<\/li>\n<\/ul>\n<p>When the janitor notices that one of these three targets has changed, it\nprioritizes processing of a package - this means that a push to a packaging\nrepository on salsa usually leads to a build being kicked off within 10\nminutes. New upstream releases are usually noticed by <span class=\"caps\">QA<\/span> watch within a day or\nso and then lead to a build. Now commits in upstream repositories don&#8217;t get\nnoticed&nbsp;today.<\/p>\n<p>Note that there are no guarantees; the scheduler tries to be clever and not\ne.g. rebuild the same package over and over again if it&#8217;s constantly changing\nand takes a long time to&nbsp;build.<\/p>\n<p>Packages without priority are processed with a scoring system that takes into\naccount perceived value (based on e.g. popcon), cost (based on wall-time\nduration of previous builds) and likelihood of success (whether recent builds\nwere successful, and how frequently the repositories involved&nbsp;change).<\/p>\n<\/div>\n<div class=\"section\" id=\"webhooks-for-upstream-repositories\">\n<h2>webhooks for upstream&nbsp;repositories<\/h2>\n<p>At the moment there is no service in Debian (yet - perhaps this is something\nthat vcswatch or a sibling service could also do?) that scans upstream\nrepositories for&nbsp;changes.<\/p>\n<p>However, if you maintain an upstream package, you can use a webhook to notify\nthe janitor that commits have been made to your repository, and it will create\na new package in fresh-snapshots. Webhooks from the\nfollowing hosting site software are currently&nbsp;supported:<\/p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https:\/\/github.com\/\">GitHub<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/gitlab.com\/\">Gitlab<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/launchpad.net\/\">Launchpad<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/gitea.io\/\">Gitea<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/gogs.io\/\">Gogs<\/a><\/li>\n<\/ul>\n<p>You can simply use the <span class=\"caps\">URL<\/span> <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/\">https:\/\/janitor.debian.net\/<\/a> as the target for hooks. There is no need to specify a secret, and the hook can either use a <span class=\"caps\">JSON<\/span> or form encoding&nbsp;payload.<\/p>\n<p>The endpoint should tell you whether it understood a webhook request, and\nwhether it took any action. It&#8217;s fine to submit webhooks for repositories that\nthe janitor does not (yet) know&nbsp;about.<\/p>\n<div class=\"section\" id=\"github-1\">\n<h3>GitHub<\/h3>\n<p>For GitHub, you can do so in the <tt class=\"docutils literal\">Webhooks<\/tt> section of the <tt class=\"docutils literal\">Settings<\/tt> tab. Fill the form as shown below and click on <tt class=\"docutils literal\">Add webhook<\/tt>:<\/p>\n<img alt=\"\" src=\"\/images\/github-webhook.png\" \/>\n<\/div>\n<div class=\"section\" id=\"gitlab-1\">\n<h3>GitLab<\/h3>\n<p>On GitLab instances, you can find the <tt class=\"docutils literal\">Webhooks<\/tt> tab under the <tt class=\"docutils literal\">Settings<\/tt> menu for each repository (under the gear symbol). Fill the form in as shown below and click <tt class=\"docutils literal\">Add Webhook<\/tt>:<\/p>\n<img alt=\"\" src=\"\/images\/gitlab-webhook.png\" \/>\n<\/div>\n<div class=\"section\" id=\"launchpad-1\">\n<h3>Launchpad<\/h3>\n<p>For Launchpad, go to the repository (for Git) web view and click <tt class=\"docutils literal\">Manage Webhooks<\/tt>. From there, you can add a new webhook; fill the form in as shown below and click <tt class=\"docutils literal\">Add Webhook<\/tt>:<\/p>\n<img alt=\"\" src=\"\/images\/launchpad-webhook-git.png\" \/>\n<\/div>\n<\/div>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor-update"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Thousands of Debian packages updated from their upstream Git\u00a0repository","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/fresh-builds.html","rel":"alternate"}},"published":"2021-08-25T20:00:00+02:00","updated":"2021-08-25T20:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2021-08-25:fresh-builds.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>Linux distributions like Debian fulfill an important function in the <span class=\"caps\">FOSS<\/span> ecosystem - they are system integrators that take existing free and open source software projects and adapt them where necessary to work well together. They also make it possible for users to install more software in an easy and consistent way and with some degree of quality control and&nbsp;review.<\/p>\n<p>One of the consequences of this model is that the distribution package often lags behind upstream releases. This is especially true for distributions that have tighter integration and standardization (such as Debian), and often new upstream code is only imported irregularly because it is a manual process - both updating the package, but also making sure that it still works together well with the rest of the&nbsp;system.<\/p>\n<p>The process of importing a new upstream used to be (well, back when I started working on\nDebian packages) fairly manual and something like&nbsp;this:<\/p>\n<ul class=\"simple\">\n<li>Go to the upstream&#8217;s homepage, find the tarball and signature and verify the&nbsp;tarball<\/li>\n<li>Make modifications so the tarball matches Debian&#8217;s&nbsp;format<\/li>\n<li>Diff the original and new upstream tarballs and figure out whether changes\nare reasonable and which require packaging&nbsp;changes<\/li>\n<li>Update the packaging, changelog, build and manually test the&nbsp;package<\/li>\n<li>Upload<\/li>\n<\/ul>\n<div class=\"section\" id=\"ecosystem-improvements\">\n<h2>Ecosystem&nbsp;Improvements<\/h2>\n<p>However, there have been developments over the last decade that make it easier to import new upstream releases into Debian&nbsp;packages.<\/p>\n<div class=\"section\" id=\"uscan-and-debian-qa-watch\">\n<h3>Uscan and debian <span class=\"caps\">QA<\/span>&nbsp;watch<\/h3>\n<p><a class=\"reference external\" href=\"https:\/\/manpages.debian.org\/buster\/devscripts\/uscan.1.en.html\">Uscan<\/a> and\n<a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/debian\/watch\">debian\/watch<\/a> have been around for a\nwhile and make it possible to find upstream&nbsp;tarballs.<\/p>\n<p>A debian watch file usually looks something like&nbsp;this:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"go\">version=4<\/span>\n<span class=\"go\">http:\/\/somesite.com\/dir\/filenamewithversion.tar.gz<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>The <a class=\"reference external\" href=\"https:\/\/qa.debian.org\/cgi-bin\/watch\"><span class=\"caps\">QA<\/span> watch service<\/a> regularly polls\nall watch locations in the archive and makes the information available, so it\u2019s\npossible to know which packages have changed without downloading each one of&nbsp;them.<\/p>\n<\/div>\n<div class=\"section\" id=\"git\">\n<h3>Git<\/h3>\n<p>Git is fairly ubiquitous nowadays, and most upstream projects and packages in Debian use it. There are still exceptions that do not use any version control system or that use a different control system, but they are becoming increasingly rare. <a class=\"footnote-reference\" href=\"#footnote-1\" id=\"footnote-reference-1\">[1]<\/a><\/p>\n<a class=\"reference external image-reference\" href=\"https:\/\/trends.debian.net\/#version-control-system\">\n<img alt=\"\" src=\"https:\/\/trends.debian.net\/vcs_testing-stacked.png\" \/>\n<\/a>\n<\/div>\n<div class=\"section\" id=\"debian-upstream-metadata\">\n<h3>debian\/upstream\/metadata<\/h3>\n<p><a class=\"reference external\" href=\"https:\/\/dep-team.pages.debian.net\/deps\/dep12\/\"><span class=\"caps\">DEP<\/span>-12<\/a> specifies a file format with metadata about the upstream project that a package was based on. In particular relevant for our case is the fact it has fields for the location of the upstream version control&nbsp;location.<\/p>\n<p>debian\/upstream\/metadata files look something like&nbsp;this:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"nn\">---<\/span>\n<span class=\"nt\">Repository<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">https:\/\/www.dulwich.io\/code\/dulwich\/<\/span>\n<span class=\"nt\">Repository-Browse<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l l-Scalar l-Scalar-Plain\">https:\/\/www.dulwich.io\/code\/dulwich\/<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>While <span class=\"caps\">DEP<\/span>-12 is still a draft, it has already been widely adopted - there are <a class=\"reference external\" href=\"https:\/\/codesearch.debian.net\/search?q=path%3Adebian%2Fupstream%2Fmetadata+Repository%3A&amp;literal=1\">about 10000 packages<\/a> in Debian that ship a debian\/upstream\/metadata file with Repository&nbsp;information.<\/p>\n<\/div>\n<div class=\"section\" id=\"autopkgtest\">\n<h3>Autopkgtest<\/h3>\n<p>The <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/ci-team\/autopkgtest\/-\/blob\/master\/doc\/README.package-tests.rst\">Autopkgtest<\/a>\nstandard and associated tooling provide a way to run a defined set of tests\nagainst an installed package. This makes it possible to verify that a package\nis working correctly as part of the system as a whole. <a class=\"reference external\" href=\"https:\/\/ci.debian.net\">ci.debian.net<\/a> regularly runs these tests against Debian packages to\ndetect&nbsp;regressions.<\/p>\n<\/div>\n<div class=\"section\" id=\"vcs-git-headers\">\n<h3>Vcs-Git&nbsp;headers<\/h3>\n<p>The Vcs-Git headers in debian\/control are the equivalent of the Repository field in debian\/upstream\/metadata, but for the packaging repositories (as opposed to the upstream&nbsp;ones).<\/p>\n<p>They\u2019ve been around for a while and are widely adopted, as can be seen from <a class=\"reference external\" href=\"https:\/\/upsilon.cc\/~zack\/stuff\/vcs-usage\/\">zack\u2019s stats<\/a>:<\/p>\n<img alt=\"\" src=\"\/images\/fresh-builds-vcs.png\" \/>\n<p>The <a class=\"reference external\" href=\"https:\/\/qa.debian.org\/cgi-bin\/vcswatch\">vcswatch service<\/a> that regularly\npolls packaging repositories to see whether they have changed makes it a lot\neasier to consume this information in usable&nbsp;way.<\/p>\n<\/div>\n<div class=\"section\" id=\"debhelper-adoption\">\n<h3>Debhelper&nbsp;adoption<\/h3>\n<p>Over the last couple of years, Debian has slowly been converging on a single\nbuild tool - debhelper\u2019s dh&nbsp;interface.<\/p>\n<p>Being able to rely on a single build tool makes it easier to write code to\nupdate packaging when upstream changes require&nbsp;it.<\/p>\n<a class=\"reference external image-reference\" href=\"https:\/\/trends.debian.net\/#build-systems\">\n<img alt=\"\" src=\"https:\/\/trends.debian.net\/build-system_testing-stacked.png\" \/>\n<\/a>\n<\/div>\n<div class=\"section\" id=\"debhelper-dwim\">\n<h3>Debhelper <span class=\"caps\">DWIM<\/span><\/h3>\n<p>Debhelper (and its helpers) increasingly can figure out how to do the Right\nThing in many cases without being explicitly configured. This makes packaging\nless effort, but also means that it\u2019s less likely that importing a new upstream\nversion will require updates to the&nbsp;packaging.<\/p>\n<p>With all of these improvements in place, it actually becomes feasible in a lot\nof situations to update a Debian package to a new upstream version\nautomatically. Of course, this requires that all of this information is\navailable, so it won\u2019t work for all packages. In some cases, the packaging for\nthe older upstream version might not apply to the newer upstream&nbsp;version.<\/p>\n<p>The Janitor has attempted to import a new upstream Git snapshot and a new\nupstream release for every package in the archive where a debian\/watch file or\ndebian\/upstream\/metadata file are&nbsp;present.<\/p>\n<p>These are the steps it&nbsp;uses:<\/p>\n<ul class=\"simple\">\n<li><dl class=\"first docutils\">\n<dt>Find new upstream&nbsp;version<\/dt>\n<dd><ul class=\"first last\">\n<li>If release, use debian\/watch - or maybe tagged in upstream&nbsp;repository<\/li>\n<li>If snapshot, use debian\/upstream\/metadata\u2019s Repository&nbsp;field<\/li>\n<li><em>If neither is available, use guess-upstream-metadata from upstream-ontologist to guess the upstream&nbsp;Repository<\/em><\/li>\n<\/ul>\n<\/dd>\n<\/dl>\n<\/li>\n<li>Merge upstream version into packaging repository, possibly importing tarballs using&nbsp;pristine-tar<\/li>\n<li>Update the changelog file to mention the new upstream&nbsp;version<\/li>\n<li><dl class=\"first docutils\">\n<dt>Run some checks to ensure there are no unintentional changes,&nbsp;e.g.:<\/dt>\n<dd><ul class=\"first last\">\n<li><dl class=\"first docutils\">\n<dt>Scan diff between old and new for surprising license&nbsp;changes<\/dt>\n<dd><ul class=\"first last\">\n<li>Today, abort if there are any - in the future, maybe update&nbsp;debian\/copyright<\/li>\n<\/ul>\n<\/dd>\n<\/dl>\n<\/li>\n<li>Check for obvious compatibility breaks - e.g. sonames&nbsp;changing<\/li>\n<\/ul>\n<\/dd>\n<\/dl>\n<\/li>\n<li><dl class=\"first docutils\">\n<dt>Attempt to update the packaging to reflect upstream&nbsp;changes<\/dt>\n<dd><ul class=\"first last\">\n<li>Refresh&nbsp;patches<\/li>\n<\/ul>\n<\/dd>\n<\/dl>\n<\/li>\n<li>Attempt to build the package with deb-fix-build, to deal with any missing&nbsp;dependencies<\/li>\n<li>Run the autopkgtests with deb-fix-build to deal with missing dependencies, and abort if any tests&nbsp;fail<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<div class=\"section\" id=\"results\">\n<h2>Results<\/h2>\n<p>When run over all packages in unstable (<a class=\"reference external\" href=\"https:\/\/packages.debian.org\/unstable\">sid<\/a>), this process works for a surprising number of&nbsp;them.<\/p>\n<div class=\"section\" id=\"fresh-releases\">\n<h3>Fresh&nbsp;Releases<\/h3>\n<p>For fresh-releases (aka imports of upstream releases), processing all packages maintained in Git for which <span class=\"caps\">QA<\/span> watch reports new releases (about&nbsp;11,000):<\/p>\n<img alt=\"\" src=\"\/images\/fresh-releases.png\" \/>\n<p>That means about 2300 packages updated, and about 4000&nbsp;unchanged.<\/p>\n<\/div>\n<div class=\"section\" id=\"fresh-snapshots\">\n<h3>Fresh&nbsp;Snapshots<\/h3>\n<p>For fresh-snapshots (aka imports of latest Git commit from upstream), processing all packages maintained in Git (about&nbsp;26,000):<\/p>\n<img alt=\"\" src=\"\/images\/fresh-snapshots.png\" \/>\n<p>Or 5100 packages updated and 2100 for which there was nothing to do, i.e. no upstream commits since the last Debian&nbsp;upload.<\/p>\n<p>As can be seen, this works for a surprising fraction of packages. It\u2019s possible to get the numbers up even higher, by both improving the tooling, the autopkgtests and the metadata that is provided by&nbsp;packages.<\/p>\n<\/div>\n<\/div>\n<div class=\"section\" id=\"using-these-packages\">\n<h2>Using these&nbsp;packages<\/h2>\n<p>All the packages that have been built can be accessed from the Janitor <span class=\"caps\">APT<\/span> repository. More information can be found at <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/fresh\">https:\/\/janitor.debian.net\/fresh<\/a>, but in short -&nbsp;run:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span>\n<span class=\"normal\">5<\/span>\n<span class=\"normal\">6<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"go\">echo deb &quot;[arch=amd64 signed-by=\/usr\/share\/keyrings\/debian-janitor-archive-keyring.gpg]&quot; \\<\/span>\n<span class=\"go\">    https:\/\/janitor.debian.net\/ fresh-snapshots main | sudo tee \/etc\/apt\/sources.list.d\/fresh-snapshots.list<\/span>\n<span class=\"go\">echo deb &quot;[arch=amd64 signed-by=\/usr\/share\/keyrings\/debian-janitor-archive-keyring.gpg]&quot; \\<\/span>\n<span class=\"go\">    https:\/\/janitor.debian.net\/ fresh-releases main | sudo tee \/etc\/apt\/sources.list.d\/fresh-releases.list<\/span>\n<span class=\"go\">sudo curl -o \/usr\/share\/keyrings\/debian-janitor-archive-keyring.gpg https:\/\/janitor.debian.net\/pgp_keys<\/span>\n<span class=\"go\">apt update<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>And then you can install packages from the fresh-snapshots (upstream git snapshots) or fresh-releases suites on a case-by-case basis by running something&nbsp;like:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"go\">apt install -t fresh-snapshots r-cran-roxygen2<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>Most packages are updated based on information provided by vcswatch and qa watch, but it\u2019s also possible for upstream repositories to call a web hook to trigger <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/fresh-builds#requesting-new-packages\">a refresh of a package<\/a>.<\/p>\n<p>These packages were built against unstable, but should in almost all cases also work for&nbsp;testing.<\/p>\n<\/div>\n<div class=\"section\" id=\"caveats\">\n<h2>Caveats<\/h2>\n<p>Of course, since these packages are built automatically without human supervision it\u2019s likely that some of them will have bugs in them that would otherwise have been caught by the&nbsp;maintainer.<\/p>\n<table class=\"docutils footnote\" frame=\"void\" id=\"footnote-1\" rules=\"none\">\n<colgroup><col class=\"label\" \/><col \/><\/colgroup>\n<tbody valign=\"top\">\n<tr><td class=\"label\"><a class=\"fn-backref\" href=\"#footnote-reference-1\">[1]<\/a><\/td><td>I\u2019m not saying that a monoculture is great here, but it does help distributions.<\/td><\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor-update"}},{"@attributes":{"term":"git"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Ognibuild","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/ognibuild.html","rel":"alternate"}},"published":"2021-05-14T20:00:00+02:00","updated":"2021-05-14T20:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2021-05-14:ognibuild.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>The <span class=\"caps\">FOSS<\/span> world uses a wide variety of different build tools; given a git\nrepository or tarball, it can be hard to figure out how to build and install a\npiece of&nbsp;software.<\/p>\n<p>Humans will generally know what build tool a project is using when they check\nout a project from git, or they can read the <span class=\"caps\">README<\/span>. And even then, the answer\nmay not always be straightforward to everybody. For automation, there\nis no obvious place to figure out how to build or install a&nbsp;project.<\/p>\n<div class=\"section\" id=\"debian\">\n<h2>Debian<\/h2>\n<p>For Debian packages, Debian maintainers generally will have determined\nthat the appropriate tools to invoke are, and added appropriate invocations to\n<em>debian\/rules<\/em>. This is really nice when rebuilding all of Debian - one can just\ninvoke <em>debian\/rules<\/em> - a consistent interface - and it will in turn invoke the\nright tools to build the package, meeting <a class=\"reference external\" href=\"https:\/\/www.debian.org\/doc\/debian-policy\/\">a long list of requirements<\/a>.<\/p>\n<p>With newer versions of <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/debian\/debhelper\">debhelper<\/a>\nand most common build systems, debhelper can figure a lot of this out\nautomatically - the maintainer just has to add the\nappropriate build and run time&nbsp;dependencies.<\/p>\n<p>However, debhelper needs to be consistent in its behaviour per compat level -\notherwise builds might start failing with different versions of debhelper, when\nthe autodetection logic is changed. debhelper can also only do the right thing\nif all the necessary dependencies are present. debhelper also only functions\nin the context of a Debian&nbsp;package.<\/p>\n<\/div>\n<div class=\"section\" id=\"ognibuild-1\">\n<h2>Ognibuild<\/h2>\n<p><a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/ognibuild\">Ognibuild<\/a> is a new tool that figures\nout the build system in use by an upstream project, as well as the other\ndependencies it needs. This information can then be used to invoke said build\nsystem, or to e.g. add missing build dependencies to a Debian&nbsp;package.<\/p>\n<p>Ognibuild uses a variety of techniques to work out what the dependencies for an\nupstream package&nbsp;are:<\/p>\n<ul class=\"simple\">\n<li>Extracting dependencies and other requirements declared in build system\nmetadata (e.g.&nbsp;setup.py)<\/li>\n<li>Attempting builds and parsing build logs for missing dependencies (repeating\nuntil the build succeeds), calling out to <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/buildlog-consultant\">buildlog-consultant<\/a><\/li>\n<\/ul>\n<p>Once it is determined which dependencies are missing, they can be resolved in a\nvariety of ways. Apt can be invoked to install missing dependencies on Debian\nsystems (optionally in a chroot) or ecosystem-specific tools can be used to do\nso (e.g. <a class=\"reference external\" href=\"https:\/\/pypi.org\/\">pypi<\/a> or <a class=\"reference external\" href=\"https:\/\/www.cpan.org\/\">cpan<\/a>).\nInstead of installing packages, the tool can also simply\ninform the user about the missing packages and commands to install them, or\nupdate a Debian package appropriately (this is what <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/deb-fix-build.html\">deb-fix-build<\/a>&nbsp;does).<\/p>\n<p>The target audience of ognibuild are people who need to (possibly from\nautomation) build a variety of projects from different ecosystems or users who\nare looking to just install a project from source. Developers who are just\nhacking on e.g. a Python project are better off directly invoking the\necosystem-native tools rather than a wrapper like&nbsp;ognibuild.<\/p>\n<\/div>\n<div class=\"section\" id=\"supported-ecosystems\">\n<h2>Supported&nbsp;ecosystems<\/h2>\n<p>(Partially) supported ecosystems currently&nbsp;include:<\/p>\n<ul class=\"simple\">\n<li>Combinations of make and autoconf, automake or&nbsp;CMake<\/li>\n<li>Python, including fetching packages from&nbsp;pypi<\/li>\n<li>Perl, including fetching packages from&nbsp;cpan<\/li>\n<li>Haskell, including fetching from&nbsp;hackage<\/li>\n<li>Ninja\/Meson<\/li>\n<li>Maven<\/li>\n<li>Rust, including fetching packages from&nbsp;crates.io<\/li>\n<li><span class=\"caps\">PHP<\/span>&nbsp;Pear<\/li>\n<li>R, including fetching packages from <span class=\"caps\">CRAN<\/span> and&nbsp;Bioconductor<\/li>\n<\/ul>\n<p>For a full list, see <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/ognibuild\/blob\/main\/README.md\">the <span class=\"caps\">README<\/span><\/a>.<\/p>\n<\/div>\n<div class=\"section\" id=\"usage\">\n<h2>Usage<\/h2>\n<p>Ognibuild provides a couple of top-level subcommands that will seem familiar to anybody who has used a couple of other build&nbsp;systems:<\/p>\n<ul class=\"simple\">\n<li><em>ogni clean<\/em> - remove build&nbsp;artifacts<\/li>\n<li><em>ogni dist<\/em> - create a dist&nbsp;tarball<\/li>\n<li><em>ogni build<\/em> - build the project in the current&nbsp;directory<\/li>\n<li><em>ogni test<\/em> - run the test&nbsp;suite<\/li>\n<li><em>ogni install<\/em> - install the project&nbsp;somewhere<\/li>\n<li><em>ogni info<\/em> - display project information including discovered build system and&nbsp;dependencies<\/li>\n<li><em>ogni exec<\/em> - run an arbitrary command but attempt to resolve issues like missing&nbsp;dependencies<\/li>\n<\/ul>\n<p>These tools all take a couple of common&nbsp;options:<\/p>\n<div class=\"section\" id=\"resolve-apt-auto-native\">\n<h3>&#8212;resolve=apt|auto|native<\/h3>\n<p>Specifies how to resolve any missing&nbsp;dependencies:<\/p>\n<ul class=\"simple\">\n<li><strong>apt<\/strong>: install the appropriate dependency using&nbsp;apt<\/li>\n<li><strong>native<\/strong>: install dependencies using native tools like pip or&nbsp;cpan<\/li>\n<li><strong>auto<\/strong>: invoke either apt or native package install, depending on whether\nthe current user is allowed to invoke&nbsp;apt<\/li>\n<\/ul>\n<\/div>\n<div class=\"section\" id=\"schroot-name\">\n<h3>&#8212;schroot=name<\/h3>\n<p>Run inside of a&nbsp;schroot.<\/p>\n<\/div>\n<div class=\"section\" id=\"explain\">\n<h3>&#8212;explain<\/h3>\n<p>do not make any changes but tell the user which native on apt packages they could&nbsp;install.<\/p>\n<p>There are also subcommand-specific options, e.g. to install to a specific directory on restrict which tests are&nbsp;run.<\/p>\n<\/div>\n<\/div>\n<div class=\"section\" id=\"examples\">\n<h2>Examples<\/h2>\n<div class=\"section\" id=\"creating-a-dist-tarball\">\n<h3>Creating a dist&nbsp;tarball<\/h3>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span>\n<span class=\"normal\">5<\/span>\n<span class=\"normal\">6<\/span>\n<span class=\"normal\">7<\/span>\n<span class=\"normal\">8<\/span>\n<span class=\"normal\">9<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"gp\">% <\/span>git<span class=\"w\"> <\/span>clone<span class=\"w\"> <\/span>https:\/\/github.com\/dulwich\/dulwich\n<span class=\"gp\">% <\/span><span class=\"nb\">cd<\/span><span class=\"w\"> <\/span>dulwich\n<span class=\"gp\">% <\/span>ogni<span class=\"w\"> <\/span>--schroot<span class=\"o\">=<\/span>unstable-amd64-sbuild<span class=\"w\"> <\/span>dist\n<span class=\"go\">\u2026<\/span>\n<span class=\"go\">Writing dulwich-0.20.21\/setup.cfg<\/span>\n<span class=\"go\">creating dist<\/span>\n<span class=\"go\">Creating tar archive<\/span>\n<span class=\"go\">removing &#39;dulwich-0.20.21&#39; (and everything under it)<\/span>\n<span class=\"go\">Found new tarball dulwich-0.20.21.tar.gz in \/var\/run\/schroot\/mount\/unstable-amd64-sbuild-974d32d7-6f10-4e77-8622-b6a091857e85\/build\/tmpucazj7j7\/package\/dist.<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<\/div>\n<div class=\"section\" id=\"installing-ldb-from-source-resolving-dependencies-using-apt\">\n<h3>Installing ldb from source, resolving dependencies using&nbsp;apt<\/h3>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span>\n<span class=\"normal\">5<\/span>\n<span class=\"normal\">6<\/span>\n<span class=\"normal\">7<\/span>\n<span class=\"normal\">8<\/span>\n<span class=\"normal\">9<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"gp\">% <\/span>wget<span class=\"w\"> <\/span>https:\/\/download.samba.org\/pub\/ldb\/ldb-2.3.0.tar.gz\n<span class=\"gp\">% <\/span>tar<span class=\"w\"> <\/span>xvfz<span class=\"w\"> <\/span>ldb-2.3.0.tar.gz\n<span class=\"gp\">% <\/span><span class=\"nb\">cd<\/span><span class=\"w\"> <\/span>ldb-2.3.0\n<span class=\"gp\">% <\/span>ogni<span class=\"w\"> <\/span>install<span class=\"w\"> <\/span>--prefix<span class=\"o\">=<\/span>\/tmp\/ldb\n<span class=\"go\">\u2026<\/span>\n<span class=\"go\">+ install \/tmp\/ldb\/include\/ldb.h (from include\/ldb.h)<\/span>\n<span class=\"go\">\u2026<\/span>\n<span class=\"go\">Waf: Leaving directory `\/tmp\/ldb-2.3.0\/bin\/default&#39;<\/span>\n<span class=\"go\">&#39;install&#39; finished successfully (11.395s)<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<\/div>\n<div class=\"section\" id=\"running-all-tests-from-xml-libxml-lazybuilder\">\n<h3>Running all tests from <span class=\"caps\">XML<\/span>::LibXML::LazyBuilder<\/h3>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span>\n<span class=\"normal\">5<\/span>\n<span class=\"normal\">6<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"gp\">% <\/span>wget<span class=\"w\"> <\/span><span class=\"sb\">``<\/span>https:\/\/cpan.metacpan.org\/authors\/id\/T\/TO\/TORU\/XML-LibXML-LazyBuilder-0.08.tar.gz<span class=\"sb\">`<\/span>_<span class=\"w\"> <\/span>&lt;https:\/\/cpan.metacpan.org\/authors\/id\/T\/TO\/TORU\/XML-LibXML-LazyBuilder-0.08.tar.gz&gt;<span class=\"sb\">`<\/span>_\n\n<span class=\"gp\">% <\/span>tar<span class=\"w\"> <\/span>xvfz<span class=\"w\"> <\/span>XML-LibXML-LazyBuilder-0.08.tar.gz\n<span class=\"go\">Cd XML-LibXML-LazyBuilder-0.08<\/span>\n<span class=\"gp\">% <\/span>ogni<span class=\"w\"> <\/span><span class=\"nb\">test<\/span>\n<span class=\"go\">\u2026<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<\/div>\n<div class=\"section\" id=\"current-status\">\n<h3>Current&nbsp;Status<\/h3>\n<p>ognibuild is still in its early stages, but works well enough that it can\ndetect and invoke the build system for most of the upstream projects packaged\nin Debian. If there are buildsystems that it currently lacks support for or\nother issues, then I&#8217;d welcome any <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/ognibuild\/issues\/new\/choose\">bug reports<\/a>.<\/p>\n<\/div>\n<\/div>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"ognibuild"}},{"@attributes":{"term":"ogni"}},{"@attributes":{"term":"buildsystem"}}]},{"title":"The upstream\u00a0ontologist","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/upstream-ontologist.html","rel":"alternate"}},"published":"2021-04-12T00:40:00+02:00","updated":"2021-04-12T00:40:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2021-04-12:upstream-ontologist.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>The <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/upstream-ontologist\">upstream ontologist<\/a> is a project that extracts metadata about upstream projects in a consistent format. It does this with a combination of heuristics and reading ecosystem-specific metadata files, such as Python\u2019s <em>setup.py<\/em>, rust\u2019s <em>Cargo.toml<\/em> as well as e.g. scanning <span class=\"caps\">README<\/span>&nbsp;files.<\/p>\n<div class=\"section\" id=\"supported-data-sources\">\n<h2>Supported Data&nbsp;Sources<\/h2>\n<p>It will extract information from a wide variety of sources,&nbsp;including:<\/p>\n<ul class=\"simple\">\n<li>Python package metadata (<span class=\"caps\">PKG<\/span>-<span class=\"caps\">INFO<\/span>, setup.py, setup.cfg,&nbsp;pyproject.toml)<\/li>\n<li><a class=\"reference external\" href=\"https:\/\/docs.npmjs.com\/cli\/v7\/configuring-npm\/package-json\">package.json<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/getcomposer.org\/doc\/04-schema.md\">composer.json<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/pear.php.net\/manual\/en\/guide.developers.package2.dependencies.php\">package.xml<\/a><\/li>\n<li>Perl package metadata (dist.ini, <span class=\"caps\">META<\/span>.json, <span class=\"caps\">META<\/span>.yml, Makefile.<span class=\"caps\">PL<\/span>)<\/li>\n<li><a class=\"reference external\" href=\"https:\/\/perldoc.perl.org\/perlpod\">Perl <span class=\"caps\">POD<\/span>&nbsp;files<\/a><\/li>\n<li><span class=\"caps\">GNU<\/span> configure&nbsp;files<\/li>\n<li><a class=\"reference external\" href=\"https:\/\/r-pkgs.org\/description.html\">R <span class=\"caps\">DESCRIPTION<\/span>&nbsp;files<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/doc.rust-lang.org\/cargo\/reference\/manifest.html\">Rust&nbsp;Cargo.toml<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/maven.apache.org\/pom.html\">maven&nbsp;pom.xml<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/www.freedesktop.org\/software\/appstream\/docs\/chap-Metadata.html\">metainfo.xml<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/git-scm.com\/docs\/git-config\">.git\/config<\/a><\/li>\n<li><span class=\"caps\">SECURITY<\/span>.md<\/li>\n<li><a class=\"reference external\" href=\"https:\/\/github.com\/ewilderj\/doap\"><span class=\"caps\">DOAP<\/span><\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/cabal.readthedocs.io\/en\/3.4\/cabal-package.html\">Haskell cabal&nbsp;files<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/guides.rubygems.org\/specification-reference\/\">Ruby gemspec&nbsp;files<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/golang.org\/doc\/modules\/gomod-ref\">go.mod<\/a><\/li>\n<li><span class=\"caps\">README<\/span>{,.rst,.md}&nbsp;files<\/li>\n<li>Debian packaging metadata (debian\/watch, debian\/control, debian\/rules, debian\/get-orig-source.sh, debian\/copyright,&nbsp;debian\/patches)<\/li>\n<\/ul>\n<\/div>\n<div class=\"section\" id=\"supported-fields\">\n<h2>Supported&nbsp;Fields<\/h2>\n<p>Fields that it currently provides&nbsp;include:<\/p>\n<ul class=\"simple\">\n<li><strong>Homepage<\/strong>: homepage <span class=\"caps\">URL<\/span><\/li>\n<li><strong>Name<\/strong>: name of the upstream&nbsp;project<\/li>\n<li><strong>Contact<\/strong>: contact address of some sort of the upstream (e-mail, mailing list <span class=\"caps\">URL<\/span>)<\/li>\n<li><strong>Repository<\/strong>: <span class=\"caps\">VCS<\/span> <span class=\"caps\">URL<\/span><\/li>\n<li><strong>Repository-Browse<\/strong>: Web <span class=\"caps\">URL<\/span> for viewing the <span class=\"caps\">VCS<\/span><\/li>\n<li><strong>Bug-Database<\/strong>: Bug database <span class=\"caps\">URL<\/span> (for web viewing,&nbsp;generally)<\/li>\n<li><strong>Bug-Submit<\/strong>: <span class=\"caps\">URL<\/span> to use to submit new bugs (either on the web or an e-mail&nbsp;address)<\/li>\n<li><strong>Screenshots<\/strong>: List of URLs with&nbsp;screenshots<\/li>\n<li><strong>Archive<\/strong>: Archive used - e.g.&nbsp;SourceForge<\/li>\n<li><strong>Security-Contact<\/strong>: e-mail or <span class=\"caps\">URL<\/span> with instructions for reporting security&nbsp;issues<\/li>\n<li><strong>Documentation<\/strong>: Link to documentation on the&nbsp;web:<\/li>\n<li><strong>Wiki<\/strong>: Wiki <span class=\"caps\">URL<\/span><\/li>\n<li><strong>Summary<\/strong>: one-line description of the&nbsp;project<\/li>\n<li><strong>Description<\/strong>: longer description of the&nbsp;project<\/li>\n<li><strong>License<\/strong>: Single line license description (e.g. &#8220;<span class=\"caps\">GPL<\/span> 2.0&#8221;) as declared in the metadata<a class=\"footnote-reference\" href=\"#f1\" id=\"footnote-reference-1\">[1]<\/a><\/li>\n<li><strong>Copyright<\/strong>: List of copyright&nbsp;holders<\/li>\n<li><strong>Version<\/strong>: Current upstream&nbsp;version<\/li>\n<li><strong>Security-<span class=\"caps\">MD<\/span><\/strong>: <span class=\"caps\">URL<\/span> to markdown file with security&nbsp;policy<\/li>\n<\/ul>\n<p>All data fields have a \u201ccertainty\u201d associated with them (\u201ccertain\u201d, \u201cconfident\u201d, \u201clikely\u201d or \u201cpossible\u201d), which gets set depending on how the data was derived or where it was found. If multiple possible values were found for a specific field, then the value with the highest certainty is&nbsp;taken.<\/p>\n<\/div>\n<div class=\"section\" id=\"interface\">\n<h2>Interface<\/h2>\n<p>The ontologist provides a high-level Python <span class=\"caps\">API<\/span> as well as two command-line tools that can write output in two different&nbsp;formats:<\/p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https:\/\/manpages.debian.org\/testing\/python3-upstream-ontologist\/guess-upstream-metadata.1.en.html\">guess-upstream-metadata<\/a> writes <a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/UpstreamMetadata\"><span class=\"caps\">DEP<\/span>-12-like<\/a> <span class=\"caps\">YAML<\/span>&nbsp;output<\/li>\n<li><a class=\"reference external\" href=\"https:\/\/manpages.debian.org\/testing\/python3-upstream-ontologist\/autodoap.1.en.html\">autodoap<\/a>  writes <a class=\"reference external\" href=\"https:\/\/github.com\/ewilderj\/doap\"><span class=\"caps\">DOAP<\/span><\/a>&nbsp;files<\/li>\n<\/ul>\n<p>For example, running <em>guess-upstream-metadata<\/em> on <a class=\"reference external\" href=\"https:\/\/github.com\/dulwich\/dulwich\">dulwich<\/a>:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> % <\/span>guess-upstream-metadata\n<span class=\"go\"> &lt;string&gt;:2: (INFO\/1) Duplicate implicit target name: &quot;contributing&quot;.<\/span>\n<span class=\"go\"> Name: dulwich<\/span>\n<span class=\"go\"> Repository: https:\/\/www.dulwich.io\/code\/<\/span>\n<span class=\"go\"> X-Security-MD: https:\/\/github.com\/dulwich\/dulwich\/tree\/HEAD\/SECURITY.md<\/span>\n<span class=\"go\"> X-Version: 0.20.21<\/span>\n<span class=\"go\"> Bug-Database: https:\/\/github.com\/dulwich\/dulwich\/issues<\/span>\n<span class=\"go\"> X-Summary: Python Git Library<\/span>\n<span class=\"go\"> X-Description: |<\/span>\n<span class=\"go\">   This is the Dulwich project.<\/span>\n<span class=\"go\">   It aims to provide an interface to git repos (both local and remote) that<\/span>\n<span class=\"go\">   doesn&#39;t call out to git directly but instead uses pure Python.<\/span>\n<span class=\"go\"> X-License: Apache License, version 2 or GNU General Public License, version 2 or later.<\/span>\n<span class=\"go\"> Bug-Submit: https:\/\/github.com\/dulwich\/dulwich\/issues\/new<\/span>\n<\/pre><\/div>\n<\/div>\n<div class=\"section\" id=\"lintian-brush-1\">\n<h2>Lintian-Brush<\/h2>\n<p><a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> can update <a class=\"reference external\" href=\"https:\/\/dep-team.pages.debian.net\/deps\/dep12\/\"><span class=\"caps\">DEP<\/span>-12-style debian\/upstream\/metadata files<\/a> that hold information about the upstream project that is packaged as well as the <em>Homepage<\/em> in the debian\/control file based on information provided by the upstream ontologist. By default, it only imports data with the highest certainty - you can override this by specifying the &#8212;uncertain command-line&nbsp;flag.<\/p>\n<table class=\"docutils footnote\" frame=\"void\" id=\"f1\" rules=\"none\">\n<colgroup><col class=\"label\" \/><col \/><\/colgroup>\n<tbody valign=\"top\">\n<tr><td class=\"label\"><a class=\"fn-backref\" href=\"#footnote-reference-1\">[1]<\/a><\/td><td>Obviously this won&#8217;t be able to describe the full licensing situation for many projects. Projects like <a class=\"reference external\" href=\"https:\/\/github.com\/nexB\/scancode-toolkit\">scancode-toolkit<\/a> are more appropriate for that.<\/td><\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"buildlog"}},{"@attributes":{"term":"doap"}},{"@attributes":{"term":"upstream"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Automatic Fixing of Debian Build\u00a0Dependencies","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/deb-fix-build.html","rel":"alternate"}},"published":"2021-04-06T23:46:16+02:00","updated":"2021-04-06T23:46:16+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2021-04-06:deb-fix-build.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>In my <a class=\"reference external\" href=\"\/buildlog-consultant.html\">last blogpost<\/a>, I introduced the <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/buildlog-consultant\">buildlog\nconsultant<\/a> - a tool that can\nidentify many reasons why a Debian build&nbsp;failed.<\/p>\n<p>For example, here\u2019s a fragment of a build log where the Build-Depends lack\n<em>python3-setuptools<\/em>:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">849<\/span>\n<span class=\"normal\">850<\/span>\n<span class=\"normal\">851<\/span>\n<span class=\"normal\">852<\/span>\n<span class=\"normal\">853<\/span>\n<span class=\"normal\">854<\/span>\n<span class=\"normal\">855<\/span>\n<span class=\"normal\">856<\/span>\n<span class=\"normal\">857<\/span>\n<span class=\"normal\">858<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"go\"> dpkg-buildpackage: info: host architecture amd64<\/span>\n<span class=\"go\">  fakeroot debian\/rules clean<\/span>\n<span class=\"go\"> dh clean --with python3,sphinxdoc --buildsystem=pybuild<\/span>\n<span class=\"go\">    dh_auto_clean -O--buildsystem=pybuild<\/span>\n<span class=\"go\"> I: pybuild base:232: python3.9 setup.py clean<\/span>\n<span class=\"go\"> Traceback (most recent call last):<\/span>\n<span class=\"go\">   File &quot;\/&lt;&lt;PKGBUILDDIR&gt;&gt;\/setup.py&quot;, line 2, in &lt;module&gt;<\/span>\n<span class=\"go\">     from setuptools import setup<\/span>\n<span class=\"hll\"><span class=\"go\"> ModuleNotFoundError: No module named &#39;setuptools&#39;<\/span>\n<\/span><span class=\"go\"> E: pybuild pybuild:353: clean: plugin distutils failed with: exit code=1: python3.9 setup.py clean<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>The buildlog consultant can identify the line in bold as being key, and interprets&nbsp;it:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> % <\/span>analyse-sbuild-log<span class=\"w\"> <\/span>--json<span class=\"w\"> <\/span>~\/build.log\n\n<span class=\"go\"> {<\/span>\n<span class=\"go\">    &quot;stage&quot;: &quot;build&quot;,<\/span>\n<span class=\"go\">    &quot;section&quot;: &quot;Build&quot;,<\/span>\n<span class=\"go\">    &quot;lineno&quot;: 857,<\/span>\n<span class=\"go\">    &quot;kind&quot;: &quot;missing-python-module&quot;,<\/span>\n<span class=\"go\">    &quot;details&quot;: {&quot;module&quot;: &quot;setuptools&quot;, &quot;python_version&quot;: 3, &quot;minimum_version&quot;: null}<\/span>\n<span class=\"go\"> }<\/span>\n<\/pre><\/div>\n<div class=\"section\" id=\"automatically-acting-on-buildlog-problems\">\n<h2>Automatically acting on buildlog&nbsp;problems<\/h2>\n<p>A common reason why Debian builds fail is missing dependencies or incorrect versions of dependencies declared in the package build&nbsp;depends.<\/p>\n<p>Based on the output of the buildlog consultant, it is possible in many cases to determine what dependency needs to be added to <em>Build-Depends<\/em>. In the example given above, we can use apt-file to look for the package that contains the path <em>\/usr\/lib\/python3\/dist-packages\/setuptools\/__init__.py<\/em> - and voila, we find&nbsp;python3-setuptools:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> % <\/span>apt-file<span class=\"w\"> <\/span>search<span class=\"w\"> <\/span>\/usr\/lib\/python3\/dist-packages\/setuptools\/__init__.py\n<span class=\"go\"> python3-setuptools: \/usr\/lib\/python3\/dist-packages\/setuptools\/__init__.py<\/span>\n<\/pre><\/div>\n<p>The <em>deb-fix-build<\/em> command automates these&nbsp;steps:<\/p>\n<ol class=\"arabic simple\">\n<li>It builds the package using sbuild; if the package successfully builds then it just exits&nbsp;successfully<\/li>\n<li>It tries to identify the problem by looking through the build log; if it can&#8217;t or if it&#8217;s a problem it has seen before (but apparently failed to resolve), then it exits with a non-zero exit&nbsp;code<\/li>\n<li>It tries to find a dependency that can address the&nbsp;problem<\/li>\n<li>It updates <em>Build-Depends<\/em> in <em>debian\/control<\/em> or <em>Depends<\/em> in <em>debian\/tests\/control<\/em><\/li>\n<li>Go to step&nbsp;1<\/li>\n<\/ol>\n<p>This takes away the tedious manual process of building a package, discovering that a  dependency is missing, updating Build-Depends and trying&nbsp;again.<\/p>\n<p>For example, when I ran deb-fix-build while packaging <a class=\"reference external\" href=\"https:\/\/github.com\/nexb\/saneyaml\">saneyaml<\/a>, the output looks something like&nbsp;this:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> % <\/span>deb-fix-build\n<span class=\"go\"> Using output directory \/tmp\/tmpyz0nkgqq<\/span>\n<span class=\"go\"> Using sbuild chroot unstable-amd64-sbuild<\/span>\n<span class=\"go\"> Using fixers: \u2026<\/span>\n<span class=\"go\"> Building debian packages, running &#39;sbuild --no-clean-source -A -s -v&#39;.<\/span>\n<span class=\"go\"> Attempting to use fixer upstream requirement fixer(apt) to address MissingPythonDistribution(&#39;setuptools_scm&#39;, python_version=3, minimum_version=&#39;4&#39;)<\/span>\n<span class=\"go\"> Using apt-file to search apt contents<\/span>\n<span class=\"go\"> Adding build dependency: python3-setuptools-scm (&gt;= 4)<\/span>\n<span class=\"go\"> Building debian packages, running &#39;sbuild --no-clean-source -A -s -v&#39;.<\/span>\n<span class=\"go\"> Attempting to use fixer upstream requirement fixer(apt) to address MissingPythonDistribution(&#39;toml&#39;, python_version=3, minimum_version=None)<\/span>\n<span class=\"go\"> Adding build dependency: python3-toml<\/span>\n<span class=\"go\"> Building debian packages, running &#39;sbuild --no-clean-source -A -s -v&#39;.<\/span>\n<span class=\"go\"> Built 0.5.2-1- changes files at [\u2018saneyaml_0.5.2-1_amd64.changes\u2019].<\/span>\n<\/pre><\/div>\n<p>And in our Git repository, we see these changes as&nbsp;well:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\">% <\/span>git<span class=\"w\"> <\/span>log<span class=\"w\"> <\/span>-p\n<span class=\"go\"> commit 5a1715f4c7273b042818fc75702f2284034c7277 (HEAD -&gt; master)<\/span>\n<span class=\"go\"> Author: Jelmer Vernoo\u0133 &lt;jelmer@jelmer.uk&gt;<\/span>\n<span class=\"go\"> Date:   Sun Apr 4 02:35:56 2021 +0100<\/span>\n\n<span class=\"go\">     Add missing build dependency on python3-toml.<\/span>\n\n<span class=\"go\"> diff --git a\/debian\/control b\/debian\/control<\/span>\n<span class=\"go\"> index 5b854dc..3b27b73 100644<\/span>\n<span class=\"go\"> --- a\/debian\/control<\/span>\n<span class=\"go\"> +++ b\/debian\/control<\/span>\n<span class=\"go\"> @@ -1,6 +1,6 @@<\/span>\n<span class=\"go\">  Rules-Requires-Root: no<\/span>\n<span class=\"go\">  Standards-Version: 4.5.1<\/span>\n<span class=\"go\"> -Build-Depends: debhelper-compat (= 12), dh-sequence-python3, python3-all, python3-setuptools (&gt;= 50), python3-wheel, python3-setuptools-scm (&gt;= 4)<\/span>\n<span class=\"go\"> +Build-Depends: debhelper-compat (= 12), dh-sequence-python3, python3-all, python3-setuptools (&gt;= 50), python3-wheel, python3-setuptools-scm (&gt;= 4), python3-toml<\/span>\n<span class=\"go\">  Testsuite: autopkgtest-pkg-python<\/span>\n<span class=\"go\">  Source: python-saneyaml<\/span>\n<span class=\"go\">  Priority: optional<\/span>\n\n<span class=\"go\"> commit f03047da80fcd8468ee231fbc4cf8488d7a0acd1<\/span>\n<span class=\"go\"> Author: Jelmer Vernoo\u0133 &lt;jelmer@jelmer.uk&gt;<\/span>\n<span class=\"go\"> Date:   Sun Apr 4 02:35:34 2021 +0100<\/span>\n\n<span class=\"go\">     Add missing build dependency on python3-setuptools-scm (&gt;= 4).<\/span>\n\n<span class=\"go\"> diff --git a\/debian\/control b\/debian\/control<\/span>\n<span class=\"go\"> index a476cc2..5b854dc 100644<\/span>\n<span class=\"go\"> --- a\/debian\/control<\/span>\n<span class=\"go\"> +++ b\/debian\/control<\/span>\n<span class=\"go\"> @@ -1,6 +1,6 @@<\/span>\n<span class=\"go\">  Rules-Requires-Root: no<\/span>\n<span class=\"go\">  Standards-Version: 4.5.1<\/span>\n<span class=\"go\"> -Build-Depends: debhelper-compat (= 12), dh-sequence-python3, python3-all, python3-setuptools (&gt;= 50), python3-wheel<\/span>\n<span class=\"go\"> +Build-Depends: debhelper-compat (= 12), dh-sequence-python3, python3-all, python3-setuptools (&gt;= 50), python3-wheel, python3-setuptools-scm (&gt;= 4)<\/span>\n<span class=\"go\">  Testsuite: autopkgtest-pkg-python<\/span>\n<span class=\"go\">  Source: python-saneyaml<\/span>\n<span class=\"go\">  Priority: optional<\/span>\n<\/pre><\/div>\n<\/div>\n<div class=\"section\" id=\"using-deb-fix-build\">\n<h2>Using&nbsp;deb-fix-build<\/h2>\n<p>You can run <em>deb-fix-build<\/em> by installing the <a class=\"reference external\" href=\"https:\/\/packages.debian.org\/ognibuild\">ognibuild package<\/a> from unstable. The only requirements\nfor using it are&nbsp;that:<\/p>\n<ul class=\"simple\">\n<li>The package is maintained in&nbsp;Git<\/li>\n<li>A sbuild schroot is available for&nbsp;use<\/li>\n<\/ul>\n<\/div>\n<div class=\"section\" id=\"caveats\">\n<h2>Caveats<\/h2>\n<p>deb-fix-build is fairly easy to understand, and if it doesn&#8217;t work then you&#8217;re no worse off than you were without it - you&#8217;ll have to add your own&nbsp;Build-Depends.<\/p>\n<p>That said, there are a couple of things to keep in&nbsp;mind:<\/p>\n<ul class=\"simple\">\n<li>At the moment, it doesn&#8217;t distinguish between general, Arch or Indep&nbsp;Build-Depends.<\/li>\n<li>It can only add dependencies for things that are actually in the&nbsp;archive<\/li>\n<li>Sometimes there are multiple packages that can provide a file, command or python package - it tries to find the right one with heuristics but doesn&#8217;t always get it&nbsp;right<\/li>\n<\/ul>\n<\/div>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"The Buildlog\u00a0Consultant","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/buildlog-consultant.html","rel":"alternate"}},"published":"2021-04-05T16:00:00+02:00","updated":"2021-04-05T16:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2021-04-05:buildlog-consultant.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<div class=\"section\" id=\"reading-build-logs\">\n<h2>Reading build&nbsp;logs<\/h2>\n<p>Build logs for Debian packages can be quite long and difficult\nfor a human to read. Anybody who has looked at these logs\ntrying to figure out why a build failed will have spent\ntime scrolling through them and skimming for certain phrases\n(lines starting with \u201cerror:\u201d for example). In many cases,\nyou can spot the problem in the last 10 or 20 lines of\noutput \u2013 but it\u2019s also quite common that the error is somewhere\nat the beginning of many pages of error&nbsp;output.<\/p>\n<\/div>\n<div class=\"section\" id=\"the-buildlog-consultant-1\">\n<h2>The buildlog&nbsp;consultant<\/h2>\n<p>The <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/buildlog-consultant\">buildlog consultant project<\/a> attempts to aid in this\nprocess by parsing sbuild and non-Debian (e.g. the output\nof \u201cmake\u201d) build logs and trying to identify the key line\nthat explains why a build failed. It can then either display\nthis specific line, or a fragment of the log around surrounding\nthe key&nbsp;line.<\/p>\n<\/div>\n<div class=\"section\" id=\"classification\">\n<h2>Classification<\/h2>\n<p>In addition to finding the key line explaining the failure,\nit can also classify and parse the error in many cases\nand return a result code and some&nbsp;metadata.<\/p>\n<p>For example, in a <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/cupboard\/pkg\/gnss-sdr-upstream\/5980a87d-b1a4-4d1d-9660-acd385ee5186\/\">failed build<\/a>\nof <a class=\"reference external\" href=\"https:\/\/gnss-sdr.org\/\">gnss-sdr<\/a> that has produced <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/cupboard\/pkg\/gnss-sdr-upstream\/5980a87d-b1a4-4d1d-9660-acd385ee5186\/build.log\">2119 lines of output<\/a>,\nthe reason for the failure is that\nlog4cpp is missing \u2013 which is on line&nbsp;641:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">634<\/span>\n<span class=\"normal\">635<\/span>\n<span class=\"normal\">636<\/span>\n<span class=\"normal\">637<\/span>\n<span class=\"normal\">638<\/span>\n<span class=\"normal\">639<\/span>\n<span class=\"normal\">640<\/span>\n<span class=\"normal\">641<\/span>\n<span class=\"normal\">642<\/span>\n<span class=\"normal\">643<\/span>\n<span class=\"normal\">644<\/span>\n<span class=\"normal\">645<\/span>\n<span class=\"normal\">646<\/span>\n<span class=\"normal\">647<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"go\"> -- Required GNU Radio Component: ANALOG missing!<\/span>\n<span class=\"go\"> -- Could NOT find GNURADIO (missing: GNURADIO_RUNTIME_FOUND)<\/span>\n<span class=\"go\"> -- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)<\/span>\n<span class=\"go\"> -- Could NOT find LOG4CPP (missing: LOG4CPP_INCLUDE_DIRS<\/span>\n<span class=\"go\"> LOG4CPP_LIBRARIES)<\/span>\n\n<span class=\"go\"> CMake Error at CMakeLists.txt:593 (message):<\/span>\n<span class=\"go\">   *** Log4cpp is required to build gnss-sdr<\/span>\n\n<span class=\"go\"> -- Configuring incomplete, errors occurred!<\/span>\n<span class=\"go\"> See also &quot;\/&lt;&lt;PKGBUILDDIR&gt;&gt;\/obj-x86_64-linux-gnu\/CMakeFiles\/<\/span>\n<span class=\"go\"> CMakeOutput.log&quot;.<\/span>\n<span class=\"go\"> See also &quot;\/&lt;&lt;PKGBUILDDIR&gt;&gt;\/obj-x86_64-linux-gnu\/CMakeFiles\/<\/span>\n<span class=\"go\"> CMakeError.log&quot;.<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>In this case, the buildlog consultant can both figure out\nline was problematic and what the problem&nbsp;was:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> % <\/span>analyse-sbuild-log<span class=\"w\"> <\/span>build.log\n<span class=\"go\"> Failed stage: build<\/span>\n<span class=\"go\"> Section: build<\/span>\n<span class=\"go\"> Failed line: 641:<\/span>\n<span class=\"go\">   *** Log4cpp is required to build gnss-sdr<\/span>\n<span class=\"go\"> Error: Missing dependency: Log4cpp<\/span>\n<\/pre><\/div>\n<p>Or, if you&#8217;d like to do something else with the output, use <span class=\"caps\">JSON<\/span>&nbsp;output:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> % <\/span>analyse-sbuild-log<span class=\"w\"> <\/span>--json<span class=\"w\"> <\/span>build.log\n<span class=\"go\"> {&quot;stage&quot;: &quot;build&quot;, &quot;section&quot;: &quot;Build&quot;, &quot;lineno&quot;: 641, &quot;kind&quot;: &quot;missing-dependency&quot;, &quot;details&quot;: {&quot;name&quot;: &quot;Log4cpp&quot;&quot;}}<\/span>\n<\/pre><\/div>\n<\/div>\n<div class=\"section\" id=\"how-it-works\">\n<h2>How it&nbsp;works<\/h2>\n<p>The consultant does some structured parsing (most notably\nit can parse the sections from a sbuild log), but otherwise\nis a large set of carefully crafted regular expressions\nand heuristics. It doesn\u2019t always find the problem, but\nhas proven to be fairly accurate. It is constantly improved\nas part of the  <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/\">Debian Janitor project<\/a>, and\nthat exposes it to a wide variety of different&nbsp;errors.<\/p>\n<p>You can see the classification and error detection in action\non the  <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/cupboard\/result-codes\/\">result codes<\/a>\npage of the&nbsp;Janitor.<\/p>\n<\/div>\n<div class=\"section\" id=\"using-the-buildlog-consultant\">\n<h2>Using the buildlog&nbsp;consultant<\/h2>\n<p>You can get the buildlog consultant from either pip or Debian\nunstable (package:  <a class=\"reference external\" href=\"https:\/\/packages.debian.org\/python3-buildlog-consultant\">python3-buildlog-consultant<\/a>&nbsp;).<\/p>\n<p>The buildlog consultant comes with two scripts \u2013 <em>analyse-build-log<\/em>  and <em>analyse-sbuild-log<\/em>,  for analysing\nbuild logs and sbuild logs&nbsp;respectively.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"buildlog"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Debian Janitor: Hosters used by Debian\u00a0packages","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-update-8.html","rel":"alternate"}},"published":"2020-10-24T08:00:00+02:00","updated":"2020-10-24T08:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133, Perry Lorrier"},"id":"tag:www.jelmer.uk,2020-10-24:janitor-update-8.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>The Janitor knows how to talk to different hosting platforms.\nFor each hosting platform, it needs to support the platform-\nspecific <span class=\"caps\">API<\/span> for creating and managing merge proposals.\nFor each hoster it also needs to have  <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/credentials\">credentials<\/a>.<\/p>\n<p>At the moment, it supports the <a class=\"reference external\" href=\"https:\/\/developer.github.com\/v3\/\">GitHub <span class=\"caps\">API<\/span><\/a>,\n<a class=\"reference external\" href=\"https:\/\/launchpad.net\/+apidoc\/devel.html\">Launchpad <span class=\"caps\">API<\/span><\/a> and <a class=\"reference external\" href=\"https:\/\/docs.gitlab.com\/ee\/api\/\">GitLab <span class=\"caps\">API<\/span><\/a>. Both GitHub and Launchpad have only a\nsingle instance; the GitLab instances it supports are  <a class=\"reference external\" href=\"https:\/\/gitlab.com\/\">gitlab.com<\/a> and <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/\">salsa.debian.org<\/a>.<\/p>\n<p>This provides coverage for the vast majority of Debian packages\nthat can be accessed using Git. More than 75% of all packages\nare available on salsa - although in some cases, the Vcs-Git\nheader has not yet been&nbsp;updated.<\/p>\n<p>Of the other 25%, the majority either does not declare where\nit is hosted using a Vcs-* header (10.5%), or have not\nyet migrated from alioth to another hosting platform\n(9.7%). A further 2.3% are hosted somewhere on\n<a class=\"reference external\" href=\"https:\/\/www.github.com\/\">GitHub<\/a>  (2%),\n<a class=\"reference external\" href=\"https:\/\/launchpad.net\/\">Launchpad<\/a> (0.18%) or\n<a class=\"reference external\" href=\"https:\/\/gitlab.com\/\">GitLab.com<\/a> (0.15%), in many cases\nin the same repository as the upstream&nbsp;code.<\/p>\n<p>The remaining 1.6% are hosted on many other hosts, primarily\npeople\u2019s personal servers (which usually don\u2019t have an\n<span class=\"caps\">API<\/span> for creating pull&nbsp;requests).<\/p>\n<img alt=\"Packages per hoster\" src=\"\/images\/janitor-packages-per-hoster.png\" \/>\n<div class=\"section\" id=\"outdated-vcs-headers\">\n<h2>Outdated Vcs-*&nbsp;headers<\/h2>\n<p>It is possible that the 20% of packages that do not have\na Vcs-* header or have a Vcs header that say there on\nalioth are actually hosted elsewhere. However, it is hard\nto know where they are until a version with an updated\nVcs-Git header is&nbsp;uploaded.<\/p>\n<p>The Janitor primarily relies on\n<a class=\"reference external\" href=\"https:\/\/qa.debian.org\/cgi-bin\/vcswatch\">vcswatch<\/a>  to find the correct\nlocations of repositories. vcswatch looks at Vcs-* headers\nbut has its own heuristics as well. For about 2,000 packages\n(6%) that still have Vcs-* headers that point to alioth,\nvcswatch successfully finds their new home on&nbsp;salsa.<\/p>\n<\/div>\n<div class=\"section\" id=\"merge-proposals-by-hoster\">\n<h2>Merge Proposals by&nbsp;Hoster<\/h2>\n<p>These proportions are also visible in the number of pull\nrequests created by the Janitor on various hosters. The\nvast majority so far has been created on&nbsp;Salsa.<\/p>\n<table class=\"docutils\" border=\"1\">\n<colgroup>\n <col width=\"26%\" \/>\n <col width=\"18%\" \/>\n <col width=\"35%\" \/>\n <col width=\"21%\" \/>\n<\/colgroup>\n<thead>\n<tr>\n <td class=\"head\"><b>Hoster<\/b><\/td>\n <td class=\"head\"><b>Open<\/b><\/td>\n <td class=\"head\"><b>Merged <span class=\"amp\">&amp;<\/span> Applied<\/b><\/td>\n <td class=\"head\"><b>Closed<\/b><\/td>\n<\/tr>\n<\/thead>\n<tbody>\n <tr><td>github.com<\/td><td align=\"right\">92<\/td><td align=\"right\">168<\/td><td align=\"right\">5<\/td><\/tr><\/tr>\n <tr><td>gitlab.com<\/td><td align=\"right\">12<\/td><td align=\"right\">3<\/td><td align=\"right\">0<\/td><\/tr>\n <tr><td>code.launchpad.net<\/td><td align=\"right\">24<\/td><td align=\"right\">51<\/td><td align=\"right\">1<\/td><\/tr>\n <tr><td>salsa.debian.org<\/td><td align=\"right\">1,360<\/td><td align=\"right\">5,657<\/td><td align=\"right\">126<\/td><\/tr>\n<\/tbody>\n<\/table><img alt=\"Merge Proposal statistics\" src=\"\/images\/janitor-merge-proposal-stats.png\" \/>\n<p>In this graph, \u201cOpen\u201d means that the pull request has been\ncreated but likely nobody has looked at it yet. Merged\nmeans that the pull request has been marked as merged on\nthe hoster, and applied means that the changes have ended\nup in the packaging branch but via a different route (e.g. cherry-picked or\nmanually applied). Closed means that the pull request was closed without the\nchanges being&nbsp;incorporated.<\/p>\n<p>Note that this excludes ~5,600 direct pushes, all of which were to salsa-hosted&nbsp;repositories.<\/p>\n<p>See&nbsp;also:<\/p>\n<ul class=\"simple\">\n<li>Historical graphs on  <a class=\"reference external\" href=\"http:\/\/trends.debian.net\">trends.debian.net<\/a> with number of packages  <a class=\"reference external\" href=\"https:\/\/trends.debian.net\/#version-control-system\">per <span class=\"caps\">VCS<\/span><\/a> and <a class=\"reference external\" href=\"https:\/\/trends.debian.net\/#vcs-hosting\">per hoster<\/a> (purely based on Vcs-* headers in the archive, with no heuristics&nbsp;applied)<\/li>\n<li>Zack\u2019s table of  <a class=\"reference external\" href=\"https:\/\/upsilon.cc\/~zack\/stuff\/vcs-usage\/\">number of Vcs-* header by system<\/a> (Git, Svn,&nbsp;etc)<\/li>\n<li>current <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/cupboard\/stats\">Janitor merge proposal&nbsp;statistics<\/a><\/li>\n<\/ul>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Debian Janitor: How to Contribute Lintian-Brush\u00a0Fixers","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-update-7.html","rel":"alternate"}},"published":"2020-10-15T20:00:00+02:00","updated":"2020-10-15T20:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2020-10-15:janitor-update-7.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>lintian-brush can currently fix about 150 different issues that lintian can\nreport, but that&#8217;s still a small fraction of the more than thousand different\ntypes of issue that lintian can&nbsp;detect.<\/p>\n<p>If you&#8217;re interested in contributing a fixer script to <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a>, there is now <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\/-\/blob\/master\/doc\/fixer-writing-guide.rst\">a guide<\/a>\nthat describes all steps of the&nbsp;process:<\/p>\n<ol class=\"arabic simple\">\n<li>how to identify lintian tags that are good candidates for automated&nbsp;fixing<\/li>\n<li>creating test&nbsp;cases<\/li>\n<li>writing the actual&nbsp;fixer<\/li>\n<\/ol>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Debian Janitor: Expanding Into Improving\u00a0Multi-Arch","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-update-6.html","rel":"alternate"}},"published":"2020-09-19T08:00:00+02:00","updated":"2020-09-19T08:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133, Perry Lorrier"},"id":"tag:www.jelmer.uk,2020-09-19:janitor-update-6.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>As of dpkg 1.16.2 and apt 0.8.13, Debian has full support\nfor  <a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/Multiarch\">multi-arch<\/a>. To quote from the multi-arch implementation&nbsp;page:<\/p>\n<blockquote>\nMultiarch lets you install library packages from multiple architectures on\nthe same machine. This is useful in various ways, but the most common is\ninstalling both 64 and 32- bit software on the same machine and having\ndependencies correctly resolved automatically. In general you can have\nlibraries of more than one architecture installed together and applications\nfrom one architecture or another installed as alternatives.<\/blockquote>\n<p>The  <a class=\"reference external\" href=\"https:\/\/wiki.ubuntu.com\/MultiarchSpec\">Multi-Arch specification<\/a> describes a new Multi-Arch header which can be used\nto indicate how to resolve cross-architecture&nbsp;dependencies.<\/p>\n<p>The existing  <a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/MultiArch\/Hints\">Debian Multi-Arch hinter<\/a> is a version of  <a class=\"reference external\" href=\"dedup.debian.net\">dedup.debian.net<\/a> that compares binary\npackages between architectures and suggests fixes to resolve\nmulti-arch problems. It provides hints as to what Multi-\nArch fields can be set, allowing the packages to be safely\ninstalled in a Multi-Arch world. The full list of almost\n10,000 hints generated by the hinter is available at  <a class=\"reference external\" href=\"https:\/\/dedup.debian.net\/static\/multiarch-hints.yaml\">https:\/\/dedup.debian.net\/static\/multiarch-hints.yaml<\/a>.<\/p>\n<p>Recent versions of lintian-brush now include a command called  <a class=\"reference external\" href=\"https:\/\/manpages.debian.org\/testing\/lintian-brush\/apply-multiarch-hints.1.en.html\">apply-multiarch-hints<\/a>\nthat downloads and locally caches the hints and can apply\nthem to a package maintained in Git. For example, to apply\nmulti-arch hints to  <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/js-team\/autosize.js\">autosize.js<\/a>:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> $ <\/span>debcheckout<span class=\"w\"> <\/span>autosize.js\n<span class=\"go\"> declared git repository at https:\/\/salsa.debian.org\/js-team\/autosize.js.git<\/span>\n<span class=\"go\"> git clone https:\/\/salsa.debian.org\/js-team\/autosize.js.git autosize.js ...<\/span>\n<span class=\"go\"> Cloning into &#39;autosize.js&#39;...<\/span>\n<span class=\"go\"> [...]<\/span>\n<span class=\"gp\"> $ <\/span><span class=\"nb\">cd<\/span><span class=\"w\"> <\/span>autosize.js\n<span class=\"gp\"> $ <\/span>apply-multiarch-hints\n<span class=\"go\"> Downloading new version of multi-arch hints.<\/span>\n<span class=\"go\"> libjs-autosize: Add Multi-Arch: foreign.<\/span>\n<span class=\"go\"> node-autosize: Add Multi-Arch: foreign.<\/span>\n<span class=\"gp\"> $ <\/span>git<span class=\"w\"> <\/span>log<span class=\"w\"> <\/span>-p\n<span class=\"go\"> commit 3f8d1db5af4a87e6ebb08f46ddf79f6adf4e95ae (HEAD -&gt; master)<\/span>\n<span class=\"go\"> Author: Jelmer Vernoo\u0133 &lt;jelmer@debian.org&gt;<\/span>\n<span class=\"go\"> Date:   Fri Sep 18 23:37:14 2020 +0000<\/span>\n\n<span class=\"go\">     Apply multi-arch hints.<\/span>\n<span class=\"go\">     + libjs-autosize, node-autosize: Add Multi-Arch: foreign.<\/span>\n\n<span class=\"go\">     Changes-By: apply-multiarch-hints<\/span>\n\n<span class=\"go\"> diff --git a\/debian\/changelog b\/debian\/changelog<\/span>\n<span class=\"go\"> index e7fa120..09af4a7 100644<\/span>\n<span class=\"go\"> --- a\/debian\/changelog<\/span>\n<span class=\"go\"> +++ b\/debian\/changelog<\/span>\n<span class=\"go\"> @@ -1,3 +1,10 @@<\/span>\n<span class=\"go\"> +autosize.js (4.0.2~dfsg1-5) UNRELEASED; urgency=medium<\/span>\n<span class=\"go\"> +<\/span>\n<span class=\"go\"> +  * Apply multi-arch hints.<\/span>\n<span class=\"go\"> +    + libjs-autosize, node-autosize: Add Multi-Arch: foreign.<\/span>\n<span class=\"go\"> +<\/span>\n<span class=\"go\"> + -- Jelmer Vernoo\u0133 &lt;jelmer@debian.org&gt;  Fri, 18 Sep 2020 23:37:14 -0000<\/span>\n<span class=\"go\"> +<\/span>\n<span class=\"go\">  autosize.js (4.0.2~dfsg1-4) unstable; urgency=medium<\/span>\n\n<span class=\"go\">    * Team upload<\/span>\n<span class=\"go\"> diff --git a\/debian\/control b\/debian\/control<\/span>\n<span class=\"go\"> index 01ca968..fbba1ae 100644<\/span>\n<span class=\"go\"> --- a\/debian\/control<\/span>\n<span class=\"go\"> +++ b\/debian\/control<\/span>\n<span class=\"go\"> @@ -20,6 +20,7 @@ Architecture: all<\/span>\n<span class=\"go\">  Depends: ${misc:Depends}<\/span>\n<span class=\"go\">  Recommends: javascript-common<\/span>\n<span class=\"go\">  Breaks: ruby-rails-assets-autosize (&lt;&lt; 4.0)<\/span>\n<span class=\"go\"> +Multi-Arch: foreign<\/span>\n<span class=\"go\">  Description: script to automatically adjust textarea height to fit text - NodeJS<\/span>\n<span class=\"go\">   Autosize is a small, stand-alone script to automatically adjust textarea<\/span>\n<span class=\"go\">   height to fit text. The autosize function accepts a single textarea element,<\/span>\n<span class=\"go\"> @@ -32,6 +33,7 @@ Package: node-autosize<\/span>\n<span class=\"go\">  Architecture: all<\/span>\n<span class=\"go\">  Depends: ${misc:Depends}<\/span>\n<span class=\"go\">   , nodejs<\/span>\n<span class=\"go\"> +Multi-Arch: foreign<\/span>\n<span class=\"go\">  Description: script to automatically adjust textarea height to fit text - Javascript<\/span>\n<span class=\"go\">   Autosize is a small, stand-alone script to automatically adjust textarea<\/span>\n<span class=\"go\">   height to fit text. The autosize function accepts a single textarea element,<\/span>\n<\/pre><\/div>\n<p>The Debian Janitor also has a new  <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/multiarch-fixes\/\">multiarch-fixes<\/a> suite that runs <em>apply-multiarch-hints<\/em> across packages in the archive\nand proposes merge requests. For example, you can see the\nmerge request against autosize.js  <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/js-team\/autosize.js\/-\/merge_requests\/1\">here<\/a>.<\/p>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Debian Janitor: All Packages Processed with\u00a0Lintian-Brush","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-update-5.html","rel":"alternate"}},"published":"2020-09-12T08:00:00+02:00","updated":"2020-09-12T08:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133, Perry Lorrier"},"id":"tag:www.jelmer.uk,2020-09-12:janitor-update-5.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>On 12 July 2019, the Janitor started fixing lintian issues in packages in the\nDebian archive. Now, a year and a half later, it has processed every one of the\nalmost 28,000 packages at least&nbsp;once.<\/p>\n<a class=\"reference external image-reference\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/stats#burndown\">\n<img alt=\"Graph with Lintian Fixes Burndown\" src=\"\/images\/janitor-lintian-fixes-burndown.png\" \/>\n<\/a>\n<p>As discussed two weeks ago, this has resulted in roughly\n65,000 total changes. These 65,000 changes were made to\na total of almost 17,000 packages. Of the remaining packages,\nfor about 4,500 lintian-brush could not make any improvements.\nThe rest (about 6,500) failed to be processed for one\nof many reasons \u2013 they are e.g. not yet migrated off\n<a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/Alioth\">alioth<\/a>, use uncommon formatting\nthat can&#8217;t be preserved or failed to build for one reason or&nbsp;another.<\/p>\n<img alt=\"Graph with runs by status (success, failed, nothing-to-do)\" src=\"\/images\/janitor-lintian-fixes-status.png\" \/>\n<p>Now that the entire archive has been processed, packages\nare prioritized based on the likelihood of a change being\nmade to them&nbsp;successfully.<\/p>\n<p>Over the course of its existence, the Janitor has slowly\ngained support for a wider variety of packaging methods.\nFor example, it can now edit the templates for some of\nthe generated control files. Many of the packages that\nthe janitor was unable to propose changes for the first\ntime around are expected to be correctly handled when they\nare&nbsp;reprocessed.<\/p>\n<p>If you\u2019re a Debian developer, you can find the list of improvements\nmade by the janitor in your packages by going to\n<a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/m\/\">https:\/\/janitor.debian.net\/m\/<\/a>.<\/p>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Debian Janitor: The Slow Trickle from Git Repositories to the Debian\u00a0Archive","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-update-4.html","rel":"alternate"}},"published":"2020-08-29T08:00:00+02:00","updated":"2020-08-29T08:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133, Perry Lorrier"},"id":"tag:www.jelmer.uk,2020-08-29:janitor-update-4.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p><a class=\"reference external\" href=\"https:\/\/jelmer.uk\/janitor-update-3.html\">Last week\u2019s blog post<\/a>\ndocumented how there are now over 30,000 lintian issues\nthat have been fixed in git packaging repositories by the&nbsp;Janitor.<\/p>\n<p>It&#8217;s important to note that any fixes from the Janitor that\nmake it into a Git packaging repository will also need\nto be uploaded to the Debian archive. This currently requires\nthat a Debian packager clones the repository and builds\nand uploads the&nbsp;package.<\/p>\n<p>Until a change makes it into the archive, users of Debian\nwill unfortunately not see the benefits of improvements\nmade by the&nbsp;Janitor.<\/p>\n<p>82% of the 30,000 changes from the Janitor that have made\nit into a Git repository have not yet been uploaded, although\nchanges do slowly trickle in as maintainers make other\nchanges to packages and upload them along with the lintian\nfixes from the Janitor. This is not just true for changes\nfrom the Janitor, but for all sorts of other smaller improvements\nas&nbsp;well.<\/p>\n<p>However, the process of cloning and building git repositories\nand uploading the resulting packages to the Debian archive\nis fairly time-consuming \u2013 and it\u2019s probably not worth\nthe time of developers to follow up every change from the\nJanitor with a labour-intensive upload to the&nbsp;archive.<\/p>\n<p>It would be great if it was easier to trigger uploads from\ngit commits. Projects like  <a class=\"reference external\" href=\"https:\/\/spwhitton.name\/blog\/entry\/tag2upload\/\">tag2upload<\/a>  will hopefully help, and\nmake it more likely that changes end up in the Debian&nbsp;archive.<\/p>\n<p>The majority packages do get at least one new source version\nupload per release, so most changes will eventually make\nit into the&nbsp;archive.<\/p>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Debian Janitor: > 60,000 Lintian Issues Automatically\u00a0Fixed","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-update-3.html","rel":"alternate"}},"published":"2020-08-22T08:00:00+02:00","updated":"2020-08-22T08:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133, Perry Lorrier"},"id":"tag:www.jelmer.uk,2020-08-22:janitor-update-3.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<div class=\"section\" id=\"scheduling-lintian-fixes\">\n<h2>Scheduling Lintian&nbsp;Fixes<\/h2>\n<p>To determine which packages to process, the  <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/\">Janitor<\/a>  looks at the import of  <a class=\"reference external\" href=\"https:\/\/lintian.debian.org\/\">lintian<\/a>  output across the archive that is available\nin  <a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/UltimateDebianDatabase\/\"><span class=\"caps\">UDD<\/span><\/a> <a class=\"footnote-reference\" href=\"#f1\" id=\"footnote-reference-1\">[1]<\/a>. It\nwill prioritize those packages with the most and more severe issues that it has\nfixers&nbsp;for.<\/p>\n<p>Once a package is selected, it will clone the packaging repository and run\n<a class=\"reference external\" href=\"https:\/\/manpages.debian.org\/testing\/lintian-brush\/lintian-brush.1.en.html\">lintian-brush<\/a>\non it.  Lintian-brush provides a framework for applying a set of \u201cfixers\u201d to a\npackage. It will run each of a set of \u201cfixers\u201d in a pristine version of the\nrepository, and handles most of the heavy&nbsp;lifting.<\/p>\n<\/div>\n<div class=\"section\" id=\"the-inner-workings-of-a-fixer\">\n<h2>The Inner Workings of a&nbsp;Fixer<\/h2>\n<p>Each fixer is just an executable which gets run in a clean\ncheckout of the package, and can make changes there. Most\nof the fixers are written in Python or shell, but they\ncan be in any&nbsp;language.<\/p>\n<p>The contract for fixers is pretty&nbsp;simple:<\/p>\n<ul class=\"simple\">\n<li>If the fixer exits with non-zero, the changes are reverted and fixer is\nconsidered to have&nbsp;failed<\/li>\n<li>If it exits with zero and made changes, then it should write a summary of its\nchanges to standard&nbsp;out<\/li>\n<\/ul>\n<p>If a fixer is uncertain about the changes it has made, it should report so on\nstandard output using a pseudo-header.  By default, lintian-brush will discard\nany changes with uncertainty but if you are running it locally you can still\napply them by specifying <tt class=\"docutils literal\"><span class=\"pre\">--uncertain<\/span><\/tt>.<\/p>\n<p>The summary message on standard out will be used for the commit message and\n(possibly) the changelog message, if the package doesn\u2019t use gbp&nbsp;dch.<\/p>\n<\/div>\n<div class=\"section\" id=\"example-fixer\">\n<h2>Example&nbsp;Fixer<\/h2>\n<p>Let\u2019s look at an example. The package priority \u201cextra\u201d is deprecated since\nDebian Policy 4.0.1 (released August 2 017) \u2013 see\n<a class=\"reference external\" href=\"https:\/\/www.debian.org\/doc\/debian-policy\/ch-archive.html#priorities\">Policy 2.5 &#8220;Priorities&#8221;<\/a>.\nInstead, most packages should use the \u201coptional\u201d&nbsp;priority.<\/p>\n<p>Lintian will warn when a package uses the deprecated \u201cextra\u201d value for the\n\u201cPriority\u201d  - the associated tag is\n<a class=\"reference external\" href=\"https:\/\/lintian.debian.org\/tags\/priority-extra-is-replaced-by-priority-optional.html\">priority-extra-is-replaced-by-priority-optional<\/a>.\nLintian-brush has a fixer script that can automatically replace \u201cextra\u201d with&nbsp;\u201coptional\u201d.<\/p>\n<p>On systems that have lintian-brush installed, the source for the fixer lives in\n<a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\/-\/blob\/master\/fixers\/priority-extra-is-replaced-by-priority-optional.py\">\/usr\/share\/lintian-brush\/fixers\/priority-extra-is-replaced-by-priority-optional.py<\/a>,\nbut here is a copy of it for&nbsp;reference:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"ch\">#!\/usr\/bin\/python3<\/span>\n\n<span class=\"kn\">from<\/span> <span class=\"nn\">debmutate.control<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ControlEditor<\/span>\n<span class=\"kn\">from<\/span> <span class=\"nn\">lintian_brush.fixer<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">report_result<\/span><span class=\"p\">,<\/span> <span class=\"n\">fixed_lintian_tag<\/span>\n\n<span class=\"k\">with<\/span> <span class=\"n\">ControlEditor<\/span><span class=\"p\">()<\/span> <span class=\"k\">as<\/span> <span class=\"n\">updater<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">para<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">updater<\/span><span class=\"o\">.<\/span><span class=\"n\">paragraphs<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">para<\/span><span class=\"o\">.<\/span><span class=\"n\">get<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;Priority&quot;<\/span><span class=\"p\">)<\/span> <span class=\"o\">==<\/span> <span class=\"s2\">&quot;extra&quot;<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">para<\/span><span class=\"p\">[<\/span><span class=\"s2\">&quot;Priority&quot;<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">&quot;optional&quot;<\/span>\n            <span class=\"n\">fixed_lintian_tag<\/span><span class=\"p\">(<\/span>\n                <span class=\"n\">para<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;priority-extra-is-replaced-by-priority-optional&#39;<\/span><span class=\"p\">)<\/span>\n\n<span class=\"n\">report_result<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;Change priority extra to priority optional.&quot;<\/span><span class=\"p\">)<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>This fixer is written in Python and uses the  <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/debmutate\">debmutate<\/a>  library to easily modify\ncontrol files while preserving formatting \u2014 or back out if it is not possible\nto preserve&nbsp;formatting.<\/p>\n<p>All the current fixers come with tests, e.g. for this particular fixer the\ntests can be found here:\n<a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\/-\/tree\/master\/tests\/priority-extra-is-replaced-by-priority-optional\">https:\/\/salsa.debian.org\/jelmer\/lintian-brush\/-\/tree\/master\/tests\/priority-extra-is-replaced-by-priority-optional<\/a>.<\/p>\n<p>For more details on writing new fixers, see the  <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush#writing-new-fixers\"><span class=\"caps\">README<\/span><\/a>  for&nbsp;lintian-brush.<\/p>\n<p>For more details on debugging them, see the  <a class=\"reference external\" href=\"https:\/\/manpages.debian.org\/unstable\/lintian-brush\/lintian-brush.1.en.html\">manual page<\/a>.<\/p>\n<\/div>\n<div class=\"section\" id=\"successes-by-fixer\">\n<h2>Successes by&nbsp;fixer<\/h2>\n<p>Here is a list of the fixers currently available, with the number of successful\nmerges\/pushes per&nbsp;fixer:<\/p>\n<table>\n<thead>\n<tr class=\"row-odd\">\n  <th class=\"head\">Lintian Tag<\/th>\n  <th class=\"head\">Previously merged\/pushed<\/th>\n  <th class=\"head\">Ready but not yet merged\/pushed<\/th>\n<\/tr>\n<\/thead>\n<tbody valign=\"top\" name=\"tag-table\">\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/uses-debhelper-compat-file.html\">uses-debhelper-compat-file<\/a><\/td>\n    <td>4906<\/td>\n    <td>4161<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/upstream-metadata-file-is-missing.html\">upstream-metadata-file-is-missing<\/a><\/td>\n    <td>4281<\/td>\n    <td>3841<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/package-uses-old-debhelper-compat-version.html\">package-uses-old-debhelper-compat-version<\/a><\/td>\n    <td>4256<\/td>\n    <td>3617<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/upstream-metadata-missing-bug-tracking.html\">upstream-metadata-missing-bug-tracking<\/a><\/td>\n    <td>2438<\/td>\n    <td>2995<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/out-of-date-standards-version.html\">out-of-date-standards-version<\/a><\/td>\n    <td>2062<\/td>\n    <td>2936<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/upstream-metadata-missing-repository.html\">upstream-metadata-missing-repository<\/a><\/td>\n    <td>1936<\/td>\n    <td>2987<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/trailing-whitespace.html\">trailing-whitespace<\/a><\/td>\n    <td>1720<\/td>\n    <td>2295<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/insecure-copyright-format-uri.html\">insecure-copyright-format-uri<\/a><\/td>\n    <td>1791<\/td>\n    <td>1093<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/package-uses-deprecated-debhelper-compat-version.html\">package-uses-deprecated-debhelper-compat-version<\/a><\/td>\n    <td>1391<\/td>\n    <td>1287<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/vcs-obsolete-in-debian-infrastructure.html\">vcs-obsolete-in-debian-infrastructure<\/a><\/td>\n    <td>872<\/td>\n    <td>782<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/homepage-field-uses-insecure-uri.html\">homepage-field-uses-insecure-uri<\/a><\/td>\n    <td>527<\/td>\n    <td>1111<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/vcs-field-not-canonical.html\">vcs-field-not-canonical<\/a><\/td>\n    <td>850<\/td>\n    <td>655<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-changelog-has-wrong-day-of-week.html\">debian-changelog-has-wrong-day-of-week<\/a><\/td>\n    <td>224<\/td>\n    <td>376<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-watch-uses-insecure-uri.html\">debian-watch-uses-insecure-uri<\/a><\/td>\n    <td>314<\/td>\n    <td>242<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/useless-autoreconf-build-depends.html\">useless-autoreconf-build-depends<\/a><\/td>\n    <td>112<\/td>\n    <td>428<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/priority-extra-is-replaced-by-priority-optional.html\">priority-extra-is-replaced-by-priority-optional<\/a><\/td>\n    <td>315<\/td>\n    <td>194<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-rules-contains-unnecessary-get-orig-source-target.html\">debian-rules-contains-unnecessary-get-orig-source-target<\/a><\/td>\n    <td>35<\/td>\n    <td>428<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/tab-in-license-text.html\">tab-in-license-text<\/a><\/td>\n    <td>125<\/td>\n    <td>320<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-changelog-line-too-long.html\">debian-changelog-line-too-long<\/a><\/td>\n    <td>186<\/td>\n    <td>190<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-rules-sets-dpkg-architecture-variable.html\">debian-rules-sets-dpkg-architecture-variable<\/a><\/td>\n    <td>69<\/td>\n    <td>166<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-rules-uses-unnecessary-dh-argument.html\">debian-rules-uses-unnecessary-dh-argument<\/a><\/td>\n    <td>42<\/td>\n    <td>182<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/package-lacks-versioned-build-depends-on-debhelper.html\">package-lacks-versioned-build-depends-on-debhelper<\/a><\/td>\n    <td>125<\/td>\n    <td>95<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/unversioned-copyright-format-uri.html\">unversioned-copyright-format-uri<\/a><\/td>\n    <td>43<\/td>\n    <td>136<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/package-needs-versioned-debhelper-build-depends.html\">package-needs-versioned-debhelper-build-depends<\/a><\/td>\n    <td>127<\/td>\n    <td>50<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/binary-control-field-duplicates-source.html\">binary-control-field-duplicates-source<\/a><\/td>\n    <td>34<\/td>\n    <td>134<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/renamed-tag.html\">renamed-tag<\/a><\/td>\n    <td>73<\/td>\n    <td>69<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/vcs-field-uses-insecure-uri.html\">vcs-field-uses-insecure-uri<\/a><\/td>\n    <td>14<\/td>\n    <td>109<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/uses-deprecated-adttmp.html\">uses-deprecated-adttmp<\/a><\/td>\n    <td>13<\/td>\n    <td>91<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debug-symbol-migration-possibly-complete.html\">debug-symbol-migration-possibly-complete<\/a><\/td>\n    <td>12<\/td>\n    <td>88<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/copyright-refers-to-symlink-license.html\">copyright-refers-to-symlink-license<\/a><\/td>\n    <td>51<\/td>\n    <td>48<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-control-has-unusual-field-spacing.html\">debian-control-has-unusual-field-spacing<\/a><\/td>\n    <td>33<\/td>\n    <td>66<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/old-source-override-location.html\">old-source-override-location<\/a><\/td>\n    <td>32<\/td>\n    <td>62<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/out-of-date-copyright-format.html\">out-of-date-copyright-format<\/a><\/td>\n    <td>20<\/td>\n    <td>62<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/public-upstream-key-not-minimal.html\">public-upstream-key-not-minimal<\/a><\/td>\n    <td>43<\/td>\n    <td>30<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/older-source-format.html\">older-source-format<\/a><\/td>\n    <td>17<\/td>\n    <td>54<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/custom-compression-in-debian-source-options.html\">custom-compression-in-debian-source-options<\/a><\/td>\n    <td>12<\/td>\n    <td>57<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/copyright-refers-to-versionless-license-file.html\">copyright-refers-to-versionless-license-file<\/a><\/td>\n    <td>29<\/td>\n    <td>39<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/tab-in-licence-text.html\">tab-in-licence-text<\/a><\/td>\n    <td>33<\/td>\n    <td>31<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/global-files-wildcard-not-first-paragraph-in-dep5-copyright.html\">global-files-wildcard-not-first-paragraph-in-dep5-copyright<\/a><\/td>\n    <td>28<\/td>\n    <td>33<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/out-of-date-copyright-format-uri.html\">out-of-date-copyright-format-uri<\/a><\/td>\n    <td>9<\/td>\n    <td>50<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/field-name-typo-dep5-copyright.html\">field-name-typo-dep5-copyright<\/a><\/td>\n    <td>29<\/td>\n    <td>29<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/copyright-does-not-refer-to-common-license-file.html\">copyright-does-not-refer-to-common-license-file<\/a><\/td>\n    <td>13<\/td>\n    <td>42<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debhelper-but-no-misc-depends.html\">debhelper-but-no-misc-depends<\/a><\/td>\n    <td>9<\/td>\n    <td>45<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-watch-file-is-missing.html\">debian-watch-file-is-missing<\/a><\/td>\n    <td>11<\/td>\n    <td>41<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-control-has-obsolete-dbg-package.html\">debian-control-has-obsolete-dbg-package<\/a><\/td>\n    <td>8<\/td>\n    <td>40<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/possible-missing-colon-in-closes.html\">possible-missing-colon-in-closes<\/a><\/td>\n    <td>31<\/td>\n    <td>13<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/unnecessary-testsuite-autopkgtest-field.html\">unnecessary-testsuite-autopkgtest-field<\/a><\/td>\n    <td>32<\/td>\n    <td>9<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/missing-debian-source-format.html\">missing-debian-source-format<\/a><\/td>\n    <td>7<\/td>\n    <td>33<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debhelper-tools-from-autotools-dev-are-deprecated.html\">debhelper-tools-from-autotools-dev-are-deprecated<\/a><\/td>\n    <td>9<\/td>\n    <td>29<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/vcs-field-mismatch.html\">vcs-field-mismatch<\/a><\/td>\n    <td>8<\/td>\n    <td>29<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-changelog-file-contains-obsolete-user-emacs-setting.html\">debian-changelog-file-contains-obsolete-user-emacs-setting<\/a><\/td>\n    <td>33<\/td>\n    <td>0<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/patch-file-present-but-not-mentioned-in-series.html\">patch-file-present-but-not-mentioned-in-series<\/a><\/td>\n    <td>24<\/td>\n    <td>9<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/ copyright-refers-to-versionless-license-file.html\"> copyright-refers-to-versionless-license-file<\/a><\/td>\n    <td>22<\/td>\n    <td>9<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-control-has-empty-field.html\">debian-control-has-empty-field<\/a><\/td>\n    <td>25<\/td>\n    <td>6<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/missing-build-dependency-for-dh-addon.html\">missing-build-dependency-for-dh-addon<\/a><\/td>\n    <td>10<\/td>\n    <td>20<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/obsolete-field-in-dep5-copyright.html\">obsolete-field-in-dep5-copyright<\/a><\/td>\n    <td>15<\/td>\n    <td>13<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/xs-testsuite-field-in-debian-control.html\">xs-testsuite-field-in-debian-control<\/a><\/td>\n    <td>20<\/td>\n    <td>7<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/ancient-python-version-field.html\">ancient-python-version-field<\/a><\/td>\n    <td>13<\/td>\n    <td>12<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/unnecessary-team-upload.html\">unnecessary-team-upload<\/a><\/td>\n    <td>19<\/td>\n    <td>5<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/misspelled-closes-bug.html\">misspelled-closes-bug<\/a><\/td>\n    <td>6<\/td>\n    <td>16<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/field-name-typo-in-dep5-copyright.html\">field-name-typo-in-dep5-copyright<\/a><\/td>\n    <td>1<\/td>\n    <td>20<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/transitional-package-not-oldlibs-optional.html\">transitional-package-not-oldlibs-optional<\/a><\/td>\n    <td>4<\/td>\n    <td>17<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/maintainer-script-without-set-e.html\">maintainer-script-without-set-e<\/a><\/td>\n    <td>9<\/td>\n    <td>11<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/dh-clean-k-is-deprecated.html\">dh-clean-k-is-deprecated<\/a><\/td>\n    <td>4<\/td>\n    <td>14<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/no-dh-sequencer.html\">no-dh-sequencer<\/a><\/td>\n    <td>14<\/td>\n    <td>4<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/missing-vcs-browser-field.html\">missing-vcs-browser-field<\/a><\/td>\n    <td>5<\/td>\n    <td>12<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/space-in-std-shortname-in-dep5-copyright.html\">space-in-std-shortname-in-dep5-copyright<\/a><\/td>\n    <td>6<\/td>\n    <td>10<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/xc-package-type-in-debian-control.html\">xc-package-type-in-debian-control<\/a><\/td>\n    <td>4<\/td>\n    <td>11<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-rules-missing-recommended-target.html\">debian-rules-missing-recommended-target<\/a><\/td>\n    <td>4<\/td>\n    <td>10<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/desktop-entry-contains-encoding-key.html\">desktop-entry-contains-encoding-key<\/a><\/td>\n    <td>1<\/td>\n    <td>13<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/build-depends-on-obsolete-package.html\">build-depends-on-obsolete-package<\/a><\/td>\n    <td>4<\/td>\n    <td>9<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/license-file-listed-in-debian-copyright.html\">license-file-listed-in-debian-copyright<\/a><\/td>\n    <td>1<\/td>\n    <td>12<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/missing-built-using-field-for-golang-package.html\">missing-built-using-field-for-golang-package<\/a><\/td>\n    <td>9<\/td>\n    <td>4<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/unused-license-paragraph-in-dep5-copyright.html\">unused-license-paragraph-in-dep5-copyright<\/a><\/td>\n    <td>4<\/td>\n    <td>7<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/missing-build-dependency-for-dh_command.html\">missing-build-dependency-for-dh_command<\/a><\/td>\n    <td>6<\/td>\n    <td>4<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/comma-separated-files-in-dep5-copyright.html\">comma-separated-files-in-dep5-copyright<\/a><\/td>\n    <td>3<\/td>\n    <td>6<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/systemd-service-file-refers-to-var-run.html\">systemd-service-file-refers-to-var-run<\/a><\/td>\n    <td>4<\/td>\n    <td>5<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/copyright-not-using-common-license-for-apache2.html\">copyright-not-using-common-license-for-apache2<\/a><\/td>\n    <td>3<\/td>\n    <td>5<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-tests-control-autodep8-is-obsolete.html\">debian-tests-control-autodep8-is-obsolete<\/a><\/td>\n    <td>2<\/td>\n    <td>6<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/dh-quilt-addon-but-quilt-source-format.html\">dh-quilt-addon-but-quilt-source-format<\/a><\/td>\n    <td>2<\/td>\n    <td>6<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/no-homepage-field.html\">no-homepage-field<\/a><\/td>\n    <td>3<\/td>\n    <td>5<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/font-package-not-multi-arch-foreign.html\">font-packge-not-multi-arch-foreign<\/a><\/td>\n    <td>1<\/td>\n    <td>6<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/homepage-in-binary-package.html\">homepage-in-binary-package<\/a><\/td>\n    <td>1<\/td>\n    <td>4<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/vcs-field-bitrotted.html\">vcs-field-bitrotted<\/a><\/td>\n    <td>1<\/td>\n    <td>3<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/built-using-field-on-arch-all-package.html\">built-using-field-on-arch-all-package<\/a><\/td>\n    <td>2<\/td>\n    <td>1<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/ copyright-should-refer-to-common-license-file-for-apache-2.html\"> copyright-should-refer-to-common-license-file-for-apache-2<\/a><\/td>\n    <td>1<\/td>\n    <td>2<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-pyversions-is-obsolete.html\">debian-pyversions-is-obsolete<\/a><\/td>\n    <td>3<\/td>\n    <td>0<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/debian-watch-file-uses-deprecated-githubredir.html\">debian-watch-file-uses-deprecated-githubredir<\/a><\/td>\n    <td>1<\/td>\n    <td>1<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/executable-desktop-file.html\">executable-desktop-file<\/a><\/td>\n    <td>1<\/td>\n    <td>1<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/skip-systemd-native-flag-missing-pre-depends.html\">skip-systemd-native-flag-missing-pre-depends<\/a><\/td>\n    <td>1<\/td>\n    <td>1<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/vcs-field-uses-not-recommended-uri-format.html\">vcs-field-uses-not-recommended-uri-format<\/a><\/td>\n    <td>1<\/td>\n    <td>1<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/init.d-script-needs-depends-on-lsb-base.html\">init.d-script-needs-depends-on-lsb-base<\/a><\/td>\n    <td>1<\/td>\n    <td>0<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/maintainer-also-in-uploaders.html\">maintainer-also-in-uploaders<\/a><\/td>\n    <td>1<\/td>\n    <td>0<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/public-upstream-keys-in-multiple-locations.html\">public-upstream-keys-in-multiple-locations<\/a><\/td>\n    <td>1<\/td>\n    <td>0<\/td>\n<\/tr>\n\n<tr>\n    <td><a href=\"https:\/\/lintian.debian.org\/tags\/wrong-debian-qa-group-name.html\">wrong-debian-qa-group-name<\/a><\/td>\n    <td>1<\/td>\n    <td>0<\/td>\n<\/tr>\n\n<tr>\n    <td><b>Total<\/b><\/td>\n    <td><b>29656<\/b><\/td>\n    <td><b>32209<\/b><\/td>\n<\/tr>\n<\/table><p class=\"rubric\">Footnotes<\/p>\n<table class=\"docutils footnote\" frame=\"void\" id=\"f1\" rules=\"none\">\n<colgroup><col class=\"label\" \/><col \/><\/colgroup>\n<tbody valign=\"top\">\n<tr><td class=\"label\"><a class=\"fn-backref\" href=\"#footnote-reference-1\">[1]<\/a><\/td><td>temporarily unavailable due to <a class=\"reference external\" href=\"https:\/\/bugs.debian.org\/960156\">Debian bug #960156<\/a>  \u2013 but the Janitor is relying on historical data<\/td><\/tr>\n<\/tbody>\n<\/table>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Debian Janitor: 8,200 landed changes landed so\u00a0far","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-update-2.html","rel":"alternate"}},"published":"2020-08-15T08:00:00+02:00","updated":"2020-08-15T08:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133, Perry Lorrier"},"id":"tag:www.jelmer.uk,2020-08-15:janitor-update-2.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>The bot has been submitting merge requests for about seven\nmonths now. The rollout has happened gradually across the\nDebian archive, and the bot is now enabled for all packages\nmaintained on  <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/\">Salsa<\/a>,  <a class=\"reference external\" href=\"https:\/\/gitlab.com\/\">GitLab<\/a>,  <a class=\"reference external\" href=\"https:\/\/github.com\/\">GitHub<\/a>  and  <a class=\"reference external\" href=\"https:\/\/launchpad.net\/\">Launchpad<\/a>.<\/p>\n<p>There are currently over 1,000 open merge requests, and\nclose to 3,400 merge requests have been merged so far.\nDirect pushes are enabled for a number of large Debian\nteams, with about 5,000 direct pushes to date. That covers\n<a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/stats\">about 11,000 lintian tags of varying severities<\/a>  (about 75 different varieties) fixed across&nbsp;Debian.<\/p>\n<img alt=\"Janitor pushes over time\" src=\"\/images\/janitor-pushes-over-time.png\" \/>\n<img alt=\"Janitor merges over time\" src=\"\/images\/janitor-merges-over-time.png\" \/>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"Improvements to Merge Proposals by the\u00a0Janitor","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/janitor-update-1.html","rel":"alternate"}},"published":"2020-08-08T08:00:00+02:00","updated":"2020-08-08T08:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133, Perry Lorrier"},"id":"tag:www.jelmer.uk,2020-08-08:janitor-update-1.html","summary":"<p class=\"italic\">The <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/debian-janitor.html\">Debian Janitor<\/a> is an automated\nsystem that commits fixes for (minor) issues in Debian packages that can be\nfixed by software. It gradually started proposing merges in early\nDecember. The first set of changes sent out ran <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on sid packages maintained in\nGit. This post is part of <a class=\"reference external\" href=\"https:\/\/jelmer.uk\/tag\/janitor-update.html\">a series<\/a> about the progress of the&nbsp;Janitor.<\/p>\n<p>Since the original post, merge proposals created by the\njanitor now include the\n<a class=\"reference external\" href=\"https:\/\/manpages.debian.org\/testing\/devscripts\/debdiff.1.en.html\">debdiff<\/a>\nbetween a build with and without the changes (showing the impact to the binary\npackages), in addition to the merge proposal diff (which shows the impact to\nthe source&nbsp;package).<\/p>\n<p>New merge proposals also include a link to the  <a class=\"reference external\" href=\"https:\/\/www.diffoscope.org\/\">diffoscope<\/a>  diff between a vanilla build and the build\nwith changes. Unfortunately these can be a bit noisy for packages that are not\n<a class=\"reference external\" href=\"https:\/\/reproducible-builds.org\/\">reproducible<\/a>\nyet, due to the difference in build environment between\nthe two&nbsp;builds.<\/p>\n<p>This is part of the effort to keep the changes from the\njanitor <a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/debian-janitor.html#ensuring-quality\">high-quality<\/a>.<\/p>\n<p>The rollout surfaced  <a class=\"reference external\" href=\"https:\/\/bugs.debian.org\/lintian-brush\">some bugs in lintian-brush<\/a>; these have been either fixed or\nmitigated (e.g. by disabling specified&nbsp;fixers).<\/p>\n<p class=\"italic\">For more information about the Janitor&#8217;s lintian-fixes efforts, see <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/\">the landing page<\/a>.<\/p>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"debian-janitor"}},{"@attributes":{"term":"janitor"}},{"@attributes":{"term":"janitor-update"}}]},{"title":"The Debian\u00a0Janitor","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/debian-janitor.html","rel":"alternate"}},"published":"2019-12-03T22:00:12+01:00","updated":"2019-12-03T22:00:12+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2019-12-03:debian-janitor.html","summary":"<!-- TL;DR\n=====\n\nThe `Janitor <https:\/\/janitor.debian.net\/>` is a new bot that automatically\nproposes improvements for Debian packages maintained in Git. -->\n<!-- Problem statement -->\n<p>There are a lot of small changes that can be made to the Debian archive to\nincrease the overall quality. Many of these changes are small and have just\nminor benefits if they are applied to just a single package. Lintian encourages\nmaintainers to fix these problems by pointing out the common&nbsp;ones.<\/p>\n<p>Most of these issues are often trivially fixable; they are in general an\ninefficient use of human time, and it takes a lot of effort to keep up with.\nThis is something that can clearly be&nbsp;automated.<\/p>\n<p>Several tools (e.g. onovy&#8217;s <a class=\"reference external\" href=\"https:\/\/github.com\/onovy\/onovy-mass\">mass tool<\/a>,\nand the <a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/lintian-brush-intro.html\">lintian-brush<\/a> tool\nthat I&#8217;ve been working on) go a step further and (for a subset of the issues\nreported by lintian) fix the problems for you, where they can.  Lintian-brush\ncan currently fix most instances of <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush#supported-tags\">close to 100 lintian tags<\/a>.<\/p>\n<p>Thanks to the Vcs-* fields set by many packages and <a class=\"reference external\" href=\"https:\/\/docs.gitlab.com\/ee\/api\/\">the APIs provided by hosting\nplatforms like Salsa<\/a>, it is now possible to\nproactively attempt to fix these&nbsp;issues.<\/p>\n<p>The Debian Janitor is a tool that will run lintian-brush across the entire\narchive, and propose fixes to lintian issues via pull&nbsp;request.<\/p>\n<div class=\"section\" id=\"objectives\">\n<h2>Objectives<\/h2>\n<p>The aim of Debian Janitor is to take some drudge work away from Debian\nmaintainers where possible, so they can spend their time on more important\npackaging work.  Its purpose is to make automated changes quick and easy to\napply, with minimal overhead for package maintainers. It is essentially a bit\nof infrastructure to run lintian-brush across all of the&nbsp;archive.<\/p>\n<p>The actions of the bot are restricted to a limited set of problems for which\nobviously correct actions can be taken. It is not meant to automate all\npackaging, or even to cover automating all instances of the issues it knows&nbsp;about.<\/p>\n<p>The bot is designed to be conservative and delight with consistently correct\nfixes instead of proposing possibly incorrect fixes and hoping for the best.\nConsiderable effort has been made to avoid the janitor creating pull requests\nwith incorrect changes, as these take valuable time away from maintainers, the\npackage doesn&#8217;t actually improve (since the merge request is rejected) and it\nmakes it likelier that future pull requests from the Debian Janitor bot are\nignored or&nbsp;rejected.<\/p>\n<p>In short: The janitor is meant to propose correct changes if it can, and back\noff&nbsp;otherwise.<\/p>\n<\/div>\n<div class=\"section\" id=\"design\">\n<h2>Design<\/h2>\n<p>The Janitor finds package sources in version control systems from the Vcs*-\ncontrol field in Debian source packages. If the packaging branch is hosted on a\nhosting platform that the Janitor has a presence on, it will attempt to run\n<a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/lintian-brush-intro.html\">lintian-brush<\/a> on the packaging branch and (if there are any changes made)\nbuild the package and\npropose a merge. It is based on\n<a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/silver-platter\/\">silver-platter<\/a> and currently has\nsupport&nbsp;for:<\/p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/\">Salsa<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/github.com\/\">GitHub<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/launchpad.net\">Launchpad<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/gitlab.com\/\">GitLab<\/a><\/li>\n<\/ul>\n<p>The Janitor is driven from the lintian and vcswatch tables in\n<a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/UltimateDebianDatabase\/\"><span class=\"caps\">UDD<\/span><\/a>. It queries for packages\nthat are affected by any of the <a class=\"reference external\" href=\"https:\/\/lintian.debian.org\/\">lintian<\/a> tags\nthat <a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/lintian-brush-intro.html\">lintian-brush<\/a> has a\nfixer script for. This way it can limit the number of repositories it has to&nbsp;process.<\/p>\n<\/div>\n<div class=\"section\" id=\"ensuring-quality\">\n<h2>Ensuring&nbsp;quality<\/h2>\n<p>There are a couple of things I am doing to make sure that the Debian\nJanitor delights rather than&nbsp;annoys.<\/p>\n<div class=\"section\" id=\"high-quality-changes\">\n<h3>High quality&nbsp;changes<\/h3>\n<p>Lintian-brush has end-to-end tests for its&nbsp;fixers.<\/p>\n<p>In order to make sure that merge requests are useful and high-value, the bot\nwill only propose changes from lintian-brush&nbsp;that:<\/p>\n<ul class=\"simple\">\n<li>successfully build in a chroot and pass <a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/ContinuousIntegration\/autopkgtest\">autopkgtest<\/a> and <a class=\"reference external\" href=\"https:\/\/wiki.debian.org\/piuparts\">piuparts<\/a>;<\/li>\n<li>are not completely trivial - e.g. only stripping&nbsp;whitespace<\/li>\n<\/ul>\n<p>Changes for a package will also be reviewed by a human before they make it into\na pull&nbsp;request.<\/p>\n<\/div>\n<div class=\"section\" id=\"one-open-pull-request-per-package\">\n<h3>One open pull request per&nbsp;package<\/h3>\n<p>If the bot created a pull request previously, it will attempt to update the\ncurrent request by adding new commits (and updating the pull request\ndescription). It will remove and fix the branch when the pull request conflicts\nbecause of new upstream&nbsp;changes.<\/p>\n<p>In other words, it will only create a single pull request per package and will\nattempt to keep that pull request up to&nbsp;date.<\/p>\n<\/div>\n<div class=\"section\" id=\"gradual-rollout\">\n<h3>Gradual&nbsp;rollout<\/h3>\n<p>I&#8217;m slowly adding interested maintainers to receiving pull requests, before\nopening it up to the entire archive. This should help catch any widespread\nissues&nbsp;early.<\/p>\n<\/div>\n<div class=\"section\" id=\"providing-control\">\n<h3>Providing&nbsp;control<\/h3>\n<p>The bot will be upfront about its pull requests and try to avoid overwhelming\nmaintainers with pull requests&nbsp;by:<\/p>\n<ul class=\"simple\">\n<li>Clearly identifying any merge requests it creates as being made by a bot.\nThis should allow maintainers to prioritize contributions from&nbsp;humans.<\/li>\n<li>Limiting the number of open proposals per maintainer. It starts by opening a\nsingle merge request and won&#8217;t open additional merge requests until the first\nproposal has a&nbsp;response<\/li>\n<li>Providing a way to opt out of future merge requests; just a reply on the\nmerge request is&nbsp;sufficient.<\/li>\n<\/ul>\n<p>Any comments on merge requests will also still be reviewed by a&nbsp;human.<\/p>\n<\/div>\n<\/div>\n<div class=\"section\" id=\"current-state\">\n<h2>Current&nbsp;state<\/h2>\n<p>Debian janitor is running, generating changes and already creating merge\nrequests (albeit under close review). Some examples of merge requests it has&nbsp;created:<\/p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/i3-team\/i3-wm\/merge_requests\/1\">i3 (on&nbsp;Salsa)<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/wouter\/nbd\/merge_requests\/2\">nbd (on&nbsp;Salsa)<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/code.launchpad.net\/~debian-janitor\/friendly-recovery\/lintian-fixes\/+merge\/375943\">friendly recovery (on&nbsp;Launchpad)<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/github.com\/algernon\/dh-exec\/pull\/3\">dh-exec (on&nbsp;GitHub)<\/a><\/li>\n<\/ul>\n<div class=\"section\" id=\"using-the-janitor\">\n<h3>Using the&nbsp;janitor<\/h3>\n<p>The janitor can process any package that\u2019s maintained in Git and has its\nVcs-Git header set correctly (you can use\n<a class=\"reference external\" href=\"https:\/\/qa.debian.org\/cgi-bin\/vcswatch\">vcswatch<\/a> to check&nbsp;this).<\/p>\n<p>If you&#8217;re interested in receiving pull requests early, leave a comment below.\nEventually, the janitor should get to all packages, though it may take a while\nwith the current number of source packages in the&nbsp;archive.<\/p>\n<p>By default, salsa does not send notifications when a new merge request for one\nof the repositories you&#8217;re a maintainer for is created. Make sure you have\nnotifications enabled in\n<a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/profile\/notifications\">your Salsa profile<\/a>,\nby ticking &#8220;New Merge Requests&#8221; for the packages you care&nbsp;about.<\/p>\n<p>You can also see the number of open merge requests for a package repository on\n<a class=\"reference external\" href=\"https:\/\/qa.debian.org\/developer.php\"><span class=\"caps\">QA<\/span><\/a> - it&#8217;s the ! followed by a number in the\npull request&nbsp;column.<\/p>\n<p>It is also possible to download the diff for a particular package (if it&#8217;s been\ngenerated) ahead of the janitor publishing&nbsp;it:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> $ <\/span>curl<span class=\"w\"> <\/span>https:\/\/janitor.debian.net\/api\/lintian-fixes\/pkg\/PACKAGE\/diff\n<\/pre><\/div>\n<p>E.g. for i3-wm, look at\n<a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/api\/lintian-fixes\/pkg\/i3-wm\/diff\">https:\/\/janitor.debian.net\/api\/lintian-fixes\/pkg\/i3-wm\/diff<\/a>.<\/p>\n<\/div>\n<\/div>\n<div class=\"section\" id=\"future-plans\">\n<h2>Future&nbsp;Plans<\/h2>\n<p>The current set of supported hosting platforms covers the bulk of packages in\nDebian that is maintained in a <span class=\"caps\">VCS<\/span>.  The only other 100+ package platform\nthat&#8217;s unsupported is <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/dgit-team\/dgit\">dgit<\/a>. If you\nhave suggestions on how best to submit git changes to dgit repositories (<span class=\"caps\">BTS<\/span>\nbugs with patches? or would that be too much overhead?), let me&nbsp;know.<\/p>\n<p>The next platform that is currently missing is\n<a class=\"reference external\" href=\"https:\/\/bitbucket.org\/\">bitbucket<\/a>, but there are only about 15 packages in\nunstable hosted&nbsp;there.<\/p>\n<p>At the moment, lintian-brush can fix close to 100 lintian tags. It would be\ngreat to add fixers for more common&nbsp;issues.<\/p>\n<p>The janitor should probably be more tightly integrated with other pieces of\nDebian infrastructure, e.g. Jenkins for running jobs or linked to from the\n<a class=\"reference external\" href=\"https:\/\/tracker.debian.org\/\">tracker<\/a> or\n<a class=\"reference external\" href=\"https:\/\/lintian.debian.org\/\">lintian.debian.org<\/a>.<\/p>\n<\/div>\n<div class=\"section\" id=\"more-information\">\n<h2>More&nbsp;information<\/h2>\n<p>See <a class=\"reference external\" href=\"https:\/\/janitor.debian.net\/lintian-fixes\/#faq\">the <span class=\"caps\">FAQ<\/span> on the homepage<\/a>.<\/p>\n<p>If you have any concerns about these roll-out plans, have other ideas or\nquestions, please let me know in the&nbsp;comments.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"git"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}},{"@attributes":{"term":"silver-platter"}}]},{"title":"Silver\u00a0Platter","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/silver-platter-intro.html","rel":"alternate"}},"published":"2019-04-11T03:04:00+02:00","updated":"2019-04-11T03:04:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2019-04-11:silver-platter-intro.html","summary":"<p>Making changes across the open source ecosystem is very hard; software is hosted\non different platforms and in many different version control repositories. Not\nbeing able to make bulk changes slows down the rate of progress. For example, instead\nof being able to actively run a a script that strips out an obsolete header file\n(say &#8220;<span class=\"caps\">DM<\/span>-Upload-Allowed&#8221;) across all Debian packages, we make the linter warn about\nthe deprecated header and wait as all developers manually remove the deprecated&nbsp;header.<\/p>\n<div class=\"section\" id=\"silver-platter-1\">\n<h2>Silver&nbsp;Platter<\/h2>\n<p>Silver-platter is a new tool that aids in making automated changes across\ndifferent version control repositories. It provides a common command-line\ninterface and <span class=\"caps\">API<\/span> that is not specific to a single version control system or hosting\nplatform, so that it&#8217;s easy to propose changes based on a single script across\na large set of&nbsp;repositories.<\/p>\n<p>The tool will check out a repository, run a user-specified script that makes changes\nto the repository, and then either push those changes to the upstream repository or\npropose them for&nbsp;merging.<\/p>\n<p>It&#8217;s specifically built so that it can be run in a shell loop over many\ndifferent repository&nbsp;URLs.<\/p>\n<div class=\"section\" id=\"example\">\n<h3>Example<\/h3>\n<p>As an example, you could use the following script (<tt class=\"docutils literal\"><span class=\"pre\">fix-fsf-address.sh<\/span><\/tt>) to\nupdate the <span class=\"caps\">FSF<\/span> address in copyright&nbsp;headers:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"w\"> <\/span><span class=\"c1\">#!\/bin\/sh<\/span>\n\n<span class=\"w\"> <\/span>perl<span class=\"w\"> <\/span>-i<span class=\"w\"> <\/span>-pe<span class=\"w\"> <\/span><span class=\"se\">\\<\/span>\n<span class=\"w\"> <\/span><span class=\"s1\">&#39;BEGIN{undef $\/;} s\/Free Software<\/span>\n<span class=\"s1\"> ([# ]+)Foundation, Inc\\., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\/Free Software<\/span>\n<span class=\"s1\"> \\1Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA\/smg&#39;<\/span><span class=\"w\"> <\/span>*\n\n<span class=\"w\"> <\/span><span class=\"nb\">echo<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;Update FSF postal address.&quot;<\/span>\n<\/pre><\/div>\n<p>Say you a wanted to create a merge proposal with these changes against\n<tt class=\"docutils literal\">offlineimap<\/tt>. First, log into GitHub (this needs to be done once per hosting&nbsp;site):<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> $ <\/span>svp<span class=\"w\"> <\/span>login<span class=\"w\"> <\/span>https:\/\/github.com\n<\/pre><\/div>\n<p>To see what the changes would be without actually creating the pull request, do a&nbsp;dry-run:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> $ <\/span>svp<span class=\"w\"> <\/span>run<span class=\"w\"> <\/span>--dry-run<span class=\"w\"> <\/span>--diff<span class=\"w\"> <\/span>.\/fix-fsf-address.sh<span class=\"w\"> <\/span>https:\/\/github.com\/offlineimap\/offlineimap\n<span class=\"go\"> Merge proposal created.<\/span>\n<span class=\"go\"> Description: Update FSF postal address.<\/span>\n\n<span class=\"go\"> === modified file &#39;offlineimap.py&#39;<\/span>\n<span class=\"go\"> --- upstream\/offlineimap.py 2018-03-04 03:28:30 +0000<\/span>\n<span class=\"go\"> +++ proposed\/offlineimap.py 2019-04-06 21:07:25 +0000<\/span>\n<span class=\"go\"> @@ -14,7 +14,7 @@<\/span>\n<span class=\"gp\">  #<\/span>\n<span class=\"gp\">  #    <\/span>You<span class=\"w\"> <\/span>should<span class=\"w\"> <\/span>have<span class=\"w\"> <\/span>received<span class=\"w\"> <\/span>a<span class=\"w\"> <\/span>copy<span class=\"w\"> <\/span>of<span class=\"w\"> <\/span>the<span class=\"w\"> <\/span>GNU<span class=\"w\"> <\/span>General<span class=\"w\"> <\/span>Public<span class=\"w\"> <\/span>License\n<span class=\"gp\">  #    <\/span>along<span class=\"w\"> <\/span>with<span class=\"w\"> <\/span>this<span class=\"w\"> <\/span>program<span class=\"p\">;<\/span><span class=\"w\"> <\/span><span class=\"k\">if<\/span><span class=\"w\"> <\/span>not,<span class=\"w\"> <\/span>write<span class=\"w\"> <\/span>to<span class=\"w\"> <\/span>the<span class=\"w\"> <\/span>Free<span class=\"w\"> <\/span>Software\n<span class=\"go\"> -#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA<\/span>\n<span class=\"go\"> +#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA<\/span>\n\n<span class=\"go\">  import os<\/span>\n<span class=\"go\">  import sys<\/span>\n\n<span class=\"go\"> === modified file &#39;setup.py&#39;<\/span>\n<span class=\"go\"> --- upstream\/setup.py       2018-05-01 01:48:26 +0000<\/span>\n<span class=\"go\"> +++ proposed\/setup.py       2019-04-06 21:07:25 +0000<\/span>\n<span class=\"go\"> @@ -19,7 +19,7 @@<\/span>\n<span class=\"gp\">  #<\/span>\n<span class=\"gp\">  #    <\/span>You<span class=\"w\"> <\/span>should<span class=\"w\"> <\/span>have<span class=\"w\"> <\/span>received<span class=\"w\"> <\/span>a<span class=\"w\"> <\/span>copy<span class=\"w\"> <\/span>of<span class=\"w\"> <\/span>the<span class=\"w\"> <\/span>GNU<span class=\"w\"> <\/span>General<span class=\"w\"> <\/span>Public<span class=\"w\"> <\/span>License\n<span class=\"gp\">  #    <\/span>along<span class=\"w\"> <\/span>with<span class=\"w\"> <\/span>this<span class=\"w\"> <\/span>program<span class=\"p\">;<\/span><span class=\"w\"> <\/span><span class=\"k\">if<\/span><span class=\"w\"> <\/span>not,<span class=\"w\"> <\/span>write<span class=\"w\"> <\/span>to<span class=\"w\"> <\/span>the<span class=\"w\"> <\/span>Free<span class=\"w\"> <\/span>Software\n<span class=\"go\"> -#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA<\/span>\n<span class=\"go\"> +#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA<\/span>\n\n<span class=\"go\">  import os<\/span>\n<span class=\"go\">  from distutils.core import setup, Command<\/span>\n<\/pre><\/div>\n<p>Then, create the actual pull request by&nbsp;running:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> $ <\/span>svp<span class=\"w\"> <\/span>run<span class=\"w\"> <\/span>.\/fix-fsf-address.sh<span class=\"w\"> <\/span>https:\/\/github.com\/offlineimap\/offlineimap\n<span class=\"go\"> ...<\/span>\n<span class=\"go\"> Reusing existing repository https:\/\/github.com\/jelmer\/offlineimap<\/span>\n<span class=\"go\"> Merge proposal created.<\/span>\n<span class=\"go\"> URL: https:\/\/github.com\/OfflineIMAP\/offlineimap\/pull\/609<\/span>\n<span class=\"go\"> Description: Update FSF postal address.<\/span>\n<\/pre><\/div>\n<p>This would create a new commit with the updated postal address (if any files\nwere changed) and the commit message <tt class=\"docutils literal\">Update <span class=\"caps\">FSF<\/span> postal address<\/tt>. You can see the resulting\npull request <a class=\"reference external\" href=\"https:\/\/github.com\/OfflineIMAP\/offlineimap\/pull\/609\">here<\/a>.<\/p>\n<\/div>\n<div class=\"section\" id=\"debian-specific-operations\">\n<h3>Debian-specific&nbsp;operations<\/h3>\n<p>To make working with Debian packaging repositories easier, Silver Platter comes\nwith a wrapper (<tt class=\"docutils literal\"><span class=\"pre\">debian-svp<\/span><\/tt>) specifically for Debian&nbsp;packages.<\/p>\n<p>This wrapper allows specifying package names to refer to packaging branches; packaging\nURLs are retrieved from the <tt class=\"docutils literal\"><span class=\"pre\">Vcs-Git<\/span><\/tt> header in a package. For&nbsp;example:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span>$ debian-svp run ~\/fix-fsf-address.sh offlineimap\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>to fix the same issue in the offlineimap&nbsp;package.<\/p>\n<p>(Of course, you wouldn&#8217;t normally fix upstream issues like this in the Debian\npackage but forward them upstream&nbsp;instead)<\/p>\n<p>There is also a <tt class=\"docutils literal\"><span class=\"pre\">debian-svp<\/span> <span class=\"pre\">lintian-brush<\/span><\/tt> subcommand that will invoke\n<a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">lintian-brush<\/a> on a packaging&nbsp;branch.<\/p>\n<\/div>\n<div class=\"section\" id=\"supported-technologies\">\n<h3>Supported&nbsp;technologies<\/h3>\n<p>Silver-Platter currently supports the following hosting&nbsp;platforms:<\/p>\n<blockquote>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https:\/\/github.com\/\">GitHub<\/a><\/li>\n<li>GitLab instances (for example <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/\">Salsa<\/a> or <a class=\"reference external\" href=\"https:\/\/gitlab.gnome.org\/\"><span class=\"caps\">GNOME<\/span> gitlab<\/a>)<\/li>\n<li><a class=\"reference external\" href=\"https:\/\/https:\/\/launchpad.net\/\">Launchpad<\/a> (both Git and Bazaar repositories through <a class=\"reference external\" href=\"https:\/\/www.breezy-vcs.org\/\">Breezy<\/a>)<\/li>\n<\/ul>\n<\/blockquote>\n<p>It works in one of three&nbsp;modes:<\/p>\n<blockquote>\n<ul class=\"simple\">\n<li><em>propose<\/em>: Always create a pull request with the&nbsp;changes<\/li>\n<li><em>push<\/em>: Directly push changes back to the original&nbsp;branch<\/li>\n<li><em>attempt-push<\/em>: Attempt <em>push<\/em>, and fall back to <em>propose<\/em> if the current\nusers doesn&#8217;t have permissions to push to the repository or the&nbsp;branch.<\/li>\n<\/ul>\n<\/blockquote>\n<\/div>\n<div class=\"section\" id=\"installation\">\n<h3>Installation<\/h3>\n<p>There is a Silver Platter repository <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/silver-platter\">on GitHub<\/a>. Silver Platter is also available\nas a Debian package <a class=\"reference external\" href=\"https:\/\/packages.debian.org\/silver-platter\">in unstable<\/a> (not&nbsp;buster).<\/p>\n<\/div>\n<div class=\"section\" id=\"more-information\">\n<h3>More&nbsp;information<\/h3>\n<p>For a full list of <tt class=\"docutils literal\">svp<\/tt> subcommands, see <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/silver-platter\/blob\/master\/man\/svp.1\">svp(1)<\/a>.<\/p>\n<\/div>\n<\/div>\n","category":[{"@attributes":{"term":"silver-platter"}},{"@attributes":{"term":"vcs"}},{"@attributes":{"term":"breezy"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"lintian-brush"}}]},{"title":"Breezy\u00a0evolves","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/breezy-evolution.html","rel":"alternate"}},"published":"2019-03-24T16:00:00+00:00","updated":"2019-03-24T16:00:00+00:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2019-03-24:breezy-evolution.html","summary":"<p>Last month Martin, Vincent and I finally released version 3.0.0 of\n<a class=\"reference external\" href=\"https:\/\/www.breezy-vcs.org\/\">Breezy<\/a>, a little over a year after we\noriginally <a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/bazaar\/breezy-intro.html\">forked\nBazaar<\/a>.<\/p>\n<p>When we started working on Breezy, it was mostly as a way to keep Bazaar\nworking going forward - in a world where Python 2 has mostly disappeared\nin favour of Python&nbsp;3).<\/p>\n<div class=\"section\" id=\"improvements\">\n<h2>Improvements<\/h2>\n<p>Since then, we have also made other improvements. In addition to Python 3\nsupport, Breezy comes with the following other bigger&nbsp;changes:<\/p>\n<div class=\"section\" id=\"batteries-included\">\n<h3>Batteries&nbsp;Included<\/h3>\n<p>Breezy bundles most of the common plugins. This makes the installation of\nBreezy much simpler (<tt class=\"docutils literal\">pip install brz<\/tt>), and prevents possible issues with\n<span class=\"caps\">API<\/span> incompatibility that plagued&nbsp;Bazaar.<\/p>\n<p>Bundled plugins include: <tt class=\"docutils literal\">grep<\/tt>,  <tt class=\"docutils literal\">git<\/tt>, <tt class=\"docutils literal\">fastimport<\/tt>, <tt class=\"docutils literal\">propose<\/tt>,\n<tt class=\"docutils literal\">upload<\/tt>, <tt class=\"docutils literal\">stats<\/tt> and parts of <tt class=\"docutils literal\">bzrtools<\/tt>.<\/p>\n<\/div>\n<div class=\"section\" id=\"fixed-bugs\">\n<h3>&gt;120 fixed&nbsp;bugs<\/h3>\n<p>Since Bazaar 2.7, lots of bugs in the Bazaar code base have been fixed\n(over 120 as of March 2019). We&#8217;ve also started an effort to go through\nall bugs in the Bazaar bug tracker to see whether they also apply to&nbsp;Breezy.<\/p>\n<\/div>\n<div class=\"section\" id=\"native-git-support\">\n<h3>Native Git&nbsp;Support<\/h3>\n<p>Breezy now supports the Git file formats as a first class citizen; Git\nsupport is included in Breezy itself, and should work just as well\nas regular Bazaar format&nbsp;repositories.<\/p>\n<\/div>\n<div class=\"section\" id=\"improved-abstractions\">\n<h3>Improved&nbsp;abstractions<\/h3>\n<p>Bazaar has always had a higher level <span class=\"caps\">API<\/span> that could be used for version control\noperations, and which was implemented for both Bazaar, Git and Subversion&nbsp;formats.<\/p>\n<p>As part of the work to support the Git format natively, we have changed the\n<span class=\"caps\">API<\/span> to remove Bazaar-specific artefacts, like the use of file ids. Inventories\n(a Bazaar concept) are now also an implementation detail of the bzr formats,\nand not a concept that is visible in the <span class=\"caps\">API<\/span> or <span class=\"caps\">UI<\/span>.<\/p>\n<p>In the future, I hope the <span class=\"caps\">API<\/span> will be useful for tools that want to make\nautomated changes to any version controlled resource, whether that be\nGit, Bazaar, Subversion or Mercurial&nbsp;repositories.<\/p>\n<\/div>\n<\/div>\n","category":{"@attributes":{"term":"vcs"}}},{"title":"Lintian\u00a0Brush","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/lintian-brush-intro.html","rel":"alternate"}},"published":"2018-12-09T00:04:00+01:00","updated":"2018-12-09T00:04:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2018-12-09:lintian-brush-intro.html","summary":"<p>With Debian packages now widely being maintained in Git repositories, there has\nbeen an uptick in the number of bulk changes made to Debian packages. Several\nmaintainers are running commands over many packages (e.g. all packages owned by a\nspecific team) to fix common issues in&nbsp;packages.<\/p>\n<p>Examples of changes being made&nbsp;include:<\/p>\n<blockquote>\n<ul class=\"simple\">\n<li>Updating the <tt class=\"docutils literal\"><span class=\"pre\">Vcs-Git<\/span><\/tt> and <tt class=\"docutils literal\"><span class=\"pre\">Vcs-Browser<\/span><\/tt> URLs after migrating from alioth to&nbsp;salsa<\/li>\n<li>Stripping trailing whitespace in various control&nbsp;files<\/li>\n<li>Updating e.g. homepage URLs to use https rather than&nbsp;http<\/li>\n<\/ul>\n<\/blockquote>\n<p>Most of these can be fixed with simple sed or perl&nbsp;one-liners.<\/p>\n<p>Some of these scripts are publically available, for&nbsp;example:<\/p>\n<blockquote>\n<ul class=\"simple\">\n<li>The R packaging team&#8217;s <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/r-pkg-team\/maintenance-utilities\/blob\/master\/routine-update\">routine-update<\/a>,<\/li>\n<li>Ond\u0159ej Nov\u00fd&#8217;s <a class=\"reference external\" href=\"https:\/\/github.com\/onovy\/onovy-mass\/tree\/master\/checks\">onovy-mass<\/a>&nbsp;repository.<\/li>\n<\/ul>\n<\/blockquote>\n<div class=\"section\" id=\"lintian-brush-1\">\n<h2>Lintian-Brush<\/h2>\n<p>Lintian-Brush is both a simple wrapper around a set of these kinds of scripts\nand a repository for these scripts, with the goal of making it easy for any Debian\nmaintainer to run&nbsp;them.<\/p>\n<p>The lintian-brush command-line tool is a simple wrapper that runs a set of\n&#8220;fixer scripts&#8221;, and for&nbsp;each:<\/p>\n<blockquote>\n<ul class=\"simple\">\n<li>Reverts the changes made by the script if it failed with an&nbsp;error<\/li>\n<li>Commits the changes to the <span class=\"caps\">VCS<\/span> with an appropriate commit&nbsp;message<\/li>\n<li>Adds a changelog entry (if&nbsp;desired)<\/li>\n<\/ul>\n<\/blockquote>\n<p>The tool also provides some basic infrastructure for testing that these scripts\ndo what they should, and e.g. don&#8217;t have unintended&nbsp;side-effects.<\/p>\n<p>The idea is that it should be safe, quick and unobtrusive to run <tt class=\"docutils literal\"><span class=\"pre\">lintian-brush<\/span><\/tt>,\nand get it to opportunistically fix lintian issues and to leave the source tree\nalone when it&nbsp;can&#8217;t.<\/p>\n<div class=\"section\" id=\"example\">\n<h3>Example<\/h3>\n<p>For example, running lintian-brush on the package <tt class=\"docutils literal\">talloc<\/tt> fixes two minor lintian&nbsp;issues:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"gp\"> % <\/span>debcheckout<span class=\"w\"> <\/span>talloc\n<span class=\"go\"> declared git repository at https:\/\/salsa.debian.org\/samba-team\/talloc.git<\/span>\n<span class=\"go\"> git clone https:\/\/salsa.debian.org\/samba-team\/talloc.git talloc ...<\/span>\n<span class=\"go\"> Cloning into &#39;talloc&#39;...<\/span>\n<span class=\"go\"> remote: Enumerating objects: 2702, done.<\/span>\n<span class=\"go\"> remote: Counting objects: 100% (2702\/2702), done.<\/span>\n<span class=\"go\"> remote: Compressing objects: 100% (996\/996), done.<\/span>\n<span class=\"go\"> remote: Total 2702 (delta 1627), reused 2601 (delta 1550)<\/span>\n<span class=\"go\"> Receiving objects: 100% (2702\/2702), 1.70 MiB | 565.00 KiB\/s, done.<\/span>\n<span class=\"go\"> Resolving deltas: 100% (1627\/1627), done.<\/span>\n<span class=\"gp\"> % <\/span><span class=\"nb\">cd<\/span><span class=\"w\"> <\/span>talloc\n<span class=\"go\"> talloc% lintian-brush<\/span>\n<span class=\"go\"> Lintian tags fixed: {&#39;insecure-copyright-format-uri&#39;, &#39;public-upstream-key-not-minimal&#39;}<\/span>\n<span class=\"gp\"> % <\/span>git<span class=\"w\"> <\/span>log\n<span class=\"go\"> commit 0ea35f4bb76f6bca3132a9506189ef7531e5c680 (HEAD -&gt; master)<\/span>\n<span class=\"go\"> Author: Jelmer Vernoo\u0133 &lt;jelmer@debian.org&gt;<\/span>\n<span class=\"go\"> Date:   Tue Dec 4 16:42:35 2018 +0000<\/span>\n\n<span class=\"go\">     Re-export upstream signing key without extra signatures.<\/span>\n\n<span class=\"go\">     Fixes lintian: public-upstream-key-not-minimal<\/span>\n<span class=\"go\">     See https:\/\/lintian.debian.org\/tags\/public-upstream-key-not-minimal.html for more details.<\/span>\n\n<span class=\"go\">  debian\/changelog                |   1 +<\/span>\n<span class=\"go\">  debian\/upstream\/signing-key.asc | 102 +++++++++++++++---------------------------------------------------------------------------------------<\/span>\n<span class=\"go\">  2 files changed, 16 insertions(+), 87 deletions(-)<\/span>\n\n<span class=\"go\"> commit feebce3147df561aa51a385c53d8759b4520c67f<\/span>\n<span class=\"go\"> Author: Jelmer Vernoo\u0133 &lt;jelmer@debian.org&gt;<\/span>\n<span class=\"go\"> Date:   Tue Dec 4 16:42:28 2018 +0000<\/span>\n\n<span class=\"go\">     Use secure copyright file specification URI.<\/span>\n\n<span class=\"go\">     Fixes lintian: insecure-copyright-format-uri<\/span>\n<span class=\"go\">     See https:\/\/lintian.debian.org\/tags\/insecure-copyright-format-uri.html for more details.<\/span>\n\n<span class=\"go\">  debian\/changelog | 3 +++<\/span>\n<span class=\"go\">  debian\/copyright | 2 +-<\/span>\n<span class=\"go\">  2 files changed, 4 insertions(+), 1 deletion(-)<\/span>\n<\/pre><\/div>\n<\/div>\n<div class=\"section\" id=\"script-interface\">\n<h3>Script&nbsp;Interface<\/h3>\n<p>A fixer script is run in the root directory of a package, where it can make\nchanges it deems necessary, and write a summary of what it&#8217;s done for the changelog\n(and commit message) to standard&nbsp;out.<\/p>\n<p>If a fixer can not provide any improvements, it can simply leave the working\ntree untouched - lintian-brush will not create any commits for it or update the\nchangelog. If it exits with a non-zero exit code, then it is assumed that it\nfailed to run and it will be listed as such and its changes reset rather than&nbsp;committed.<\/p>\n<p>In addition, tests can be added for fixers by providing various <tt class=\"docutils literal\">before<\/tt> and\n<tt class=\"docutils literal\">after<\/tt> source package trees, to verify that a fixer script makes the expected&nbsp;changes.<\/p>\n<p>For more details, see the <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush#writing-fixers\">documentation on writing new fixers<\/a>.<\/p>\n<\/div>\n<div class=\"section\" id=\"availability\">\n<h3>Availability<\/h3>\n<p><tt class=\"docutils literal\"><span class=\"pre\">lintian-brush<\/span><\/tt> is currently available in <em>unstable<\/em> and <em>testing<\/em>. See man\n<tt class=\"docutils literal\"><span class=\"pre\">lintian-brush(1)<\/span><\/tt> for an explanation of the command-line&nbsp;options.<\/p>\n<p>Fixer scripts are included that can fix (some of the instances of) <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush#supported-tags\">34 lintian\ntags<\/a>.<\/p>\n<p>Feedback would be great if you try <em>lintian-brush<\/em> - please file bugs in the <span class=\"caps\">BTS<\/span>, or propose\npull requests with new fixers <a class=\"reference external\" href=\"https:\/\/salsa.debian.org\/jelmer\/lintian-brush\">on salsa<\/a>.<\/p>\n<\/div>\n<\/div>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"vcs"}}]},{"title":"Breezy: Forking\u00a0Bazaar","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/breezy-intro.html","rel":"alternate"}},"published":"2018-01-08T17:00:00+01:00","updated":"2018-01-08T17:00:00+01:00","author":{"name":"Jelmer Vernooj"},"id":"tag:www.jelmer.uk,2018-01-08:breezy-intro.html","summary":"<p>A couple of months ago, Martin and I announced a friendly fork of Bazaar, named <a class=\"reference external\" href=\"https:\/\/www.breezy-vcs.org\/\">Breezy<\/a>.<\/p>\n<p>It&#8217;s been 5 years since I wrote a <a class=\"reference external\" href=\"\/pages\/bzr-a-retrospective.html\">Bazaar retrospective<\/a> and around\n6 since I seriously contributed to the Bazaar&nbsp;codebase.<\/p>\n<div class=\"section\" id=\"goals\">\n<h2>Goals<\/h2>\n<p>We don&#8217;t have any grand ambitions for Breezy; the main goal is to keep Bazaar\nusable going forward. Your open source projects should <a class=\"reference external\" href=\"\/pages\/bzr-a-retrospective.html#conclusion\">still be using Git<\/a>.<\/p>\n<p>The main changes we have made so far come down to fixing a number of bugs and\nto bundling useful plugins. Bundling plugins makes setting up an environment\nsimpler and to eliminate the <span class=\"caps\">API<\/span> compatibility issues that plagued external\nplugins in the Bazaar&nbsp;world.<\/p>\n<p>Perhaps the biggest effort in Breezy is porting the codebase to Python 3, allowing\nit to be used once Python 2 goes <span class=\"caps\">EOL<\/span> in&nbsp;2020.<\/p>\n<!-- One of my hopes is also to see if we can get `bzr-git`_ into a state where it -->\n<!-- functions well enough that it can be merged into Breezy and provide native, -->\n<!-- reasonably performant Git support. -->\n<\/div>\n<div class=\"section\" id=\"a-fork\">\n<h2>A&nbsp;fork<\/h2>\n<p>Breezy is a fork of Bazaar and not just a new release&nbsp;series.<\/p>\n<p>Bazaar upstream has been dormant for the last couple of years anyway - we don&#8217;t\nlose anything by&nbsp;forking.<\/p>\n<p>We&#8217;re forking because gives us the independence to make some of\nthe changes we deemed necessary and that are otherwise hard to make for\nan established project, For example, we&#8217;re now bundling plugins, taking an axe\nto a large number of APIs and dropping support for older&nbsp;platforms.<\/p>\n<p>A fork also means independence from Canonical; there is no <span class=\"caps\">CLA<\/span> for\nBreezy (a hindrance for Bazaar) and we can set up our own infrastructure\nwithout having to chase down Canonical staff for web site updates or the\ninstallation of new packages on the <span class=\"caps\">CI<\/span>&nbsp;system.<\/p>\n<\/div>\n<div class=\"section\" id=\"more-information\">\n<h2>More&nbsp;information<\/h2>\n<p>Martin gave <a class=\"reference external\" href=\"https:\/\/www.youtube.com\/watch?v=9vtToynsNSs\">a talk<\/a> about Breezy at PyCon <span class=\"caps\">UK<\/span> this&nbsp;year.<\/p>\n<p>Breezy bugs can be filed <a class=\"reference external\" href=\"https:\/\/launchpad.net\/brz\">on Launchpad<\/a>. For the moment, we are using the\n<a class=\"reference external\" href=\"https:\/\/lists.canonical.com\/archives\/bazaar\/\">Bazaar mailing list<\/a> and the <tt class=\"docutils literal\">#bzr<\/tt>\n<span class=\"caps\">IRC<\/span> channel for any discussions and status updates around&nbsp;Breezy.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"breezy"}}]},{"title":"Xandikos, a lightweight Git-backed CalDAV\/CardDAV\u00a0server","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/xandikos-intro.html","rel":"alternate"}},"published":"2017-05-06T03:06:23+02:00","updated":"2017-05-06T03:06:23+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.jelmer.uk,2017-05-06:xandikos-intro.html","summary":"<p>For the last couple of years, I have self-hosted my calendar and address book\ndata. Originally I just kept local calendars and address books in Evolution,\nbut later I moved to a self-hosted CalDAV\/CardDAV server and a plethora of&nbsp;clients.<\/p>\n<div class=\"section\" id=\"caldav-carddav\">\n<h2>CalDAV\/CardDAV<\/h2>\n<p>CalDAV and CardDAV are standards for accessing, managing, and sharing\ncalendaring and addressbook information based on the iCalendar format that are\nbuilt atop the WebDAV standard, and WebDAV itself is a set of extensions to\n<span class=\"caps\">HTTP<\/span>.<\/p>\n<p>CalDAV and CardDAV essentially store iCalendar (.ics) and vCard (.vcf) files\nusing WebDAV, but they provide some extra guarantees (e.g. files must be\nwell-formed) and some additional methods for querying the data. For example,\nit is possible to retrieve all events between two dates with a single <span class=\"caps\">HTTP<\/span>\nquery, rather than the client having to check all the calendar files in a&nbsp;directory.<\/p>\n<p>CalDAV and CardDAV are (unnecessarily) complex, in large part because they are\nbuilt on top of WebDAV. Being able to use regular <span class=\"caps\">HTTP<\/span> and WebDAV clients\nis quite neat, but results in extra complexity. In addition, because the\nstandards are so large, clients and servers end up only implementing parts of&nbsp;it.<\/p>\n<p>However, CalDAV and CardDAV have one big redeeming quality: they are the\ndominant standards for synchronising calendar events and addressbooks, and are\nsupported by a wide variety of free and non-free applications. They&#8217;re the\nstatus quo, until something better comes along. (and hey, at least there is a\nstandard to begin&nbsp;with)<\/p>\n<\/div>\n<div class=\"section\" id=\"calypso\">\n<h2>Calypso<\/h2>\n<p>I have tried a number of servers over the years. In the end, I settled for\n<a class=\"reference external\" href=\"https:\/\/keithp.com\/blogs\/calypso\/\">calypso<\/a>.<\/p>\n<p>Calypso started out as friendly fork of <a class=\"reference external\" href=\"http:\/\/radicale.org\/\">Radicale<\/a>, with some additional\nimprovements. I like Calypso because it&nbsp;is:<\/p>\n<ul class=\"simple\">\n<li>quite simple, understandable, and small (sloccount reports 1700 <span class=\"caps\">LOC<\/span>)<\/li>\n<li>it stores plain .vcf and .ics&nbsp;files<\/li>\n<li>stores history in&nbsp;git<\/li>\n<li>easy to set up, e.g. no database&nbsp;dependencies<\/li>\n<li>written in&nbsp;Python<\/li>\n<\/ul>\n<p>Its use of regular files and keeping history in Git is useful, because this\nmeans that whenever it breaks it is much easier to see what is happening. If\nsomething were to go wrong (i.e. a client decides to remove all\nserver-side entries) it&#8217;s easy to recover by rolling back history using&nbsp;git.<\/p>\n<p>However, there are some downsides to Calypso as&nbsp;well.<\/p>\n<p>It doesn&#8217;t have good test coverage, making it harder to change (especially\nin a way that doesn&#8217;t break some clients), though there are some recent efforts\nto make e.g. external spec compliance tests like <a class=\"reference external\" href=\"https:\/\/www.calendarserver.org\/CalDAVTester.html\">caldavtester<\/a> work with&nbsp;it.<\/p>\n<p>Calypso&#8217;s CalDAV\/CardDAV\/WebDAV implementation is a bit ad-hoc. The only WebDAV\nREPORTs it implements are calendar-multiget and addressbook-multiget. Support\nfor properties has been added as new clients request them. The logic for replying\nto <span class=\"caps\">DAV<\/span> requests is mixed with the actual data store&nbsp;implementation.<\/p>\n<p>Because of this, it can be hard to get going with some clients and sometimes\ntricky to&nbsp;debug.<\/p>\n<\/div>\n<div class=\"section\" id=\"xandikos\">\n<h2>Xandikos<\/h2>\n<p>After attempting to fix a number of issues in Calypso, I kept running into\nissues with the way its code is structured. This is only fixable by rewriting\nsigifnicant chunks of it, so I opted to instead write a new&nbsp;server.<\/p>\n<p>The goals of <a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/xandikos\/\">Xandikos<\/a> are along the same lines as those of Calypso, to be a\nsimple CalDAV\/CardDAV server for personal&nbsp;use:<\/p>\n<ul class=\"simple\">\n<li>easy to set up; at the moment, just running\n<cite>xandikos -d $<span class=\"caps\">HOME<\/span>\/dav &#8212;defaults<\/cite> is enough to start a new&nbsp;server<\/li>\n<li>use of plain .ics\/.ivf files for&nbsp;storage<\/li>\n<li>history stored in&nbsp;Git<\/li>\n<\/ul>\n<p>But&nbsp;additionally:<\/p>\n<ul class=\"simple\">\n<li>clear separation between protocol implementation and&nbsp;storage<\/li>\n<li>be well&nbsp;tested<\/li>\n<li>standards&nbsp;complete<\/li>\n<li>standards&nbsp;compliant<\/li>\n<\/ul>\n<\/div>\n<div class=\"section\" id=\"current-status\">\n<h2>Current&nbsp;status<\/h2>\n<p>The CalDAV\/CardDAV implementation of Xandikos is mostly complete, but there\nstill a number of <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/xandikos\/issues\">outstanding issues<\/a>.<\/p>\n<p>In&nbsp;particular:<\/p>\n<ul class=\"simple\">\n<li>lack of authentication support; setting up authentication support in uwsgi or a reverse proxy is one way of working around&nbsp;this<\/li>\n<li>there is no useful <span class=\"caps\">UI<\/span> for users accessing the <span class=\"caps\">DAV<\/span> resources via a web&nbsp;browser<\/li>\n<li>test&nbsp;coverage<\/li>\n<\/ul>\n<p>Xandikos has been tested with the following&nbsp;clients:<\/p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https:\/\/github.com\/pimutils\/vdirsyncer\">Vdirsyncer<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/www.inf-it.com\/open-source\/clients\/caldavzap\/\">caldavzap<\/a>\/<a class=\"reference external\" href=\"https:\/\/www.inf-it.com\/open-source\/clients\/carddavmate\/\">carddavmate<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/wiki.gnome.org\/Apps\/Evolution\">evolution<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/davdroid.bitfire.at\/\">DAVdroid<\/a><\/li>\n<li><a class=\"reference external\" href=\"http:\/\/v2.sogo.nu\/english\/downloads\/frontends.html\">sogo connector for&nbsp;Icedove\/Thunderbird<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/play.google.com\/store\/apps\/details?id=de.we.acaldav&amp;hl=en\">aCALdav syncer for&nbsp;Android<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/github.com\/geier\/pycarddav\">pycardsyncer<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/community.kde.org\/KDE_PIM\/Akonadi\">akonadi<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/dmfs.org\/caldav\/\">CalDAV-Sync<\/a><\/li>\n<li><a class=\"reference external\" href=\"https:\/\/dmfs.org\/carddav\/\">CardDAV-Sync<\/a><\/li>\n<\/ul>\n<\/div>\n<div class=\"section\" id=\"trying-it\">\n<h2>Trying&nbsp;it<\/h2>\n<p>To run Xandikos, follow the instructions on the <a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/projects\/xandikos\/\">homepage<\/a>:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span>.\/bin\/xandikos --defaults -d $HOME\/dav\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>A server should now be listening on <a class=\"reference external\" href=\"http:\/\/localhost:8080\/\">localhost:8080<\/a>\nthat you can access with your favorite&nbsp;client.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"caldav"}},{"@attributes":{"term":"carddav"}},{"@attributes":{"term":"webdav"}}]},{"title":"The Samba\u00a0Buildfarm","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/samba-buildfarm-history.html","rel":"alternate"}},"published":"2015-02-08T01:06:23+01:00","updated":"2015-02-08T01:06:23+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2015-02-08:samba-buildfarm-history.html","summary":"<p>Portability has always been very important to Samba.\nNowadays Samba is mostly used on top of Linux, but Tridge developed\nthe <a class=\"reference external\" href=\"http:\/\/www.rxn.com\/services\/faq\/smb\/samba.history.txt\">early versions<\/a> of his <span class=\"caps\">SMB<\/span> implementation on a Sun&nbsp;workstation.<\/p>\n<p>A few years later, when the project was being picked up, it was ported to Linux\nand eventually to a large number of other free and non-free Unix-like operating&nbsp;systems.<\/p>\n<p>Initially regression testing on different platforms was done manually and&nbsp;ad-hoc.<\/p>\n<p>Once Samba had support for a larger number of platforms, including numerous\nvariations and optional dependencies, making sure that it would still build\nand run on all of these became a non-trivial&nbsp;process.<\/p>\n<p>To make it easier to find regressions in the Samba codebase that were\nplatform-specific, tridge put together a system to automatically build\nSamba regularly on as many platforms as possible. So, in Spring 2001, the build\nfarm was born - this was a couple of years before other tools like buildbot came&nbsp;around.<\/p>\n<div class=\"section\" id=\"the-build-farm\">\n<h2>The Build&nbsp;Farm<\/h2>\n<p>The build farm is a collection of machines around the world that are\nconnected to the internet, with as wide a variety of platforms as possible. In 2001,\nit wasn&#8217;t feasible to just have a single beefy machine or a cloud account on which\nwe could run virtual machines with <span class=\"caps\">AIX<\/span>, <span class=\"caps\">HPUX<\/span>, Tru64, Solaris and Linux so we needed\naccess to physical&nbsp;hardware.<\/p>\n<p>The build farm runs as a single non-privileged user, which has a cron job set up that\nruns the build farm worker script regularly. Originally the frequency was every\ncouple of hours, but soon we asked machine owners to run it as often as\npossible. The <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/build-farm\/blob\/master\/build_test\">worker script<\/a> is as short as it is simple. It retrieves a\nshell script from the main build farm repository with instructions to run and\nafter it has done so, it uploads a log file of the terminal output to\n<tt class=\"docutils literal\">samba.org<\/tt> using rsync and a secret per-machine&nbsp;password.<\/p>\n<p>Some build farm machines are dedicated, but there have also been a large number of the\nyears that would just run as a separate user account on a machine that was tasked with\nsomething else. Most build farm machines are hosted by Samba developers (or their employers)\nbut we&#8217;ve also had a number of community volunteers over the years that were happy to add\nan extra user with an extra cron job on their machine and for a while companies like\nSourceForge and <span class=\"caps\">HP<\/span> provided dedicated porter boxes that ran the build&nbsp;farm.<\/p>\n<p>Of course, there are some security usses with this way of running things.\nArbitrary shell code is downloaded from a host claiming to be samba.org and\nrun. If the machine is shared with other (sensitive) processes, some of the\ninformation about those processes might leak into&nbsp;logs.<\/p>\n<p>Our web page has a section about <a class=\"reference external\" href=\"https:\/\/build.samba.org\/build.cgi\/instructions\">adding machines<\/a> for new volunteers, with a\nlong list of&nbsp;warnings.<\/p>\n<p>Since then, various other people have been involved in the build farm. Andrew\nBartlett started contributing to the build farm in July 2001, working on\nadding tests. He gradually took over as the maintainer in 2002, and various\nothers (Vance, Martin, Mathieu) have contributed patches and helped out with\ngeneral&nbsp;admin.<\/p>\n<p>In 2005, tridge added a script to automatically send out an e-mail to the\ncommitter of the last revision before a failed build. This meant it\nwas no longer necessary to bisect through build farm logs on the web to find\nout who had broken a specific platform when; you&#8217;d just be notified as soon as it&nbsp;happened.<\/p>\n<\/div>\n<div class=\"section\" id=\"the-web-site\">\n<h2>The web&nbsp;site<\/h2>\n<p>Once the logs are generated and uploaded to samba.org using <tt class=\"docutils literal\">rsync<\/tt>, the\nweb site at <a class=\"reference external\" href=\"http:\/\/build.samba.org\/\">http:\/\/build.samba.org\/<\/a> is responsible for making\nthem accessible to the world. Initially there was a single perl file that would take\ncare of listing and displaying log files, but over the years the functionality has been\nextended to do much more than&nbsp;that.<\/p>\n<p>Initial extensions to the build farm added support for viewing per-compiler and per-host\nbuilds, to allow spotting trends. Another addition was searching logs for common\nindicators of running out of disk&nbsp;space.<\/p>\n<p>Over time, we also added more samba.org-projects to the build farm. At the moment\nthere are about a dozen&nbsp;projects.<\/p>\n<p>In a sprint in 2009, Andrew Bartlett and I changed the build farm to store\nmachine and build metadata in a SQLite database rather than parsing all recent\nbuild log files every time their results were&nbsp;needed.<\/p>\n<p>In a follow-up sprint a year later, we converted most of the code to Python.\nWe also added a number of extensions; most notably, linking the build result\ninformation with version control information so we could automatically email\nthe exact people that had caused the build breakage, and automatically notifying\nbuild farm owners when their machines were not&nbsp;functioning.<\/p>\n<\/div>\n<div class=\"section\" id=\"autobuild\">\n<h2>autobuild<\/h2>\n<p>Sometime in 2011 all committers started using the <tt class=\"docutils literal\">autobuild<\/tt> script to push changes\nto the master Samba branch. This script enforces a full build and testsuite run for\neach commit that is pushed. If the build or any part of the testsuite fails,\nthe push is aborted. This alone massively reduced the number of problematic changes\nthat was pushed, making it less necessary for us to be made aware of issues by\nthe build&nbsp;farm.<\/p>\n<p>The rewrite also introduced some time bombs into the code. The way we called out to\nour <a class=\"reference external\" href=\"http:\/\/storm.canonical.com\/\"><span class=\"caps\">ORM<\/span><\/a> caused the code to fetch all build summary data from the database every\ntime the summary page was generated. Initially this was not a problem, but as\nthe table grew to 100,000 rows, the build farm became so slow that it was\nfrustrating to&nbsp;use.<\/p>\n<\/div>\n<div class=\"section\" id=\"analysis-tools\">\n<h2>Analysis&nbsp;tools<\/h2>\n<p>Over the years, various special build farm machines have also been used to run\nextra code analysis tools, like static code analysis, lcov, valgrind or\nvarious code quality&nbsp;scanners.<\/p>\n<\/div>\n<div class=\"section\" id=\"summer-of-code\">\n<h2>Summer of&nbsp;Code<\/h2>\n<p>Of the last couple of years the build farm has been running happily, and hasn&#8217;t\nchanged&nbsp;much.<\/p>\n<p>This summer one of our summer of code students, Krishna Teja Perannagari,\nworked on improving the look of the build farm - updating it to the current\nSamba house style - as well as various performance improvements in the Python&nbsp;code.<\/p>\n<\/div>\n<div class=\"section\" id=\"jenkins\">\n<h2>Jenkins?<\/h2>\n<p>The build farm still works reasonably well, though it is clear that\nvarious other tools that have had more developer attention have caught up with\nit. If we would have to reinvent the build farm today, we would probably end\nup using an off-the-shelve tool like Jenkins that wasn&#8217;t around 14 years ago.\nWe would also be able to get away with using virtual machines for most of our&nbsp;workers.<\/p>\n<p>Non-Linux platforms have become less relevant in the last couple of years,\nthough we still care about&nbsp;them.<\/p>\n<p>The build farm in its current form works well enough for us, and I\nthink porting to Jenkins - with the same level of platform coverage - would\ntake quite a lot of work and have only limited&nbsp;benefits.<\/p>\n<p>(Thanks to <a class=\"reference external\" href=\"https:\/\/samba.org\/~abartlet\/\">Andrew Bartlett<\/a> for proofreading the draft of this&nbsp;post.)<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"buildfarm"}},{"@attributes":{"term":"jenkins"}},{"@attributes":{"term":"buildbot"}},{"@attributes":{"term":"testing"}},{"@attributes":{"term":"nostalgia"}}]},{"title":"Autonomous Shard Distributed\u00a0Databases","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/autonomous-shard-distributed-databases.html","rel":"alternate"}},"published":"2014-08-22T20:00:00+02:00","updated":"2014-08-22T20:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2014-08-22:autonomous-shard-distributed-databases.html","summary":"<p>Distributed databases are hard. Distributed databases where you don&#8217;t have\nfull control over what shards run which version of your software are even\nharder, because it becomes near impossible to deal with fallout when things go\nwrong. For lack of a better term (is there one?), I&#8217;ll refer to these databases\nas Autonomous Shard Distributed&nbsp;Databases.<\/p>\n<p>Distributed version control systems are an excellent example of such databases.\nThey store file revisions and commit metadata in shards (&#8220;repositories&#8221;)\ncontrolled by different&nbsp;people.<\/p>\n<p>Because of the nature of these systems, it is hard to weed out corrupt data\nif all shards ignorantly propagate broken data. There will be different people\non different platforms running the database software that manages the\nindividual&nbsp;shards.<\/p>\n<p>This makes it hard - if not impossible - to deploy software updates to all\nshards of a database in a reasonable amount of time (though a Chrome-like\nupdate mechanism might help here, if that was acceptable). This has\nconsequences for the way in which you have to deal with every change to the\ndatabase format and&nbsp;model.<\/p>\n<p>(e.g. imagine introducing a modification to the Linux kernel Git repository that\nrequired everybody to install a new version of&nbsp;Git).<\/p>\n<p>Defensive programming and a good format design from the start are&nbsp;essential.<\/p>\n<p>Git and its database format do really well in all of these regards. As I wrote <a class=\"reference external\" href=\"https:\/\/www.jelmer.uk\/pages\/bzr-a-restrospective.html\">in my\nretrospective<\/a>, Bazaar has made a number of mistakes in this area, and that\nwas a major source of user&nbsp;frustration.<\/p>\n<p>I propose that every autonomous shard distributed databases should aim for the&nbsp;following:<\/p>\n<blockquote>\n<ul>\n<li><p class=\"first\">For the &#8220;base&#8221; format, keep it as simple as you possibly can. (<span class=\"caps\">KISS<\/span>)<\/p>\n<p>The simpler the format, the smaller the chance of mistakes in the design\nthat have to be corrected later. Similarly, it reduces the chances\nof mistakes in any&nbsp;implementation(s).<\/p>\n<p>In particular, there is no need for every piece of metadata to be\na part of the core database&nbsp;format.<\/p>\n<p>(in the case of Git, I would argue that e.g. &#8220;author&#8221; might as well be a&nbsp;&#8220;meta-header&#8221;)<\/p>\n<\/li>\n<li><p class=\"first\">Corruption should be detected early and not propagated. This means\nthere should be good tools to sanity check a database, and ideally\nsome of these checks should be run automatically during everyday operations\n- e.g. when pushing changes to others or receiving&nbsp;them.<\/p>\n<\/li>\n<li><p class=\"first\">If corruption does occur, there should be a way for as much of the database\nas possible to be&nbsp;recovered.<\/p>\n<p>A couple of corrupt objects should not render the entire database&nbsp;unusable.<\/p>\n<p>There should be tools for low-level access of the database, but\nthe format and structure should be also documented well enough for power users to\nunderstand it, examine and extract&nbsp;data.<\/p>\n<\/li>\n<li><p class=\"first\">No &#8220;hard&#8221; format changes (where clients \/have\/ to upgrade to access the new&nbsp;format).<\/p>\n<p>Not all users will instantly update to the latest and greatest version of the\nsoftware.  The lifecycle of enterprise Linux distributions is long enough\nthat it might take three or four years for the majority of users to&nbsp;upgrade.<\/p>\n<\/li>\n<li><p class=\"first\">Keep performance data like indexes in separate files. This makes it possible for\nolder software to still read the data, albeit at a slower pace, and\/or generate\nolder format index&nbsp;files.<\/p>\n<\/li>\n<li><p class=\"first\">New shards of the database should replicate the entire database if at all possible;\nhaving more copies of the data can&#8217;t hurt if other shards go away or\nget&nbsp;corrupted.<\/p>\n<p>Having the data locally available also means users get quicker access to\nmore&nbsp;data.<\/p>\n<\/li>\n<li><p class=\"first\">Extensions to the database format that require hard format changes (think\ne.g. submodules) should only impact databases that actually use those&nbsp;extensions.<\/p>\n<\/li>\n<li><p class=\"first\">Leave some room for structured arbitrary metadata, which gets propagated but\nthat not all clients need to be able to understand and can safely&nbsp;ignore.<\/p>\n<p>(think fields like &#8220;Signed-Off-By&#8221;, &#8220;Reviewed-By&#8221;, &#8220;Fixes-Bug&#8221;, etc) in\ngit commit metadata headers, or the revision metadata fields in&nbsp;Bazaar.<\/p>\n<\/li>\n<\/ul>\n<\/blockquote>\n","category":[{"@attributes":{"term":"dvcs"}},{"@attributes":{"term":"databases"}},{"@attributes":{"term":"sharding"}},{"@attributes":{"term":"dbts"}}]},{"title":"Using Propellor for configuration\u00a0management","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/propellor.html","rel":"alternate"}},"published":"2014-08-18T23:15:00+02:00","updated":"2014-08-18T23:15:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2014-08-18:propellor.html","summary":"<p>For a while, I&#8217;ve been wanting to set up configuration management for my home network.\nWith half a dozen servers, a <span class=\"caps\">VPS<\/span> and a workstation it is not big, but large\nenough to make it annoying to manually log into each machine for network-wide&nbsp;changes.<\/p>\n<p>Most of the servers I have are low-end <span class=\"caps\">ARM<\/span> machines, each responsible for a\ncouple of tasks. Most of my machines run Debian or something derived from Debian.\nOh, and I&#8217;m a member of the declarative school of configuration&nbsp;management.<\/p>\n<div class=\"section\" id=\"propellor\">\n<h2>Propellor<\/h2>\n<p><a class=\"reference external\" href=\"http:\/\/joeyh.name\/blog\/entry\/propellor\/\">Propellor<\/a> caught my eye earlier this year. Unlike some other configuration\nmanagement tools, it doesn&#8217;t come with its own custom language but it is\nwritten in Haskell, which I am already familiar with. It&#8217;s also fairly simple,\ndeclarative, and seems to do most of the handful of things that I&nbsp;need.<\/p>\n<p>Propellor is essentially a Haskell application that you customize for your site.\nIt works very similar to e.g. xmonad, where you write a bit of Haskell code\nfor configuration which uses the upstream library code. When you run the\napplication it takes your code and builds a binary from your code and\nthe upstream&nbsp;libraries.<\/p>\n<p>Each host on which Propellor is used keeps a clone of the site-local Propellor git\nrepository in <tt class=\"docutils literal\">\/usr\/local\/propellor<\/tt>. Every time propellor runs\n(either because of a manual &#8220;spin&#8221;, or from a cronjob it can set up for you), it\nfetches updates from the main site-local git repository, compiles the Haskell\napplication and runs&nbsp;it.<\/p>\n<\/div>\n<div class=\"section\" id=\"setup\">\n<h2>Setup<\/h2>\n<p>Propellor was surprisingly easy to set up. Running <tt class=\"docutils literal\">propellor<\/tt>\ncreates a clone of the upstream repository under <tt class=\"docutils literal\"><span class=\"pre\">~\/.propellor<\/span><\/tt> with a <span class=\"caps\">README<\/span>\nfile and some example configuration. I copied <tt class=\"docutils literal\"><span class=\"pre\">config-simple.hs<\/span><\/tt> to\n<tt class=\"docutils literal\">config.hs<\/tt>, updated it to reflect one of my hosts and within a few minutes I\nhad a basic working propellor&nbsp;setup.<\/p>\n<p>You can use <tt class=\"docutils literal\">.\/propellor &lt;host&gt;<\/tt> to trigger a run on a remote&nbsp;host.<\/p>\n<p>At the moment I have propellor working for some basic things -\nhaving certain Debian packages installed, a specific network configuration, mail\nsetup, basic Kerberos configuration and certain <span class=\"caps\">SSH<\/span> options set.\nThis took surprisingly little time to set up, and it&#8217;s been great being able\nto take full advantage of&nbsp;Haskell.<\/p>\n<p>Propellor comes with convenience functions for dealing with some commonly used\npackages, such as Apt, <span class=\"caps\">SSH<\/span> and Postfix. For a lot of the other packages, you&#8217;ll\nhave to roll your own for now. I&#8217;ve written some extra code to make Propellor deal\nwith Kerberos keytabs and Dovecot, which I hope to submit&nbsp;upstream.<\/p>\n<p>I don&#8217;t have a lot of experience with other Free Software configuration\nmanagement tools such as Puppet and Chef, but for my use case Propellor works\nvery&nbsp;well.<\/p>\n<p>The main disadvantage of propellor for me so far is that it needs to build\nitself on each machine it runs on. This is fine for my workstation and\nhigh-end servers, but it is somewhat more problematic on e.g. my Raspberry Pi&#8217;s.\nCompilation takes a while, and the Haskell compiler and libraries it needs amount\nto 500Mb worth of disk space on the tiny root&nbsp;partition.<\/p>\n<p>In order to work with Propellor, some Haskell knowledge is required.\nThe Haskell in the configuration file is reasonably easy to understand if you\nkeep it simple, but once the compiler spits out error messages then I suspect\nyou&#8217;ll have a hard time without any Haskell&nbsp;knowledge.<\/p>\n<p>Propellor relies on having a central repository with the configuration that it\ncan pull from as root. Unlike Joey, I am wary of publishing the configuration\nof my home network and I don&#8217;t have a highly available local git server&nbsp;setup.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"haskell"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"sysadmin"}}]},{"title":"The state of distributed bug\u00a0trackers","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/distributed-bug-trackers.html","rel":"alternate"}},"published":"2013-11-10T19:23:00+01:00","updated":"2013-11-10T19:23:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2013-11-10:distributed-bug-trackers.html","summary":"<p>A whopping 5 years ago, <span class=\"caps\">LWN<\/span> ran <a class=\"reference external\" href=\"https:\/\/lwn.net\/Articles\/281849\/\">a story<\/a> about distributed bug trackers. This\nwas during the early waves of distributed version control adoption, and so\neverybody was looking for other things that could benefit from&nbsp;decentralization.<\/p>\n<p><span class=\"caps\">TL<\/span>;<span class=\"caps\">DR<\/span>: Not much has changed&nbsp;since.<\/p>\n<p>The potential benefits of a distributed bug tracker are similar to those of\na distributed version control system: ability to fork any arbitrary project,\neasier collaboration between related projects and offline access to full project&nbsp;data.<\/p>\n<p>The article discussed a number of systems, including <a class=\"reference external\" href=\"http:\/\/www.bugseverywhere.org\/\">Bugs Everywhere<\/a>,\n<a class=\"reference external\" href=\"http:\/\/www.mkgnu.net\/?q=scmbug\">ScmBug<\/a>, <a class=\"reference external\" href=\"http:\/\/www.distract.wellquite.org\/\">DisTract<\/a>, <a class=\"reference external\" href=\"http:\/\/www.ditrack.org\/\">DITrack<\/a>, <a class=\"reference external\" href=\"https:\/\/github.com\/schacon\/ticgit\/wiki\">ticgit<\/a> and <a class=\"reference external\" href=\"http:\/\/ditz.rubyforge.org\/\">ditz<\/a>. The conclusion of\nour favorite grumpy editor at the time was that all of the available\ndistributed bug trackers were still in their&nbsp;infancy.<\/p>\n<p>All of these piggyback on a version control system somehow - either by reusing\nthe <span class=\"caps\">VCS<\/span> database, by storing their data along with the source code in the tree,\nor by adding custom hooks that communicate with a central&nbsp;server.<\/p>\n<p>Only <a class=\"reference external\" href=\"http:\/\/www.mkgnu.net\/?q=scmbug\">ScmBug<\/a> had been somewhat widely deployed at the time, but its homepage\ngives me a blank page now. Of the trackers reviewed by <span class=\"caps\">LWN<\/span>, <a class=\"reference external\" href=\"http:\/\/www.bugseverywhere.org\/\">Bugs Everywhere<\/a>\nis the only one that is still around and somewhat active&nbsp;today.<\/p>\n<p>In the years since the article, a handful of new trackers have come along. Two new\nversion control systems - <a class=\"reference external\" href=\"http:\/\/veracity-scm.com\/compare\/\">Veracity<\/a> and <a class=\"reference external\" href=\"http:\/\/www.fossil-scm.org\/\">Fossil<\/a> - come with the kitchen\nsink included and so feature a built-in bug tracker and&nbsp;wiki.<\/p>\n<p>There is an extension for Mercurial called <a class=\"reference external\" href=\"http:\/\/mercurial.selenic.com\/wiki\/ArtemisExtension\">Artemis<\/a> that stores issues in an\n<tt class=\"docutils literal\">.issues<\/tt> directory that is colocated with the Mercurial&nbsp;repository.<\/p>\n<p>The other new tracker that I could find (though it has also not changed since\n2009) is <a class=\"reference external\" href=\"http:\/\/syncwith.us\/sd\/\"><span class=\"caps\">SD<\/span><\/a>. It uses its own distributed database technology for storing bug\ndata - called <em>Prophet<\/em>, and doesn&#8217;t rely on a <span class=\"caps\">VCS<\/span>. One of the nice features is\nthat it supports importing bugs from foreign&nbsp;trackers.<\/p>\n<p>Some of these provide the benefits you would expect of a distributed bug\ntracker. Unfortunately, all those I&#8217;ve looked at fail to even provide the basic\nfunctionality I would want in a bug tracker. Moreso than with a version control system,\nregular users interact with a bug tracker. They report bugs, provide comments\nand feedback on fixes. All of the systems I tried make these actions a lot\nharder than with your average bugzilla or mantis instance - they provide a\nlimited web <span class=\"caps\">UI<\/span> or no web interface at&nbsp;all.<\/p>\n<p><em>Update<\/em>: <span class=\"caps\">LWN<\/span> later also published articles <a class=\"reference external\" href=\"https:\/\/lwn.net\/Articles\/434922\/\">on <span class=\"caps\">SD<\/span><\/a> and <a class=\"reference external\" href=\"https:\/\/lwn.net\/Articles\/433843\/\">on Fossil<\/a>. Other\ninteresting links are <a class=\"reference external\" href=\"http:\/\/www.ericsink.com\/entries\/dbts_fossil.html\">Eric Sink&#8217;s article on distributed bug tracking<\/a> (Erik\nworks at Sourcegear who develop Veracity) and the <a class=\"reference external\" href=\"http:\/\/dist-bugs.branchable.com\/\">dist-bugs mailing list<\/a>.<\/p>\n","category":[{"@attributes":{"term":"bts"}},{"@attributes":{"term":"bug trackers"}},{"@attributes":{"term":"bugs"}},{"@attributes":{"term":"bug"}},{"@attributes":{"term":"be"}}]},{"title":"Quantified\u00a0Self","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/quantified-self.html","rel":"alternate"}},"published":"2013-11-10T02:05:00+01:00","updated":"2013-11-10T02:05:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2013-11-10:quantified-self.html","summary":"<p>Dear&nbsp;lazyweb,<\/p>\n<p>I&#8217;ve been reading about what the rest of the world seems to be calling\n&#8220;quantified self&#8221;. In essence, it is tracking of personal data like activity,\nusually with the goal of data-driven decision making. Or to take a less\nabstract common example: counting the number of steps you take each day to\nmotivate yourself to take more. I wish it&#8217;d been given a less annoying woolly\nname but this one seems to have&nbsp;stuck.<\/p>\n<p>There are a couple of interesting devices available that track sleep, activity\nand overall health. Probably best known are the FitBit and the\njazzed-up armband pedometers like the Jawbone <span class=\"caps\">UP<\/span> and the Nike Fuelband.\nUnfortunately all existing devices seem to integrate with cloud services\nsomehow, rather than giving the user direct access to their data. Apart from\nthe usual privacy concerns, this means that it is hard to do your own data\ncrunching or create a dashboard that contains data from multiple&nbsp;sources.<\/p>\n<p>Has anybody found any devices that don&#8217;t integrate with the cloud and\njust provide raw data&nbsp;access?<\/p>\n","category":[{"@attributes":{"term":"selftracking"}},{"@attributes":{"term":"quantified self"}}]},{"title":"Porcelain in\u00a0Dulwich","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/dulwich-porcelain.html","rel":"alternate"}},"published":"2013-10-04T00:00:00+02:00","updated":"2013-10-04T00:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2013-10-04:dulwich-porcelain.html","summary":"<p><span class=\"dquo\">&#8220;<\/span>porcelain&#8221; is the term that is usually used in the Git world to refer to\nthe user-facing parts. This is opposed to the lower layers: the&nbsp;plumbing.<\/p>\n<p>For a long time, I have resisted the idea of including a porcelain layer in\nDulwich. The main reason for this is that I don&#8217;t consider Dulwich a\nfull reimplementation of Git in Python. Rather, it&#8217;s a library that Python\ntools can use to interact with local or remote Git repositories, without\nany extra&nbsp;dependencies.<\/p>\n<p>dulwich has always shipped a &#8216;dulwich&#8217; binary, but that&#8217;s never been more\nthan a basic test tool - never a proper tool for end users. It was a\nmistake to install it by&nbsp;default.<\/p>\n<p>I don&#8217;t think there&#8217;s a point in providing a dulwich command-line tool that has\nthe same behaviour as the C Git binary. It would just be slower and less\nmature. I haven&#8217;t come across any situation where it didn&#8217;t make sense to\njust directly use the&nbsp;plumbing.<\/p>\n<p>However, Python programmers using Dulwich seem to think of Git operations in\nterms of porcelain rather than plumbing. Several convenience wrappers for Dulwich\nhave sprung up, but none of them is very complete. So rather than relying on external\nmodules, I&#8217;ve added a &#8220;porcelain&#8221; module to Dulwich in the <a class=\"reference external\" href=\"https:\/\/github.com\/jelmer\/dulwich\/tree\/porcelain\">porcelain<\/a>\nbranch, which provides a porcelain-like Python <span class=\"caps\">API<\/span> for&nbsp;Git.<\/p>\n<p>At the moment, it just implements a handful of commands but that should improve\nover the next few&nbsp;releases:<\/p>\n<div class=\"highlight\"><pre><span><\/span><span class=\"kn\">from<\/span> <span class=\"nn\">dulwich<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">porcelain<\/span>\n\n<span class=\"n\">r<\/span> <span class=\"o\">=<\/span> <span class=\"n\">porcelain<\/span><span class=\"o\">.<\/span><span class=\"n\">init<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;\/path\/to\/repo&quot;<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">porcelain<\/span><span class=\"o\">.<\/span><span class=\"n\">commit<\/span><span class=\"p\">(<\/span><span class=\"n\">r<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;Create a commit&quot;<\/span><span class=\"p\">)<\/span>\n<span class=\"n\">porcelain<\/span><span class=\"o\">.<\/span><span class=\"n\">log<\/span><span class=\"p\">(<\/span><span class=\"n\">r<\/span><span class=\"p\">)<\/span>\n<\/pre><\/div>\n","category":[{"@attributes":{"term":"dulwich"}},{"@attributes":{"term":"git"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"porcelain"}}]},{"title":"Book Review: Bazaar Version\u00a0Control","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/bzr-book.html","rel":"alternate"}},"published":"2013-09-28T19:33:00+02:00","updated":"2013-09-28T19:33:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2013-09-28:bzr-book.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/www.packtpub.com\">Packt<\/a> recently published a book on <a class=\"reference external\" href=\"http:\/\/www.packtpub.com\/bazaar-version-control\/book\">Version Control using Bazaar<\/a> written by\n<a class=\"reference external\" href=\"http:\/\/www.janosgyerik.com\/\">Janos Gyerik<\/a>. I was curious what the book was like, and they kindly\nprovided me with a digital&nbsp;copy.<\/p>\n<p>The book is split into roughly five sections: an introduction to version\ncontrol using Bazaar&#8217;s main commands, an overview of the available workflows,\nsome chapters on the available extensions and integration, some more advanced topics\nand finally, a quick introduction to programming using&nbsp;bzrlib.<\/p>\n<p>It is assumed the reader has no pre-existing knowledge about version control\nsystems. The first chapters introduce the reader to the concept of revision\nhistory, branching and merging and finally collaboration. All concepts are\nfirst discussed in theory, and then demonstrated using the Bazaar command-line\n<span class=\"caps\">UI<\/span> and the bzr-explorer tool. The book follows roughly the same\ntrack as the official documentation, but it is more extensive\nand has more fancy drawings of revision&nbsp;graphs.<\/p>\n<p>The middle section of the book discusses the modes in which Bazaar\ncan be used - centralized or decentralized - as well as\nthe various ways in which code can be landed in the main branch (&#8220;workflows&#8221;).\nThe selection of workflows in the book is roughly the same as those in the\nofficial Bazaar documentation. The author briefly touches on a number of other\nsoftware engineering topics such as code reviews, code formatting and automated\ntesting, though not sufficiently to make it useful for people who are\nunfamiliar with these techniques. Both the official documentation and the book\ncomplicate things unnecessarily by listing every possible&nbsp;option.<\/p>\n<p>The next chapter is a basic howto on the use of Bazaar with various hosting\nsolutions, such as Launchpad, Redmine and&nbsp;Trac.<\/p>\n<p>The <tt class=\"docutils literal\">Advanced Features<\/tt> chapter covers a wide range of obscure and less obscure\nfeatures in Bazaar: <tt class=\"docutils literal\">uncommit<\/tt>, shelves, re-using working trees, lightweight\ncheckouts, stacked branches, signing revisions and using e-mail&nbsp;hooks.<\/p>\n<p>The chapter on foreign version control system integration is a more extensive\nversion of the public docs. It has some factual inaccuracies; in particular, it\nrecommends the installation of a 2 year old buggy version of&nbsp;bzr-git.<\/p>\n<p>The last chapter provides quite a good introduction to the Bazaar APIs and\nplugin writing. It is a fair bit better than what is available&nbsp;publically.<\/p>\n<p>Overall, it&#8217;s not a bad book but also not a huge step forward from the official\ndocumentation. I might recommend it to people who are interested in\nlearning Bazaar and who do not have any experience with version control yet.\nThose who are already familiar with Bazaar or another version control system\nwill not find much&nbsp;new.<\/p>\n<p>The book misses an opportunity by following the official documentation so\nclosely. It has the same omissions and the same overemphasis on describing\nevery possible feature. I had hoped to read more about Bazaar&#8217;s data model, its\nfile format and some of the common problems, such as parallel imports, format\nhell and&nbsp;slowness.<\/p>\n<!-- I have reported in the order of 50 minor errors in the book to the publisher. -->\n<!-- issues:\npage 24-27: Not sure if I would consider bzr-explorer mature enough to be featured this prominently in the first chapter\npage 78: fails to mention how tags are propagated, that they are not versioned and what the problem is with that\npage 86-97: confusing how numbers are used for revisions that are not related to the revision numbers bazaar assigns to revisions itself. it'd be better to use letters.\npage 103: not sure why it's necessary to cover three different languages?\npage 125: mentioning different merge types isn't particularly useful unless you explain how they are different; just trying all of them every time you hit conflicts is a waste of time (and a potential way to lose changes)\npage 130: topics such as merging multiple branches seem inappropriate at this point\npage 185: this bit of bzr+ssh configuration is not specific to centralized mode, and seems out of place for this chapter (I'd expect it in the previous chapter) -->\n<!-- inaccuracies:\npage 16: Bazaar is licensed under the GPL, version 2 or later - not just version 2.\npage 16: OpenStack no longer uses bzr\npage 16: there is nothing \"official\" about Launchpad, just that the majority of FOSS projects in bzr and bzr itself are hosted there.\npage 18,21: pip is not a recommended way for installing bzr and bzr plugins so I'm surprised to see it suggested here; at least for bzr-gtk, bzr-git, bzr-svn, bzr-rewrite, bzr-search, etc I do not keep it up to date and never test it. I suspect that's true for most other plugins as well.\npage 30: fails to explain why it's called \"committing\", as in \"committing a change\"\npage 32: doesn't explain properly what it means for a revision to be associated with a working tree, how it's the base for the revision the working tree is used to prepare. the .bzr directory of a working tree contains the metadata for the working tree and either the associated branch itself or a reference to it. it doesn't contain the full contents of the base revision\npage 44: un-versioned and unknown are not the same thing. a file can be unversioned and known to bazaar but e.g. ignored. I have never seen the term non-versioned.\npage 63: incorrect typeface for \"maps\/ directory\", probably should apply to just \"maps\/\"\npage 67: 'bzr mv - -auto' works for single renames too, and is almost always preferable to 'bzr mv - -after'.\npage 82: it seems a bit odd to mention \"bzr push\" here but not any of the other propagation commands\npage 83: the reference to PCs is strange, considering Bazaar also runs on Macs\npage 86: the diagram has two 6'' revisions (seems like it one should be 6''')\npage 128: the explanation of cherry-picking is confusing\npage 132: \"mirrorring\" is an incorrect term. The push and pull command propagate revisions only; they're not mirrorring anything else about the branch, e.g. branch config or stacking setup. THey also won't result in a mirror the tip if the target is ahead of the source.\npage 139: protocols are not servers; servers implement or provide protocols\npage 146: the bzr smart server protocol *is* available over HTTP, but it needs to be explicitly enabled on the server side.\npage 152: bzr doesn't create working trees for remote branches by default (and will in fact complain that it can't update them if they exist); - -no-tree only makes sense for branches you create locally\npage 161: the fact that the history in the branches is different doesn't have anything to do with the revision numbering - the ancestry graph is different and the revision numbering is inferred from the ancestry graph\npage 164: confusing comparison of \"code reviews\" to the term \"peer review\", which is otherwise undefined. I only know \"peer review\" as the review of a peer's performance in personnel performance evaluation - not in terms of code review.\npage 164: \"code review\" doesn't require another team member to do the eventual push, it could still be the original author after (or even before) approval. This is the case with bzr itself and various bzr plugins.\npage 166: there is no such thing as a \"default mode\" in bzr; the distributed workflow is significantly more commonly used, but there is nothing default about it\npage 171: the centralized workflow may be widely used with version control systems in general (such as CVS or Subversion), but there are not a lot of bzr users who use it\npage 172: bound branches aren't necessary for the centralized model; see e.g. lightweight checkouts (which are probably the most common way of working with centralized mode)\npage 186: same goes for using bzr server - it's not specific to centralized mode\npage 206: how is using a bzr hosting site better? I'm not convinced that it is, and there are no supporting arguments here.\npage 206: are there actually any other hosting sites but launchpad that do merge proposals? I'm not aware of any\npage 213: code review was explained earlier, and this conflates the tasks of the gatekeeper and code review\npage 229: OpenStack is no longer using bzr, and zope never officially used bzr\npage 282: the switch command *is* a core feature, but the bzr-loom plugin overrides the default implementation\npage 288: whether or not the passphrase has to be reentered depends on the users' local setup\npage 296: it's possible to create a local clone of a remote repository in the foreign format; the *default* is to use the latest bzr format for the local sprout\npage 296: bazaar doesn't necessarily preserve all metadata; there are various situations in which it doesn't, e.g. when branching from svn branches\npage 304: pip is not the recommended way of installing bzr-svn\npage 304: bzr-svn does *not* preserve file properties like svn:mime-type and only preserves svn:mergeinfo if it is set on the branch root\npage 304: svn has no concept of file ids that is exposed to the outside world; bzr-svn does not preserve revision IDs or file ids\npage 305: the revision ID shown here isn't preserved - it's autogenerated deterministically; there is no concept of file IDs and revision IDs in SVN; file and revision IDs are preserved when pushing from bzr *into* svn with bzr-svn. The point here is that this revision ID is deterministic - it is predictable so two clones of the same SVN repo result in the exact same bzr repo.\npage 306: the equivalent of 'bzr commit' is 'bzr commit - -lossy'; the equivalent of 'bzr push' is 'bzr dpush'\npage 315: pip is not the recommended way of installing bzr-git\npage 315: bzr-git-1480 is an outdated copy of bzr-git which contains bugs that have since been fixed in trunk; it also appears to be uninstallable now\npage 316: ssh:\/\/user@server:path\/to\/repo.git is not a valid URL in git either; it should be ssh:\/\/user@server\/path\/to\/repo.git\npage 316: the relative path to the users' home directory does work in bzr-git versions from 2012 and later\npage 317: the example uses the 'branches' command but doesn't explain it\npage 322: \"bzr dpush\" also changes the local branch; possibly its most dangerous side-effect\npage 328: the bzr-fastimport plugin no longer ships exporters for other version control tools (hasn't since mid 2012)\npage 337: the repository instance can be anything as long as it's derived from the Repository class, it doesn't have to be a CHKInventoryRepository instance\npage 337: control_url doesn't have to refer to a .bzr\/branch directory though it will for most native local branches\npage 357: the bzr_* variables mentioned here are not used by anything; they were never more than a recommendation and setting them won't give you anything. -->\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"book"}}]},{"title":"Migrating packaging from Bazaar to\u00a0Git","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/pristine-tar-migrate-bzr-to-git.html","rel":"alternate"}},"published":"2013-06-02T02:01:00+02:00","updated":"2013-06-02T02:01:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2013-06-02:pristine-tar-migrate-bzr-to-git.html","summary":"<p>A while ago I migrated most of my packages from Bazaar to Git. The rest of the\nworld has decided to use Git for version control, and I don&#8217;t have enough\nreason to stubbornly stick with Bazaar and make it harder for myself to\ncollaborate with&nbsp;others.<\/p>\n<p>So I&#8217;m moving away from a workflow I know and have polished over the last few\nyears - including the various bzr plugins and other tools involved. Trying to\ndo the same thing using git is frustrating and time-consuming, but I&#8217;m sure\nthat will improve with time. In particular, I haven&#8217;t found a good way to merge\nin a new upstream release (from a tarball) while referencing the relevant\nupstream commits, like <tt class=\"docutils literal\">bzr <span class=\"pre\">merge-upstream<\/span><\/tt> can. Is there a good way to do this?\nWhat helper tools can you recommend for maintaining a Debian package in&nbsp;git?<\/p>\n<p>Having been upstream for <tt class=\"docutils literal\"><span class=\"pre\">bzr-git<\/span><\/tt> earlier, I used its <tt class=\"docutils literal\"><span class=\"pre\">git-remote-bzr<\/span><\/tt>\nimplementation to do the conversions of the commits and&nbsp;tags:<\/p>\n<pre class=\"literal-block\">\n% git clone bzr::\/path\/to\/bzr\/foo.bzr \/path\/to\/git\/foo.git\n<\/pre>\n<p>One of my last contributions to bzr-git was a <tt class=\"docutils literal\">bzr <span class=\"pre\">git-push-pristine-tar-deltas<\/span><\/tt>\nsubcommand, which will export all bzr-builddeb-style pristine-tar metadata\nto a pristine-tar branch in a Git repository that can be used by\n<em>pristine-tar<\/em> directly or through something like <em>git-buildpackage<\/em>.<\/p>\n<p>Once you have created a git clone of your bzr branch, it should be a matter of\nrunning <tt class=\"docutils literal\">bzr <span class=\"pre\">git-push-pristine-tar-deltas<\/span><\/tt> with the target git repository\nand the Debian package&nbsp;name:<\/p>\n<pre class=\"literal-block\">\n% cd \/path\/to\/bzr\/foo.bzr\n% bzr git-push-pristine-tar-deltas \/path\/to\/git\/foo.git foo\n% cd \/path\/to\/git\/foo.git foo\n% git branch\n*  master\n   pristine-tar\n<\/pre>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"git"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"packaging"}},{"@attributes":{"term":"pristine-tar"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Kiln using\u00a0Dulwich","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/kiln-dulwich.html","rel":"alternate"}},"published":"2013-03-21T00:00:00+01:00","updated":"2013-03-21T00:00:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2013-03-21:kiln-dulwich.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/blog.fogcreek.com\/kiln-harmony-internals-the-basics\/\">http:\/\/blog.fogcreek.com\/kiln-harmony-internals-the-basics\/<\/a><\/p>\n<p>Nice to see that #Kiln is also using #Dulwich for some of its Git support. Unfortunately I haven&#8217;t been able to spend as much time on it recently as it deserves (busy changing jobs and countries), but hopefully that will change&nbsp;soon.<\/p>\n"},{"title":"OpenChange 2.0\u00a0released","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/openchange-20-released.html","rel":"alternate"}},"published":"2013-02-08T20:00:00+01:00","updated":"2013-02-08T20:00:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2013-02-08:openchange-20-released.html","summary":"<p>Apparently &#8216;tis the season for major software&nbsp;releases.<\/p>\n<p><a class=\"reference external\" href=\"https:\/\/twitter.com\/jkerihuel\">Julien<\/a> has just announced the release of <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/\">OpenChange<\/a> 2.0, codenamed\n<a class=\"reference external\" href=\"http:\/\/en.memory-alpha.org\/wiki\/Quadrant\">quadrant<\/a>. This release fixes a number of important bugs and enables\nintegration with <a class=\"reference external\" href=\"http:\/\/www.sogo.nu\/english.html\">SOGo<\/a>.<\/p>\n<p>With the SOGo backend, it is now possible to set up an Exchange-compatible\ngroupware server that can be accessed from Outlook without the need to\nconnect any&nbsp;connectors.<\/p>\n<p>See the <a class=\"reference external\" href=\"http:\/\/openchange.org\/developers\/relnotes\/2.0-quadrant.html\">release notes<\/a> for more&nbsp;details.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"openchange"}}]},{"title":"Bazaar: A\u00a0retrospective","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/bzr-retrospective.html","rel":"alternate"}},"published":"2012-12-19T22:36:43+01:00","updated":"2012-12-19T22:36:43+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2012-12-19:bzr-retrospective.html","summary":"<p>For the last 7 years I&#8217;ve been involved in the <a class=\"reference external\" href=\"http:\/\/bazaar-vcs.org\/\">Bazaar<\/a> project. Since\nI am slowly stepping down, I recently wrote <a class=\"reference external\" href=\"\/pages\/bzr-a-retrospective.html\">a retrospective<\/a> on the\nproject as I experienced it for the last 7&nbsp;years.<\/p>\n<p>Thanks to a few kind people for proofreading earlier drafts; if you spot any\nerrors, please let me know in the&nbsp;comments.<\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"canonical"}},{"@attributes":{"term":"samba"}},{"@attributes":{"term":"ubuntu"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"vcs"}}]},{"title":"Samba 4.0.0,\u00a0finally","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/samba-4.0.0.html","rel":"alternate"}},"published":"2012-12-11T18:00:00+01:00","updated":"2012-12-11T18:00:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2012-12-11:samba-4.0.0.html","summary":"<p>This afternoon <a class=\"reference external\" href=\"https:\/\/www.samba.org\/samba\/news\/releases\/4.0.0.html\">we released version 4.0.0<\/a> of Samba. This is a significant\nmilestone, and I&#8217;m very proud of the result. Samba 4 is the first version\nthat can be a domain controller in an Active Directory&nbsp;domain.<\/p>\n<p>We embarked on this journey almost a decade ago - <a class=\"reference external\" href=\"https:\/\/git.samba.org\/?p=samba.git;a=commit;h=b0510b5428b3461aeb9bbe3cc95f62fc73e2b97f\">the first commit<\/a> is from\nAugust 2003. It&#8217;s been a long and bumpy ride. I hardly recognize\nthe people in this <a class=\"reference external\" href=\"https:\/\/www.samba.org\/samba\/images\/team_l2003.jpg\">team photo from 2003<\/a> (I&#8217;m second from the&nbsp;left).<\/p>\n<p>A lot has happened in that time. We wrote <a class=\"reference external\" href=\"https:\/\/www.ohloh.net\/p\/samba\/contributors\/summary\">a few million lines of code<\/a>. We migrated from <span class=\"caps\">CVS<\/span> to Subversion to Git. We&#8217;ve drifted apart and grown back together as a <a class=\"reference external\" href=\"https:\/\/www.samba.org\/samba\/team\/\">team<\/a>.<\/p>\n<p>In my youthful naivity I predicted a release &#8220;within 1 or 2\nyears&#8221; during <a class=\"reference external\" href=\"http:\/\/www.samba.org\/~jelmer\/jelmer-nluug-vj04.pdf\">a talk at the <span class=\"caps\">NLUUG<\/span><\/a> in 2004. But Active Directory was a lot\nharder than we thought, and there were quite a few other distractions as well.\nI&#8217;m glad this release, which is by far the biggest and longest running software\nproject I have ever worked on, has finally&nbsp;happened.<\/p>\n<p>Some older RCs of Samba 4 have already been packaged for Debian and Ubuntu,\nin the <tt class=\"docutils literal\">samba4<\/tt> source package. For Debian jessie, these will be integrated\ninto the main <tt class=\"docutils literal\">samba<\/tt> source package. Please use <tt class=\"docutils literal\">experimental<\/tt> if you do\nwant to try the existing packages, as it is most up to&nbsp;date.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Documentation","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/documentation.html","rel":"alternate"}},"published":"2012-12-01T00:00:00+01:00","updated":"2012-12-01T00:00:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2012-12-01:documentation.html","summary":"<p>From <span class=\"caps\">LWN<\/span>&#8217;s weekly&nbsp;edition:<\/p>\n<blockquote>\n<blockquote>\nDocumentation is the sort of thing that will never be great unless someone from outside contributes it (since the developers can never remember which parts are hard to understand).<\/blockquote>\n<p class=\"attribution\">&mdash;<a class=\"reference external\" href=\"https:\/\/github.com\/apenwarr\/bup\">Avery&nbsp;Pennarun<\/a><\/p>\n<\/blockquote>\n","category":[{"@attributes":{"term":"lwn"}},{"@attributes":{"term":"bup"}}]},{"title":"Back to\u00a0blogging","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/251-back-to-blogging.html","rel":"alternate"}},"published":"2012-11-26T03:17:00+01:00","updated":"2012-11-26T03:17:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2012-11-26:251-back-to-blogging.html","summary":"<p>Hello Internet. After a long silence and several fights with <a class=\"reference external\" href=\"http:\/\/www.s9y.org\/\">Serendipity<\/a>\nI am&nbsp;back.<\/p>\n<p>The contents from my old <cite>Serendipity<\/cite> install have been migrated to\nrestructuredText in <a class=\"reference external\" href=\"http:\/\/www.getpelican.com\/\">pelican<\/a>. Among other things, this means I can\nnow get rid of the last <span class=\"caps\">PHP<\/span> install I had left on my&nbsp;server.<\/p>\n"},{"title":"Last day at\u00a0Canonical","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/last-day-at-canonical.html","rel":"alternate"}},"published":"2012-10-17T00:00:00+02:00","updated":"2012-10-17T00:00:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2012-10-17:last-day-at-canonical.html","summary":"<p>This Friday will be my last day at <a class=\"reference external\" href=\"http:\/\/www.canonical.com\/\">Canonical<\/a>.<\/p>\n<p>It has been a lot of fun working here. There is so much I have learned in\nthe last three years. I&#8217;m going to miss my&nbsp;colleagues.<\/p>\n<p>Over the last couple of months I have slowly stepped down from my involvement\nin Bazaar and the Bazaar packaging in Debian and Ubuntu.\nI would like to stay involved in Ubuntu, but we will see how that&nbsp;goes.<\/p>\n<p>I&#8217;m taking some time off until the end of the year to see the world and\nhack, before starting something new in&nbsp;February.<\/p>\n","category":[{"@attributes":{"term":"canonical"}},{"@attributes":{"term":"ubuntu"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"launchpad"}},{"@attributes":{"term":"debian"}}]},{"title":"Summer of Code\u00a02011","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/272-Summer-of-Code-2011.html","rel":"alternate"}},"published":"2011-07-18T08:53:05+02:00","updated":"2011-07-18T08:53:05+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2011-07-18:272-Summer-of-Code-2011.html","summary":"<p>The Samba team is once again participating in the Summer of Code this year.\nThis year we have 4 students working on various projects related to&nbsp;Samba.<\/p>\n<p>This year I am mentoring Dhananjay Sathe, who is improving the\n<a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/SambaGtk\"><span class=\"caps\">GTK<\/span>+ frontends for Samba<\/a>. In\nparticular, he is making it possible to manage shares and users of a remote\nSamba or Windows&nbsp;machine.<\/p>\n<p>Dhananjay is also <a class=\"reference external\" href=\"http:\/\/dsathe.blogspot.com\/2011\/07\/samba-with-soc-google-summer-of-code.html\">blogging about his progress<\/a>.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"soc"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"libapache2-mod-bzr","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/269-libapache2-mod-bzr.html","rel":"alternate"}},"published":"2011-01-02T19:07:53+01:00","updated":"2011-01-02T19:07:53+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2011-01-02:269-libapache2-mod-bzr.html","summary":"<p>During the last two days I hacked together a <a class=\"reference external\" href=\"http:\/\/bazaar.canonical.com\/\">Bazaar<\/a> module for <a class=\"reference external\" href=\"http:\/\/www.apache.org\/\">Apache<\/a>.\nThis module makes it possible to easily enable the Bazaar smart server for\nBazaar branches. It also can display a simple placeholder page for Bazaar\nbranches without working tree. It&#8217;s surprisingly easy to write Apache&nbsp;modules.<\/p>\n<p>The main advantage this has over a mod_wsgi \/ mod_python \/ mod_fcgi setup is that it doesn&#8217;t require any additional Python hacking on the users side or other configuration outside of Apache, and it doesn&#8217;t require configuration for each single branch in the Apache configuration. In the future I&#8217;d also like to support the settings &#8220;BazaarFrontend <a class=\"reference external\" href=\"https:\/\/launchpad.net\/wikkid\">Wikkid<\/a>&#8221; and &#8220;BazaarFrontend <a class=\"reference external\" href=\"https:\/\/launchpad.net\/loggerhead\">Loggerhead<\/a>&#8221;.<\/p>\n<p>The configuration is currently as simple&nbsp;as:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"nb\">LoadModule<\/span><span class=\"w\"> <\/span>bzr_module<span class=\"w\"> <\/span><span class=\"sx\">\/usr\/lib\/apache2\/modules\/mod_bzr.so<\/span>\n<span class=\"nb\">BazaarSmart<\/span><span class=\"w\"> <\/span><span class=\"k\">on<\/span>\n<span class=\"nb\">BazaarFrontend<\/span><span class=\"w\"> <\/span>Basic\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>in your <strong>apache2.conf<\/strong>. The <strong>BazaarSmart<\/strong> and <strong>BazaarFrontend<\/strong> directives can appear in &lt;Directory&gt; or &lt;Location&gt; clauses as well, if you&#8217;d like to have different behaviour for different&nbsp;directories.<\/p>\n<p>At the moment this project is a proof of concept, and probably not something\nyou would want to run in production. For example, there is no way to limit the\naccess to a branch to read only. I need to double-check there are no threading&nbsp;issues.<\/p>\n<p>Testing and patches are welcome. The project is hosted&nbsp;here:<\/p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https:\/\/launchpad.net\/apache-bzr\">https:\/\/launchpad.net\/apache-bzr<\/a><\/li>\n<\/ul>\n<p><em>Currently Playing: Stream of Passion -&nbsp;Calliopeia<\/em><\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"ubuntu"}},{"@attributes":{"term":"launchpad"}}]},{"title":"On the way to Samba 4: Part\u00a02","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/268-On-the-way-to-Samba-4-Part-2.html","rel":"alternate"}},"published":"2011-01-02T16:30:13+01:00","updated":"2011-01-02T16:30:13+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2011-01-02:268-On-the-way-to-Samba-4-Part-2.html","summary":"<p>It&#8217;s been more than a month since the last status update on my Samba 4 work -\nmuch more than the two weeks I&nbsp;promised.<\/p>\n<p>During the holidays I finally managed to release the <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Samba4\/Releases\/4.0.0alpha14\">new alpha of Samba 4<\/a>,\nas well as releases of some of our companion libraries (<a class=\"reference external\" href=\"http:\/\/tdb.samba.org\/\">tdb<\/a>, <a class=\"reference external\" href=\"http:\/\/talloc.samba.org\/\">talloc<\/a>,\ntevent and <a class=\"reference external\" href=\"http:\/\/ldb.samba.org\/\">ldb<\/a>). The release includes a significant amount of bug fixes and\na lot of work towards a properly functioning Active Directory <span class=\"caps\">DC<\/span>, too much to\nlist&nbsp;here.<\/p>\n<p>This release I&#8217;ve mainly been involved in improving our Python bindings and our\nhandling of internal and external libraries. We now use symbol versioning for\nour copy of Heimdal Kerberos as well as some of our other libraries. Hopefully\nthis will fix some of the issues users of the evolution-mapi plugin have been\nseeing where they end up with both <span class=\"caps\">MIT<\/span> Kerberos and Heimdal Kerberos loaded\ninto the same process (with all the consequences of overlapping symbol names).\nSamba 4 now also has the ability to work with the system Heimdal rather than\nusing the bundled copy. I have packaged alpha14 for Debian and Ubuntu (fixing\nmost of the open bugs against the Samba 4 package in the <span class=\"caps\">BTS<\/span>), but am currently\nwaiting for the new release of ldb to pass through <span class=\"caps\">NEW<\/span> before I can&nbsp;upload.<\/p>\n<p>The next release is scheduled for the first week of&nbsp;February.<\/p>\n<p><em>Currently Playing: Stream of Passion -&nbsp;Haunted<\/em><\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"On the way to Samba 4: Part\u00a01","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/267-On-the-way-to-Samba-4.html","rel":"alternate"}},"published":"2010-11-24T20:44:00+01:00","updated":"2010-11-24T20:44:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-11-24:267-On-the-way-to-Samba-4.html","summary":"<p>After <a class=\"reference external\" href=\"http:\/\/www.sambaxp.org\/\">Samba <span class=\"caps\">XP<\/span> 2008<\/a> <a class=\"reference external\" href=\"http:\/\/samba.org\/~abartlet\/\">Andrew<\/a> and I started keeping a wiki page with our bi-weekly goals and achievements for Samba 4. Because planning in a Free Software project is hard (time availability and priorities change over time, and other volunteers are equally unpredictable) we called this our <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Samba4\/Andrew_and_Jelmers_Fantasy_Page\">&#8220;Fantasy Page&#8221;<\/a>; it listed things we wanted to work on next (&#8220;fantasies&#8221;), but reality being what it is we would usually actually end up working on something entirely different. We discussed our progress and new plans in - what I would now call - a bi-weekly standup&nbsp;call.<\/p>\n<p>There were several reasons for doing this. It gave us some sense of direction as well as a sense of accomplishment; a way to look back at the end of the year and realize how much we had actually achieved. Because Samba 4 is such a long term project (it is 7 years old at this point) it is easy to become disillusioned, to look back at a year of commits and to not see the gradual improvement, just the fact that there is no release&nbsp;yet.<\/p>\n<p>We managed to keep this up for <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Samba4\/Andrew_and_Jelmers_Fantasy_Page\/2008\">two<\/a> <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Samba4\/Andrew_and_Jelmers_Fantasy_Page\/2009\">years<\/a>, much longer than I had anticipated, and eventually started to slip last&nbsp;year.<\/p>\n<p>More recently <a class=\"reference external\" href=\"http:\/\/www.kblin.org\">Kai<\/a> and <a class=\"reference external\" href=\"http:\/\/blog.tridgell.net\/\">Tridge<\/a> have started to blog weekly about their efforts to make Samba 4.0 a reality and I&#8217;m going to join them by trying to blog regularly - every two weeks - about my contributions, even if there were&nbsp;none.<\/p>\n<p>In the next two weeks I plan to work on finally getting alpha 14 of Samba 4 out and on fixing the daily builds of Samba 4 and OpenChange for Ubuntu on Launchpad after we did a massive reorganization of the private libraries in Samba&nbsp;4.<\/p>\n<p><em>Current Playing: Zero 7 -&nbsp;Somersault<\/em><\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Mumble and\u00a0bluetooth","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/266-Mumble-and-bluetooth.html","rel":"alternate"}},"published":"2010-11-07T21:38:35+01:00","updated":"2010-11-07T21:38:35+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-11-07:266-Mumble-and-bluetooth.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/mumble.sourceforge.net\/\">Mumble<\/a> is an open source, low-latency, high quality voice chat application that we&#8217;re using at Canonical, and which Samba has recently also&nbsp;adopted.<\/p>\n<p>After I busted the cable of my cabled headset and inspired by <a class=\"reference external\" href=\"http:\/\/mdzlog.alcor.net\/2010\/05\/26\/using-mumble-with-a-bluetooth-headset\/\">Matt&#8217;s post about Mumble and Bluetooth<\/a> I bought a cheap Nokia Bluetooth headset that works with my laptop as well as my phone. By using <a class=\"reference external\" href=\"http:\/\/blueman-project.org\/\">BlueMan<\/a> I even found that the headset worked out of the box on&nbsp;Maverick.<\/p>\n<p>A nice feature in Mumble is that it is controllable using D-Bus. Blueman supports running an arbitrary command when the answer button is pressed. Combining these two features, it is possible to automatically toggle mute when the answer button is&nbsp;pressed:<\/p>\n<pre class=\"code python literal-block\">\n<span class=\"ch\">#!\/usr\/bin\/python<\/span><span class=\"w\">\n<\/span><span class=\"kn\">import<\/span> <span class=\"nn\">dbus<\/span><span class=\"w\">\n<\/span><span class=\"n\">bus<\/span> <span class=\"o\">=<\/span> <span class=\"n\">dbus<\/span><span class=\"o\">.<\/span><span class=\"n\">SessionBus<\/span><span class=\"p\">()<\/span><span class=\"w\">\n<\/span><span class=\"n\">mumble<\/span> <span class=\"o\">=<\/span> <span class=\"n\">bus<\/span><span class=\"o\">.<\/span><span class=\"n\">get_object<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;net.sourceforge.mumble.mumble&quot;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;\/&quot;<\/span><span class=\"p\">)<\/span><span class=\"w\">\n<\/span><span class=\"n\">is_muted<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mumble<\/span><span class=\"o\">.<\/span><span class=\"n\">isSelfMuted<\/span><span class=\"p\">()<\/span><span class=\"w\">\n<\/span><span class=\"n\">mumble<\/span><span class=\"o\">.<\/span><span class=\"n\">setSelfMuted<\/span><span class=\"p\">(<\/span><span class=\"ow\">not<\/span> <span class=\"n\">is_muted<\/span><span class=\"p\">)<\/span>\n<\/pre>\n<p>To use this script, set its path in the configuration tab for the &#8220;Headset&#8221; plugin in&nbsp;blueman.<\/p>\n<p>The only remaining problem with this setup is that I can&#8217;t keep the headset on during my work day, as I don&#8217;t have a way to put it in standby mode automatically. This means that my battery runs out pretty quickly, even when nothing is happening on&nbsp;Mumble.<\/p>\n<p><em>Currently Playing: Red Sparowes - Finally As That Blazing Sun&nbsp;Shone<\/em><\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"ubuntu"}},{"@attributes":{"term":"canonical"}}]},{"title":"OpenChange server and\u00a0SOGo","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/264-OpenChange-server-and-SOGo.html","rel":"alternate"}},"published":"2010-10-26T17:47:16+02:00","updated":"2010-10-26T17:47:16+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-10-26:264-OpenChange-server-and-SOGo.html","summary":"<p>There&#8217;s more good news on the OpenChange front. Julien has been working\ntogether with Wolfgang and Ludovic from <a class=\"reference external\" href=\"http:\/\/www.inverse.ca\/english.html\">Inverse<\/a> to leverage the server-side\nsupport in OpenChange to provide native Exchange server support in <a class=\"reference external\" href=\"http:\/\/ww.sogo.nu\/\">SOGo<\/a>.<\/p>\n<p>A couple of days ago we <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/\">announced<\/a> that there now is an initial version that\nallows the use of Outlook against a SOGo server through&nbsp;OpenChange.<\/p>\n<p>There is a screencast <a class=\"reference external\" href=\"http:\/\/www.youtube.com\/v\/oSZJ95YeXYE\">up on youtube<\/a> (there is also a <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/openchange-2010-10-15.mov\">.mov version of the\nscreencast<\/a>).<\/p>\n<p>As far as I know, this is the first time it&#8217;s possible to actually use Outlook\nclients with a non-Microsoft Exchange-compatible server, without the need for\nplugins on the Outlook side. And it&#8217;s all Free Software. Of course, this is\njust a preview, and not something we&#8217;d recommend everybody to run in production\njust yet. But it&#8217;s exciting to finally see this come&nbsp;together.<\/p>\n<p>We already have OpenChange packages in <a class=\"reference external\" href=\"http:\/\/packages.debian.org\/openchangeserver\">Debian<\/a> and <a class=\"reference external\" href=\"http:\/\/packages.ubuntu.com\/openchangeserver\">Ubuntu<\/a> but I hope I can\nhelp get SOGo packaged for both distributions as&nbsp;well.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"openchange"}},{"@attributes":{"term":"ubuntu"}},{"@attributes":{"term":"canonical"}}]},{"title":"Samba 4 and OpenChange daily Ubuntu\u00a0packages","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/263-Samba-4-and-OpenChange-daily-Ubuntu-packages.html","rel":"alternate"}},"published":"2010-09-28T10:39:50+02:00","updated":"2010-09-28T10:39:50+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-09-28:263-Samba-4-and-OpenChange-daily-Ubuntu-packages.html","summary":"<div class=\"section\" id=\"daily-builds\">\n<h2>Daily&nbsp;builds<\/h2>\n<p>As of a month ago there are Ubuntu archives with fresh packages of <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Samba4\">Samba 4<\/a> and <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/\">OpenChange<\/a>, built on a daily basis day from the latest upstream&nbsp;revision.<\/p>\n<p>This means that it is now possible to run a version of Samba 4 that is less than 24 hours old, without having to know how to extract source code from the version control system that upstream is using, without having to know how to build and install an application from source, but perhaps most importantly: without having to go through the tedious process of manually updating the source code and&nbsp;rebuilding.<\/p>\n<p><a class=\"reference external\" href=\"http:\/\/www.openchange.org\/\">OpenChange<\/a> is tightly coupled to Samba 4, so installing a new version of OpenChange usually involves installing a new version of Samba 4 as well. To make matters more confusing, the two projects use different version control systems (Samba 4 is in <a class=\"reference external\" href=\"http:\/\/git-scm.com\/\">Git<\/a>, while OpenChange is in <a class=\"reference external\" href=\"http:\/\/subversion.tigris.org\/\">Subversion<\/a>) and different build systems (Samba 4 uses <a class=\"reference external\" href=\"http:\/\/code.google.com\/p\/waf\/\">waf<\/a>, OpenChange uses <a class=\"reference external\" href=\"http:\/\/www.gnu.org\/software\/autoconf\/\">autoconf<\/a> and&nbsp;make).<\/p>\n<p>I have been involved in Samba 4 and OpenChange as an upstream developer and more recently also as a packager for both <a class=\"reference external\" href=\"http:\/\/www.debian.org\/\">Debian<\/a> and <a class=\"reference external\" href=\"http:\/\/www.ubuntu.com\/\">Ubuntu<\/a>.<\/p>\n<p>As an upstream developer for both these projects it is important for me that users can easily run the development versions. It makes it possible for interested users to confirm the fixes for issues they have reported and to test new features. The more users run the development version, the more confident I can be as a developer that <a class=\"reference external\" href=\"http:\/\/lists.samba.org\/archive\/samba-technical\/2010-September\/073481.html\">doing a release will not cause any unexpected surprises<\/a>.<\/p>\n<p>As a packager it is useful to know when there are upstream changes that are going to break my package with the next&nbsp;release.<\/p>\n<\/div>\n<div class=\"section\" id=\"recipes\">\n<h2>Recipes<\/h2>\n<p>The daily builds work using so-called recipes which describe how to build a Debian source package from a set of Bazaar branches. For example, the <a class=\"reference external\" href=\"https:\/\/code.edge.launchpad.net\/~samba-team\/+recipe\/4.0-ppa\">Samba 4 recipe<\/a> looks like&nbsp;this:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span># bzr-builder format 0.2 deb-version 4.0.0~alpha14~bzr{revno}~ppa{revno:packaging}+{revno:debian}\nlp:samba\nmerge debian lp:~samba-team\/samba\/unstable\nmerge packaging lp:~samba-team\/samba\/4.0-ppa-maverick\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>This dictates that a source package should be built by taking the <a class=\"reference external\" href=\"https:\/\/code.launchpad.net\/~samba-team\/samba\/trunk\">upstream Samba branch<\/a> and merging the <a class=\"reference external\" href=\"https:\/\/code.launchpad.net\/~samba-team\/samba\/unstable\">Debian packaging<\/a> and <a class=\"reference external\" href=\"https:\/\/code.launchpad.net\/~samba-team\/samba\/4.0-ppa-maverick\">some recipe-specific tweaking<\/a>.  The last bit on the first line indicates the version string to be used when generating a changelog entry for the daily&nbsp;build.<\/p>\n<p>Every night Launchpad (through <a class=\"reference external\" href=\"https:\/\/launchpad.net\/bzr-builder\">bzr-builder<\/a>) merges these branches and attempts to build the resulting source package, e-mailing me in case of build problems. Generally I fix issues that come up by committing directly to upstream <span class=\"caps\">VCS<\/span> or to the Debian packaging branch. There is no overhead in maintaining the daily build after I&#8217;ve set it&nbsp;up.<\/p>\n<p>For more information on creating source package recipes, see <a class=\"reference external\" href=\"https:\/\/help.launchpad.net\/Packaging\/SourceBuilds\/GettingStarted\">getting started<\/a>.<\/p>\n<div class=\"section\" id=\"toolchain\">\n<h3>Toolchain<\/h3>\n<p>The entire toolchain that does the daily package builds for Ubuntu is Free Software, and I have contributed to various bits of that toolchain over the years. It&#8217;s exciting to see everything come&nbsp;together.<\/p>\n<div class=\"section\" id=\"soyuz\">\n<h4>Soyuz<\/h4>\n<p>Launchpad consists of multiple pillars - one of those pillars is Soyuz, which I hack on as part of my day job at Canonical. Soyuz is responsible for the archive management and package building. Debian source packages (a combination of upstream source code and packaging metadata) get uploaded by users and then built for various architectures on our <a class=\"reference external\" href=\"http:\/\/launchpad.net\/builders\">buildfarm<\/a> and published to the Ubuntu archive or to users personal package&nbsp;archives.<\/p>\n<\/div>\n<div class=\"section\" id=\"launchpad-code\">\n<h4>Launchpad-code<\/h4>\n<p>Another pillar of Launchpad is Launchpad-code, which is responsible for the hosting and management of version control branches. Launchpad users can either host their branches on Launchpad directly or mirror branches (either native Bazaar branches or branches in a foreign format such as Subversion, Git or Mercurial). The mirrorring of native and foreign branches happens using standard Bazaar <span class=\"caps\">API<\/span>&#8217;s. In the case of Samba and OpenChange we import the branches of the upstream projects (Samba is in Git, OpenChange is in Subversion) and the packaging for both projects is in&nbsp;Bazaar.<\/p>\n<p>Launchad-code calls out to Bazaar to do the actual mirrorring. Over the last few years I have done a lot of work to improve Bazaars support for foreign branches, in particular on supporting Subversion, Git and Mercurial. As the code mirrorring in Launchpad is one of the biggest users of bzr-svn and bzr-git it has helped find some of the more obscure bugs in those plugins over the last few years, to the point where there are only a handful of <a class=\"reference external\" href=\"https:\/\/dev.launchpad.net\/FailingBzrGitImports\">issues with Git imports<\/a> and <a class=\"reference external\" href=\"https:\/\/dev.launchpad.net\/FailingBzrSvnImports\">Subversion imports<\/a>&nbsp;left.<\/p>\n<\/div>\n<div class=\"section\" id=\"bzr-git-and-dulwich\">\n<h4>bzr-git and&nbsp;dulwich<\/h4>\n<p>bzr-git provides transparent access to Git repositories from within Bazaar and is built on top of <a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/dulwich\">Dulwich<\/a>.  Dulwich is a Python library that provides access to the Git file formats and protocols that is completely independent of Bazaar. James Westby originally started it and I adopted it for bzr-git and further extended it. There are now several other projects that use it as well, including <a class=\"reference external\" href=\"http:\/\/hg-git.github.com\/\">hg-git<\/a>, and <a class=\"reference external\" href=\"http:\/\/www.rabbitvcs.org\/\">rabbitvcs<\/a>. Apart from James and myself, almost two dozen other people have contributed it so&nbsp;far.<\/p>\n<\/div>\n<div class=\"section\" id=\"bzr-svn-and-subvertpy\">\n<h4>bzr-svn and&nbsp;subvertpy<\/h4>\n<p>bzr-svn provides transparant access to Subversion repositories in Bazaar. When I grew frustrated with the existing Subversion Python bindings <a class=\"reference external\" href=\"http:\/\/jelmer.vernstok.nl\/blog\/archives\/218-bzr-svn-now-with-its-own-Subversion-Python-bindings.html\">for various reasons<\/a>, I decided to create independent Python bindings for Subversion from scratch. These bindings have since been split out into a separate project - <a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/subvertpy\">subvertpy<\/a> - and other projects have since also started using them, e.g. <a class=\"reference external\" href=\"http:\/\/mercurial.selenic.com\/wiki\/HgSubversion\">hgsubversion<\/a> and <a class=\"reference external\" href=\"http:\/\/basieproject.org\/\">basie<\/a>.<\/p>\n<\/div>\n<\/div>\n<div class=\"section\" id=\"using-the-daily-builds\">\n<h3>Using the daily&nbsp;builds<\/h3>\n<p>To use the <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Samba4\">Samba 4<\/a> and <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/\">OpenChange<\/a> daily builds (Ubuntu Maverick only for now),&nbsp;run:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span>$<span class=\"w\"> <\/span>apt-add-repository<span class=\"w\"> <\/span>ppa:samba-team\/ppa\n$<span class=\"w\"> <\/span>apt-add-repository<span class=\"w\"> <\/span>ppa:openchange\/daily-builds\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p><em>Currently Playing: Karnivool -&nbsp;Themata<\/em><\/p>\n<\/div>\n<\/div>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"vc"}},{"@attributes":{"term":"bzr_svn"}},{"@attributes":{"term":"openchange"}},{"@attributes":{"term":"git"}},{"@attributes":{"term":"ubuntu"}},{"@attributes":{"term":"hg"}},{"@attributes":{"term":"bzr_git"}},{"@attributes":{"term":"launchpad"}},{"@attributes":{"term":"canonical"}}]},{"title":"subunit usage in\u00a0Samba","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/262-subunit-usage-in-Samba.html","rel":"alternate"}},"published":"2010-09-24T00:46:11+02:00","updated":"2010-09-24T00:46:11+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-09-24:262-subunit-usage-in-Samba.html","summary":"<p>Both Samba 3 and Samba 4 are now using the &#8220;<a class=\"reference external\" href=\"http:\/\/launchpad.net\/subunit\">subunit<\/a>&#8221; protocol inside their testsuite (aka &#8220;make test&#8221;). subunit is a streaming protocol used to report test results that is aimed at being simple to generate and parse as well as being human&nbsp;readable.<\/p>\n<p>A very simple subunit stream might look like&nbsp;this:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span>\n<span class=\"normal\">5<\/span>\n<span class=\"normal\">6<\/span>\n<span class=\"normal\">7<\/span>\n<span class=\"normal\">8<\/span>\n<span class=\"normal\">9<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span>test: samba4.tests.util.strlist.check_list_make\ncreating list...\nlist created!\nsuccess: samba4.tests.util.strlist.check_list_make\ntest: samba4.tests.util.strlist.check_list_make_shell\ncreating list...\nxfail: samba4.tests.util.strlist.check_list_make_shell [\nreturned NT_STATUS_NOT_IMPLEMENTED\n]\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>For those that are familiar with the <span class=\"caps\">TAP<\/span> protocol used by Perl, it is similar to that, although it has a couple of features that <span class=\"caps\">TAP<\/span> does not have. For example, it can report timestamps (useful for determining test duration) and has more flexible progress&nbsp;reporting.<\/p>\n<p>Subunit is particularly useful for projects that use multiple programming languages as it allows a single tool to be used for test visualization or analysis rather than one per language. All that&#8217;s required per-language is a test runner that can spit out subunit&nbsp;streams.<\/p>\n<p>selftest.pl, the main engine behind Samba&#8217;s test suite, has been using subunit internally since its creation a couple of years ago. Most other test tools we use can also report subunit, in particular our Python tests, blackbox tests, Perl tests (using tap2subunit) and&nbsp;smbtorture.<\/p>\n<p><span class=\"dquo\">&#8220;<\/span>make test&#8221; never displays raw subunit results, it always formats them using our format-subunit script. Samba 4&#8217;s &#8220;make test&#8221; stores the raw  subunit output in&nbsp;st\/subunit.<\/p>\n<p>I&#8217;m attending <a class=\"reference external\" href=\"http:\/\/www.snia.org\/events\/storage-developer2010\"><span class=\"caps\">SNIA<\/span> <span class=\"caps\">SDC<\/span><\/a> at the moment and a couple of people here have asked me about the tools I use to display and analyse test results. They&nbsp;are:<\/p>\n<div class=\"section\" id=\"subunit-1\">\n<h2><a class=\"reference external\" href=\"http:\/\/launchpad.net\/subunit\">subunit<\/a><\/h2>\n<p>The subunit project contains a bunch of convenience tools for working with subunit. Other than libraries for parsing\/generating subunit for several languages it contains tools for manipulating and analysing subunit streams,&nbsp;including:<\/p>\n<ul class=\"simple\">\n<li>subunit-ls: List all tests in a subunit stream, optionally including their run times (I used this for the <a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/samba4-test-times.ods\">test duration summary<\/a> I sent to the Samba mailing list&nbsp;earlier)<\/li>\n<li>tap2subunit: convert a <span class=\"caps\">TAP<\/span> stream to a Subunit&nbsp;stream<\/li>\n<li>subunit-stats: Print statistics for a subunit stream (how many successful tests, failed tests, skipped tests,&nbsp;etc)<\/li>\n<li>subunit-filter: E.g. remove test result or output from a&nbsp;stream<\/li>\n<li>subunit-diff: Compare two subunit streams and see what tests have started failing or are no longer&nbsp;failing<\/li>\n<li>subunit2pyunit: Format a subunit stream using Python&#8217;s standard unit test test result&nbsp;formatter<\/li>\n<\/ul>\n<p>We&#8217;re including the subunit tree in the Samba git tree at&nbsp;lib\/subunit.<\/p>\n<\/div>\n<div class=\"section\" id=\"tribunal\">\n<h2><a class=\"reference external\" href=\"http:\/\/launchpad.net\/tribunal\">tribunal<\/a><\/h2>\n<p>Tribunal is a <span class=\"caps\">GTK<\/span>+ viewer for subunit streams. It allows for easy browsing of test results. Tribunal is still a bit rough around the edges, although it should already be&nbsp;useful.<\/p>\n<p>Example&nbsp;usage:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span>$<span class=\"w\"> <\/span>make<span class=\"w\"> <\/span><span class=\"nb\">test<\/span>\n$<span class=\"w\"> <\/span>tribunal-subunit<span class=\"w\"> <\/span>st\/subunit\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<\/div>\n<div class=\"section\" id=\"testrepository\">\n<h2><a class=\"reference external\" href=\"http:\/\/launchpad.net\/testrepository\">testrepository<\/a><\/h2>\n<p>Test Repository provides a database of test results which fits into developers work flow and keeps track of useful information like what tests are failing, or which failures have the same&nbsp;backtrace.<\/p>\n<p>In particular Test Repository can re-run only the tests that failed in the previous test&nbsp;run:<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span>\n<span class=\"normal\">5<\/span>\n<span class=\"normal\">6<\/span>\n<span class=\"normal\">7<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span>$<span class=\"w\"> <\/span>testr<span class=\"w\"> <\/span>init\n<span class=\"c1\"># Run the full testsuite (1 hour goes by)<\/span>\n$<span class=\"w\"> <\/span>testr<span class=\"w\"> <\/span>run\n<span class=\"c1\"># Run those tests from the testsuite that failed in the previous run<\/span>\n<span class=\"c1\"># (this would be a lot shorter usually, depending on how many tests were<\/span>\n<span class=\"c1\"># failing)<\/span>\n$<span class=\"w\"> <\/span>testr<span class=\"w\"> <\/span>run<span class=\"w\"> <\/span>--failing\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p>testrepository is also still in its early days, but can potentially be very useful, e.g. when comparing old test runs on the <a class=\"reference external\" href=\"http:\/\/buildfarm.samba.org\/\">buildfarm<\/a>.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"conferences"}}]},{"title":"Working from\u00a0home","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/259-Working-from-home.html","rel":"alternate"}},"published":"2010-06-25T12:38:00+02:00","updated":"2010-06-25T12:38:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-06-25:259-Working-from-home.html","summary":"<p>For about 6 months now I&#8217;ve been working for <a class=\"reference external\" href=\"http:\/\/www.canonical.com\/\">Canonical<\/a> on the <a class=\"reference external\" href=\"http:\/\/launchpad.net\/soyuz\">Soyuz<\/a> component of <a class=\"reference external\" href=\"https:\/\/launchpad.net\/\">Launchpad<\/a>. Like most other engineers at Canonical I don&#8217;t work at the office but from a desk at home, as our nearest office is in London, not really a distance that is feasible for a commute. I do work at regular hours during work days and stay in touch with my colleagues using <span class=\"caps\">IRC<\/span> and voice over <span class=\"caps\">IP<\/span>.<\/p>\n<p>I did have some experience working on contracts and study assignments from home previously, but working a fulltime regular job has turned out to be a bigger challenge. It seems easy enough. No travel time, every day is <a class=\"reference external\" href=\"http:\/\/en.wikipedia.org\/wiki\/Casual_Friday\">casual Friday<\/a>, being able to listen to obscure death metal all day without driving coworkers crazy. Awesome,&nbsp;right?<\/p>\n<p>Well, not entirely. I can&#8217;t say I wasn&#8217;t warned beforehand (I was) but I still ran head-first into some of the common&nbsp;mistakes.<\/p>\n<div class=\"section\" id=\"solitude\">\n<h2>Solitude<\/h2>\n<p>I can work well by myself and I appreciate the occasional solitude, but it does get kinda lonely when you&#8217;re physically sitting by yourself for 8 hours a day, five days a&nbsp;week.<\/p>\n<p>Fortunately we regularly have sprints at different locations around the world and, apart from appealing to the travel junkie in me, that brings some essential face time with coworkers. Electronic communication mechanisms such as mailing lists, <span class=\"caps\">IRC<\/span>, Skype and, more recently, <a class=\"reference external\" href=\"http:\/\/mumble.sourceforge.net\/\">mumble<\/a> also help make the rest of the company feel closer, but it&#8217;s still very different from being able to talk to people at the water cooler (the point of which, btw, still escapes me. What&#8217;s wrong with proper cold tap&nbsp;water?).<\/p>\n<p>What also seems to help is going into the city and meeting up with others for lunch, or even just to get&nbsp;groceries.<\/p>\n<\/div>\n<div class=\"section\" id=\"concentration-work-times\">\n<h2>Concentration, work&nbsp;times<\/h2>\n<p>One of the nice things about working at home is that you&#8217;re quite flexible in planning your days; it&#8217;s possible to interrupt work to run an errand if necessary. The downside of it is that it is also really easy to get distracted, and there&#8217;s something I do very well: procrastinating. I initially ended up getting distracted quite often and then would end up working into the evening to make up for that lost time. The result being that, while only spending 8 hours doing actual work, it felt like having been at work for 12 hours in the end and having lost all spare time. Or as a friend summarized it accurately: working at home is all about&nbsp;boundaries.<\/p>\n<p>This is at least partially related to the fact that I am a compulsive multi-tasker; I always do several things at once and context-switch every minute or so (prompted by e.g. having to wait for code to compile), including checking email and responding to conversations on <span class=\"caps\">IRC<\/span> and Google Talk. This, among other things, has the effect that I respond quite slowly in <span class=\"caps\">IRC<\/span>\/<span class=\"caps\">IM<\/span> conversations; if you&#8217;ve ever chatted with me you&#8217;ve probably noticed it. Multi-tasking has always worked well for me - despite research suggesting otherwise - because software development always involves a lot of waiting (for vcses, compilers, testsuites,&nbsp;&#8230;).<\/p>\n<p>Recently I&#8217;ve tried to eliminate some of the other distractions by signing out off Skype, Empathy (Google Talk, <span class=\"caps\">MSN<\/span>, etc) and Google reader completely and only checking email a couple of times per&nbsp;day.<\/p>\n<\/div>\n<div class=\"section\" id=\"feeling-productive\">\n<h2>Feeling&nbsp;productive<\/h2>\n<p>What has perhaps surprised me most of all was how essential the satisfaction of getting something done is. After spending about a day staring at Python code it&#8217;s important for your mood to have accomplished <em>something<\/em>. This appears to be a vicious circle, as lack of progress kills the fun of work, which kills motivation, which causes a lack of&nbsp;progress.<\/p>\n<p>I am hard core, so during my first months I used my lunch breaks and evenings to hack on other free software projects, triaging bug reports that had come in or reviewing patches. Despite the fact that this is indeed technically a break from Launchpad, it didn&#8217;t (surprise!) seem to work as well as stepping away from the computer completely. Also, it turns out that spending 14 hours a day programming doesn&#8217;t make you all that much more productive than working a couple of hours&nbsp;less.<\/p>\n<p>What I&#8217;ve discovered recently is that getting at least one branch done by the end of each day, even if it&#8217;s just by fixing a trivial bug, helps tremendously in giving me some sense of accomplishment. Julian also wrote a blog post with some useful hints on <a class=\"reference external\" href=\"http:\/\/bigjools.wordpress.com\/2010\/02\/12\/feeling-productive\">feeling productive<\/a> a while&nbsp;ago.<\/p>\n<p>What is your experience working from home? Any good&nbsp;tips?<\/p>\n<p><em>Currently Playing: Sieges Even -&nbsp;Unbreakable<\/em><\/p>\n<\/div>\n","category":[{"@attributes":{"term":"real_life"}},{"@attributes":{"term":"launchpad"}},{"@attributes":{"term":"canonical"}}]},{"title":"Samba Summer of\u00a0Code","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/257-Samba-Summer-of-Code.html","rel":"alternate"}},"published":"2010-06-10T14:56:15+02:00","updated":"2010-06-10T14:56:15+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-06-10:257-Samba-Summer-of-Code.html","summary":"<p>As I have done in previous years, I am again participating in the\n<a class=\"reference external\" href=\"http:\/\/code.google.com\/soc\/\">Google Summer of Code<\/a> as mentor for the Samba&nbsp;project.<\/p>\n<p>Last year I <a class=\"reference external\" href=\"http:\/\/samba.org\/~abartlet\/\">Andrew<\/a> and I co-mentored three students with mixed results. In the end we had to drop one of our students but the other two did well. I&#8217;ve only taken on one student this year for various&nbsp;reasons.<\/p>\n<p>The amount of time required to mentor a student varies wildly depending on the student and is hard to predict based on their application. Some students seem to require quite a lot of mentoring while others are self-motivated and self-learning. This has not just been my experience, I&#8217;ve heard similar stories from fellow mentors on other&nbsp;projects.<\/p>\n<p>Last summer Ricardo worked on <a class=\"reference external\" href=\"http:\/\/github.com\/rvelhote\/GSoC-SWAT\"><span class=\"caps\">SWAT<\/span> for Samba 4<\/a> and he is still actively working on the project, even after the Summer of Code has finished. I hope to find the time to package <span class=\"caps\">SWAT<\/span> in time for <a class=\"reference external\" href=\"http:\/\/www.debian.org\/\">Debian<\/a> <a class=\"reference external\" href=\"http:\/\/www.debian.org\/releases\/testing\/\">Squeeze<\/a>. At the moment <span class=\"caps\">SWAT<\/span> just supports managing shares but Ricardo is working on user&nbsp;management.<\/p>\n<p>In 2009 Calin worked on the <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/SambaGtk\"><span class=\"caps\">GTK<\/span>+ frontends for Samba<\/a>, in particular changing them to be Python-based rather than C-based. This year his work is going to be continued by Sergio, hopefully with the some user-ready tools as the end&nbsp;result.<\/p>\n<p><em>Currently Playing: Gazpacho -&nbsp;117<\/em><\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"soc"}}]},{"title":"Proof of concept OpenChange server\u00a0working","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/256-Proof-of-concept-OpenChange-server-working.html","rel":"alternate"}},"published":"2010-06-08T19:09:08+02:00","updated":"2010-06-08T19:09:08+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-06-08:256-Proof-of-concept-OpenChange-server-working.html","summary":"<p>Seeing <a class=\"reference external\" href=\"http:\/\/openchange.org\/\">this<\/a> makes me very happy. It&#8217;s taken <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/index.php?option=com_content&amp;view=article&amp;id=24&amp;Itemid=15\">us<\/a> a couple of years to get to this point but we&#8217;ve finally made it, mostly thanks to the dedication and persistence of Julien and&nbsp;Brad.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"openchange"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Thoughts on the Nokia\u00a0N900","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/253-Thoughts-on-the-Nokia-N900.html","rel":"alternate"}},"published":"2010-04-17T06:30:00+02:00","updated":"2010-04-17T06:30:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-04-17:253-Thoughts-on-the-Nokia-N900.html","summary":"<p>Yesterday I started writing up a quick review of my new phone\/tablet, a Nokia\nN900. Unfortunately it has since broken down by what appears to be a hardware\nissue. It does still work to a certain degree, as the leds flash and I\ncan access it as a <span class=\"caps\">USB<\/span> mass-storage device, but the screen hasn&#8217;t shown\nanything since I woke up this morning. The timing could not have been worse, as\nI&#8217;m currently abroad and having a phone (as well as a <span class=\"caps\">GPS<\/span>) would be useful,\nespecially considering the ash cloud situation in&nbsp;Iceland.<\/p>\n<p><em>Update<\/em>: 4 weeks after dropping my phone off at the Nokia care center I have\nreceived a new N900; they weren&#8217;t able to tell me what was wrong with the old&nbsp;one.<\/p>\n<p>Anyway, my thoughts about the N900. Please note that I haven&#8217;t used a lot of\nother smartphones, so I can&#8217;t really compare this with Android phones or&nbsp;iPhones.<\/p>\n<div class=\"section\" id=\"the-good\">\n<h2>The&nbsp;good<\/h2>\n<p>The integration between the different components of the phone is really well\ndone. Nokia has invested heavily in Telepathy, which is used for all voice and\ntext messaging, and it shows. Skype and regular telephony are very nicely\nintegrated with telepathy, albeit through proprietary daemons. There is one\nglobal status for all protocols. Skype and <span class=\"caps\">SIP<\/span> conferencing work&nbsp;well.<\/p>\n<p>The address book is another thing that is very nicely integrated with the rest\nof the device. It combines <span class=\"caps\">IM<\/span> addresses, phone numbers, email addresses and\nother information for a contact and there are third party applications that can\nhelp keep that information up to&nbsp;date.<\/p>\n<p>Both the Ovi maps app and its data are free, and it&#8217;s possible to copy the maps\nonto the device so you don&#8217;t need to stream them all from the internet when\nyou&#8217;re abroad. It&#8217;s pretty quick compared to e.g. a Garmin <span class=\"caps\">GPS<\/span>, but lacks\nfeatures. It can&#8217;t load <span class=\"caps\">GPX<\/span> files, can&#8217;t show points of interest, store tracks,&nbsp;etc.<\/p>\n<p>The music player is neat and automatically indexes all audio and video files\nthat are copied onto the device. The camera and photo manager work well, and\nare reasonably&nbsp;snappy.<\/p>\n<p>The web browser displays all pages I&#8217;ve accessed so far without rendering\nissues, including&nbsp;flash.<\/p>\n<p>There are quite a lot of neat third-party free software applications available\n- eCoach, Hermes, grr, mBarcode, Mauku, tubes, tuner,&nbsp;fahrplan.<\/p>\n<\/div>\n<div class=\"section\" id=\"the-bad\">\n<h2>The&nbsp;bad<\/h2>\n<p>Maemo is Linux-based and it has a lot of similarities to your average\nDebian-derived distribution. Despite that, it contains a lot of proprietary\nsoftware. In particular, the Skype and <span class=\"caps\">POT<\/span> plugins for telepathy, the address\nbook and things like Ovi Maps are proprietary. This means it&#8217;s impossible for\nme to fix little annoyances (see below) in these packages, but more\nimportantly, it&#8217;s impossible for others to fix these little annoyances or port\nthese apps to the desktop and other devices (where there&#8217;s an even larger pool\nof potential bug&nbsp;fixers).<\/p>\n<p>The <span class=\"caps\">GPS<\/span> doesn&#8217;t work very well. This might be due to the fact that the hardware\nis substandard, but I suspect it has got more to do with the fact that if it\ndoes not find a signal within 30 seconds it will switch itself off. I assume\nthis is to save energy, but this behaviour can not be switched off anywhere. A\nworkaround is to close and reopen Ovi Maps every 15 seconds or so, but that&#8217;s\npretty annoying. I&#8217;m sure somebody with access to the source (I don&#8217;t!) can fix&nbsp;it.<\/p>\n<p>I&#8217;m sure the calendaring app is nice, but it lacks support for synchronization\nwith Google calendar, which makes it unusable for&nbsp;me.<\/p>\n<p>The standard email client does work, but it doesn&#8217;t scale well. It will lock\nup at times while trying to index mailboxes. I&#8217;ve tried using claws mail for a\nwhile, but its interface is just too cumbersome - in general, but in particular\non such a small&nbsp;screen.<\/p>\n<p>The battery lifetime sucks. If I&#8217;m lucky I can make it through a single day with\na fully charged battery, with only mild usage. The form factor is also still\na minor issue for me, but I doubt that bit can be fixed in&nbsp;software.<\/p>\n<p>Overall I&#8217;m pretty happy with the N900, although I&#8217;m not sure if I would pick\nit over an Android phone&nbsp;again.<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"real_life"}},{"@attributes":{"term":"es"}},{"@attributes":{"term":"n900"}},{"@attributes":{"term":"nokia"}}]},{"title":"Nostalgia: 10 Years of Samba\u00a0Hacking","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/250-Nostalgia-10-Years-of-Samba-Hacking.html","rel":"alternate"}},"published":"2010-02-11T04:32:00+01:00","updated":"2010-02-11T04:32:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-02-11:250-Nostalgia-10-Years-of-Samba-Hacking.html","summary":"<p>While searching for something else I happened to come across <a class=\"reference external\" href=\"http:\/\/lists.samba.org\/archive\/samba-ntdom\/2000-November\/016339.html\">one of my first posts to the ntdom list<\/a> in November&nbsp;2000.<\/p>\n<p>My post is a simple question about a Samba crash that I myself no doubt had introduced. I&#8217;m sure I could have found a solution to it by using Google -  excuse me, <a class=\"reference external\" href=\"http:\/\/www.altavista.com\/\">AltaVista<\/a> - but I still received a friendly reply from <a class=\"reference external\" href=\"http:\/\/plainjoe.org\/\">Jerry<\/a> explaining me to use <a class=\"reference external\" href=\"http:\/\/www.gnu.org\/software\/gdb\/\"><span class=\"caps\">GDB<\/span><\/a>. I&#8217;m not too embarrassed, at least I used proper punctuation and already wrote somewhat comprehensible English back&nbsp;then.<\/p>\n<p>It&#8217;s also strange to realize it&#8217;s already been almost ten years since I started hacking on <a class=\"reference external\" href=\"http:\/\/www.samba.org\/\">the Samba project<\/a>.<\/p>\n","category":{"@attributes":{"term":"samba"}}},{"title":"Linux.Conf.Au 2010 - Day 3 -\u00a0Wednesday","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/248-Linux.Conf.Au-2010-Day-3-Wednesday.html","rel":"alternate"}},"published":"2010-02-04T00:06:17+01:00","updated":"2010-02-04T00:06:17+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-02-04:248-Linux.Conf.Au-2010-Day-3-Wednesday.html","summary":"<p>I went to Jonathan Corbet&#8217;s yearly update of the status of the Linux kernel. He\ntalked about the various big changes that went into the kernel over the last\nyear as well as the development processes. The Linux kernel is probably one of\nthe largest open source projects, and very healthy - there are a lot of\nindividuals and companies contributing to it. With this size comes a few\ninteresting challenges coping with the flow of changes into Linus&#8217; tree. Their\ncurrent processes seem to deal with this quite well, and don&#8217;t seem to need a\nlot of major changes at the&nbsp;moment.<\/p>\n<p>His talk also included the obligatory list of features that landed in the last\nyear. The only one that really matters to me is the Nouveau driver, which I&#8217;m\nlooking forward to trying&nbsp;out.<\/p>\n<p>The second talk I went to in the morning was Selena Deckelmann&#8217;s overview of\nthe Open Source database landscape. She mentioned there&#8217;s new projects started\ndaily, but it was still a bit disappointing not to see <span class=\"caps\">TDB<\/span> up&nbsp;there.<\/p>\n<p>After lunch Rob gave a talk about Subunit, introducing to the ideas behind the\nSubunit protocol as well as presenting an overview of the tools that are\navailable for it and the projects that have Subunitized as of yet. It&#8217;s\nexciting to see the Subunit universe slowly growing, I wasn&#8217;t aware of some of\nthe projects that are using it. The recently announced <a class=\"reference external\" href=\"http:\/\/launchpad.net\/testrepository\">testrepository<\/a> also looks interesting, even though it is still very rudimentary at the&nbsp;moment.<\/p>\n<p>In the evening <a class=\"reference external\" href=\"http:\/\/en.wikipedia.org\/wiki\/Andrew_Tridgell\">Tridge<\/a>, <a class=\"reference external\" href=\"http:\/\/en.wikipedia.org\/wiki\/Rusty_Russell\">Rusty<\/a>, <a class=\"reference external\" href=\"http:\/\/samba.org\/~abartlet\">Andrew<\/a>, <a class=\"reference external\" href=\"http:\/\/en.wikipedia.org\/wiki\/Jeremy_Allison\">Jeremy<\/a>, <a class=\"reference external\" href=\"http:\/\/en.wikipedia.org\/wiki\/Anthony_Towns\"><span class=\"caps\">AJ<\/span><\/a> and I participated in the <a class=\"reference external\" href=\"http:\/\/hackoff.lca2010.org.nz\/\">hackoff<\/a> as the &#8220;Samba&nbsp;Team&#8221;.<\/p>\n<p>The hackoff was a lot of fun, and consisted of 6 problems, each of which involved somehow decoding the data file for the problem and extracting a short token from it in one way or another, which was required to retrieve the next problem. We managed to solve 4 problems in the hour that the organizers had allocated, and ended first because we were a bit quicker in solving the 4th problem than the runner-ups. No doubt the fact that we were the largest team had something to do with&nbsp;this.<\/p>\n<p>I hung out with some of the awesome <a class=\"reference external\" href=\"http:\/\/www.git-scm.com\/\">Git<\/a> and <a class=\"reference external\" href=\"http:\/\/www.github.com\/\">Github<\/a> developers in the Malthouse in the evening, and talked about <a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/dulwich\">Dulwich<\/a>, <a class=\"reference external\" href=\"http:\/\/bazaar.canonical.com\/\">Bazaar<\/a> and <a class=\"reference external\" href=\"http:\/\/launchpad.net\/\">Launchpad<\/a> (&#8220;No <em>really<\/em>, I am not aware of any plans to add Git support to&nbsp;Launchpad.&#8221;).<\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"nz"}},{"@attributes":{"term":"git"}},{"@attributes":{"term":"lca"}}]},{"title":"Linux.Conf.Au 2010 - Day 2 -\u00a0Tuesday","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/247-Linux.Conf.Au-2010-Day-2-Tuesday.html","rel":"alternate"}},"published":"2010-02-03T19:44:24+01:00","updated":"2010-02-03T19:44:24+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-02-03:247-Linux.Conf.Au-2010-Day-2-Tuesday.html","summary":"<p>On Tuesday we had our &#8220;Launchpad&#8221; mini-conf, which featured talks from\nLaunchpad developers and users alike. It wasn&#8217;t necessarily about\nhosting projects on Launchpad, but rather about how various projects could\nbenefit from&nbsp;Launchpad.<\/p>\n<p>I popped out of the Launchpad track for a bit to attend <a class=\"reference external\" href=\"http:\/\/sysadmin.miniconf.org\/presentations10.html#04\">Andrews talk about the\ncurrent status of Samba 4<\/a>. He did a nice job of summarizing the events in the\nlast year, the most of import one of course being the support for <span class=\"caps\">DC<\/span>\nsynchronization. I&#8217;m proud we&#8217;ve finally managed to pull this off - and\nhopefully we&#8217;ll actually have a beta out next year. We have been saying &#8220;maybe\nnext year&#8221; for almost 4 years now when people asked us for estimates of a\nrelease&nbsp;date.<\/p>\n<p>At the end of the day Aaron and I gave a quick introduction to\nLaunchpad&#8217;s code imports and code&nbsp;reviews.<\/p>\n","category":[{"@attributes":{"term":"nz"}},{"@attributes":{"term":"launchpad"}},{"@attributes":{"term":"lca"}}]},{"title":"Linux.Conf.Au 2010 - Day\u00a01","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/246-Linux.Conf.Au-2010-Day-1.html","rel":"alternate"}},"published":"2010-02-03T18:15:45+01:00","updated":"2010-02-03T18:15:45+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-02-03:246-Linux.Conf.Au-2010-Day-1.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/www.lca2010.org.nz\/\">Linux.Conf.Au<\/a> has a reputation for being one of the best <span class=\"caps\">FLOSS<\/span> conferences\nin the world, and it more than lived up to my high expectations. The <a class=\"reference external\" href=\"http:\/\/www.linux.org.au\/conf\/2006\/\">last\none<\/a> I attended was also in New Zealand, but further south - in&nbsp;Dunedin.<\/p>\n<div class=\"section\" id=\"day-1-monday\">\n<h2>Day 1 -&nbsp;Monday<\/h2>\n<p>As usual the actual conference was preceded by two days of miniconfs.\nOn the first day I attended some of the talks in the Open Languages&nbsp;track.<\/p>\n<p>mwhudson gave a talk about <a class=\"reference external\" href=\"http:\/\/codespeak.net\/pypy\/dist\/pypy\/doc\/\">pypy<\/a> - Python implemented in <a class=\"reference external\" href=\"http:\/\/www.python.org\/\">Python<\/a>. He\ndiscussed the reasons for doing what they do and the progress they&#8217;ve made so\nfar. Like so many of the custom Python implementations, one of the main things\nthat&#8217;s holding them back is the lack of support for the extensions written in C\nfor&nbsp;CPython.<\/p>\n<p><a class=\"reference external\" href=\"http:\/\/en.wikipedia.org\/wiki\/Rusty_Russell\">Rusty<\/a> gave a quick tutorial to <a class=\"reference external\" href=\"http:\/\/talloc.samba.org\">talloc<\/a> after lunch (&#8220;it&#8217;s a shame K&amp;R\ndidn&#8217;t think of this!&#8221;) and explained why it&#8217;s so&nbsp;great.<\/p>\n<p>In the afternoon I caught some of the talks in the <a class=\"reference external\" href=\"http:\/\/distrosummit.org\/\">distro summit<\/a> track. Both\nof the sessions that I attended happened to be Ubuntu-related - first Dustin\ngave a quick introduction to the components of Launchpad, followed by a talk\nfrom Lucas about the relationship between <a class=\"reference external\" href=\"http:\/\/www.ubuntu.com\/\">Ubuntu<\/a> and <a class=\"reference external\" href=\"http:\/\/www.debian.org\/\">Debian<\/a>. There was a\ndiscussion afterwards about interoperability between the various hosting sites\nand bug trackers.  Several audience members questioned the relevance of Debian\nand suggested everything should just switch to Launchpad, but this seemed to be\nfounded in ignorance. (For the record, none were actually Launchpad&nbsp;developers).<\/p>\n<\/div>\n","category":[{"@attributes":{"term":"nz"}},{"@attributes":{"term":"launchpad"}},{"@attributes":{"term":"lca"}}]},{"title":"Build from\u00a0branch","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/245-Build-from-branch.html","rel":"alternate"}},"published":"2010-02-01T16:49:10+01:00","updated":"2010-02-01T16:49:10+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2010-02-01:245-Build-from-branch.html","summary":"<p>At the moment I am returning home after three very productive and awesome weeks\nin Wellington, Sydney and&nbsp;Strasbourg.<\/p>\n<p>I spent the first week in the West Plaza in Wellington, working together with fellow Launchpad developers <a class=\"reference external\" href=\"http:\/\/bigjools.wordpress.com\/2010\/01\/22\/success-in-wellington\/\">on getting the basics of building from branches working<\/a>. We eventually managed to get something working at the end of Friday afternoon. We split the work up at the beginning of the week and then worked on it in pairs for a couple of days before integrating all work on Friday. At the end of the week <a class=\"reference external\" href=\"http:\/\/launchpad.net\/~wgrant\">William<\/a> managed to get a basic source package build from recipe through the&nbsp;queue.<\/p>\n<p>Pair-programming with <a class=\"reference external\" href=\"http:\/\/launchpad.net\/~jml\">Jono<\/a> and <a class=\"reference external\" href=\"http:\/\/launchpad.net\/~mwhudson\">Michael<\/a> was very educational, I suspect I&#8217;ll be a fair bit quicker when I get back to hacking on Launchpad by myself. It&#8217;s scary to see how some people can make the changes that would take me a full day in a mere&nbsp;hour.<\/p>\n<p><a class=\"reference external\" href=\"http:\/\/launchpad.net\/~thumper\">Tim<\/a> picked up my initial work on support for Mercurial imports and completed\nand landed it during the sprint. Since the rollout on Wednesday it is possible\nto request Mercurial imports on Launchpad. Most imports (e.g. mutt, dovecot,\nhg) seem to work fine, with the main exception being the really large Mercurial\nrepositories such as OpenOffice.org and OpenJDK. This is because of (known)\nscaling issues that will be fixed in one of the next releases of <a class=\"reference external\" href=\"http:\/\/launchpad.net\/bzr-hg\">bzr-hg<\/a>.<\/p>\n<p>This was the first time I was back in Wellington since 2006, and the weather\nthis year was exactly as I remembered it; showers and wind, with the occasional\nday of sunshine. For a capital the city centre is quite small, but it has its\ncharm and the view from the various hills around the bay is&nbsp;amazing.<\/p>\n<p>On the weekend I met up with <a class=\"reference external\" href=\"http:\/\/samba.org\/~abartlet\">Andrew<\/a> and Kirsty and we did some hiking around\nWellington (where the weather allowed&nbsp;it).<\/p>\n","category":[{"@attributes":{"term":"nz"}},{"@attributes":{"term":"de"}},{"@attributes":{"term":"au"}},{"@attributes":{"term":"fr"}},{"@attributes":{"term":"launchpad"}},{"@attributes":{"term":"travel"}}]},{"title":"My first week as a Launchpad developer:\u00a0impressions","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/244-My-first-week-as-a-Launchpad-developer-impressions.html","rel":"alternate"}},"published":"2009-12-10T20:10:17+01:00","updated":"2009-12-10T20:10:17+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-12-10:244-My-first-week-as-a-Launchpad-developer-impressions.html","summary":"<p>Roughly a week ago I joined Julian, Muharem and Michael, working on the <a class=\"reference external\" href=\"https:\/\/launchpad.net\/soyuz\">Soyuz<\/a> component of <a class=\"reference external\" href=\"https:\/\/launchpad.net\/\">Launchpad<\/a>. For now I&#8217;ve been working on easy Soyuz bugs, as a way of becoming more familiar with the internals. I&#8217;m working from home but I had the chance to hang out with some of the other Launchpad developers, including the full Soyuz team, at <a class=\"reference external\" href=\"http:\/\/wiki.ubuntu.com\/UDS-L\"><span class=\"caps\">UDS<\/span> Lucid<\/a> in&nbsp;Dallas.<\/p>\n<p>Launchpad is different from most other <span class=\"caps\">FOSS<\/span> projects I have worked on so far. Some things I noticed during my first&nbsp;week:<\/p>\n<p>The codebase is big and well tied together. I don&#8217;t think I&#8217;ve ever used grep and ctags as often as I have in the last week. Fortunately, the directory structure makes it relatively easy to predict where to look for&nbsp;things.<\/p>\n<p>Reviews are really quick - no long round-trips between author and reviewer trying to get a branch landed. This is a really <em>really<\/em> great&nbsp;thing.<\/p>\n<p>It&#8217;s easy to find somebody familiar with a particular piece of code and it doesn&#8217;t take long to get an answer when you ask questions. I&#8217;m still getting used to this - I tend to ask questions sporadically because I have gotten used to having to wait a couple of days for an answer that&#8217;s actually&nbsp;useful.<\/p>\n<p>Setting up the development environment takes some time. Or perhaps I&#8217;m spoiled by Bazaar where &#8220;bzr branch lp:bzr bzr &amp;&amp; .\/bzr\/bzr selftest&#8221; is all you need to start hacking. And it seems like karmic is the only platform on which things work - I tried with Debian Sid and Lucid as well, but things broke in strange and unusual&nbsp;ways.<\/p>\n<p>The test suite is heavy and takes long to start up, something that makes proper <span class=\"caps\">TDD<\/span> too hard. I also managed to run into some unexplainable problems where the librarian wouldn&#8217;t shut down on one of my systems. Since there is only one instance of the database it is not really possible to run multiple instances of the testsuite at the same time unless you use chroots or something like that - this makes it hard to work on multiple branches at the same time, something which would especially be nice since the testsuite is slow (so you can run the testsuite in one branch, hack in another and&nbsp;alterate).<\/p>\n<p>Doctests, while fast, a bit of a nuisance. Because of the setup\/teardown overhead that is paid for every single test, doc tests are a lot faster than unit tests. On the other hand, pdb doesn&#8217;t play well with doc tests - it doesn&#8217;t show any context. Conceptually I also prefer small unit tests over doc tests, since they&#8217;re quicker to read, easier to understand and there&#8217;s less side-effects from previous instructions in the test that could affect the code that&#8217;s being&nbsp;tested.<\/p>\n<p>And for those that know me well; yes, getting used to somewhat regular working hours was indeed a challenge, but I seem to have&nbsp;managed.<\/p>\n","category":{"@attributes":{"term":"launchpad"}}},{"title":"US:\u00a0Observations","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/242-US-Observations.html","rel":"alternate"}},"published":"2009-10-30T16:54:00+01:00","updated":"2009-10-30T16:54:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-10-30:242-US-Observations.html","summary":"<p>These past few days in the <span class=\"caps\">US<\/span> were a bit of a rollercoaster. Some random&nbsp;observations:<\/p>\n<ul class=\"simple\">\n<li>The mentor summit was very nice and well organized (or rather: well disorganized). Lots of awesome people around from a wide variety of projects and&nbsp;nationalities.<\/li>\n<li><span class=\"dquo\">&#8220;<\/span>Next Generation <span class=\"caps\">VCS<\/span>&#8221; seems to be an alias for git these days in the minds of most&nbsp;people.<\/li>\n<li>I didn&#8217;t write a single line of code in almost a week, something that is very&nbsp;rare.<\/li>\n<li>Driving an automatic gives you two spare limbs to use for other things. What those other things are, I have yet to figure&nbsp;out.<\/li>\n<li>Is the fact that your kid was student of the month or the fact that you own two cats and a dog really something that belongs on a bumper&nbsp;sticker?<\/li>\n<li>Gas is cheap (compared to Europe). I drove 300 miles on a $30&nbsp;tank.<\/li>\n<li>The malls in the Bay Area are some of the biggest I&#8217;ve ever seen, but strangely enough they seem to lack both book- and&nbsp;cd-stores.<\/li>\n<li>It is legal to turn right on a red traffic sign in California unless otherwise indicated. It took me a while to realize this until people repeatedly started honking behind&nbsp;me&#8230;<\/li>\n<li>The waiver I had to sign to be able to skydive in California was scary. I can live with my operating system coming without implied warranty or fitness for a particular purpose, but my&nbsp;parachute?<\/li>\n<li>I stopped pretending to have any regularity in my sleeping habits. 6 <span class=\"caps\">AM<\/span> flights? It seemed like a good idea at the&nbsp;time.<\/li>\n<\/ul>\n","category":[{"@attributes":{"term":"soc"}},{"@attributes":{"term":"usa"}}]},{"title":"CtrlProxy: Looking for a new\u00a0maintainer","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/241-ctrlproxy-looking-for-a-new-maintainer.html","rel":"alternate"}},"published":"2009-09-13T21:26:13+02:00","updated":"2009-09-13T21:26:13+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-09-13:241-ctrlproxy-looking-for-a-new-maintainer.html","summary":"<p>After over 7 years of working on it off and on, I&#8217;m looking for somebody to\nhelp maintain (and eventually take over)  <a class=\"reference external\" href=\"http:\/\/www.ctrlproxy.org\/\">CtrlProxy<\/a>. I started working on\nCtrlProxy somewhere in 2002, only a short while after Wilmer started hacking on\n<a class=\"reference external\" href=\"http:\/\/www.bitlbee.org\/\">BitlBee<\/a>. If I remember correctly I started working on it because I didn&#8217;t\nwant to run a separate dircproxy (the only real competitor at the time)\ninstance (with configuration) for each <span class=\"caps\">IRC<\/span> network that I connected to. It was\nalso just a good excuse to play with the <span class=\"caps\">IRC<\/span> protocol a&nbsp;bit.<\/p>\n<p>Over the years, CtrlProxy has served as a playground for me to try out new and\ninteresting things. It&#8217;s been rewritten or severely refactored several times in\nits early history, the latest time being the 3.0 release (from 2005).  I&#8217;ve\ntried different build systems, I&#8217;ve tried different implementation languages,\nI&#8217;ve tried different configuration file formats, I&#8217;ve tried different support\nlibraries, I&#8217;ve tried different version control systems, I&#8217;ve tried different\ndocumentation formats. So while it&#8217;s definitely been a very educational project\nfor me personally, I haven&#8217;t really had the time or the interest to dedicate to\nthe project that it deserved during the last few years. This was mostly because\n<a class=\"reference external\" href=\"http:\/\/www.samba.org\/\">there<\/a> <a class=\"reference external\" href=\"http:\/\/www.wireshark.org\/\">were<\/a> <a class=\"reference external\" href=\"http:\/\/www.ubuntu.com\/\">other<\/a> <a class=\"reference external\" href=\"http:\/\/www.debian.org\/\">more<\/a> <a class=\"reference external\" href=\"http:\/\/www.bitlbee.org\/\">interesting<\/a> <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/\"><span class=\"caps\">FOSS<\/span><\/a> <a class=\"reference external\" href=\"http:\/\/bazaar-vcs.org\/\">projects<\/a> I spent my\nspare cycles&nbsp;on.<\/p>\n<p>These days there are plenty of other good <span class=\"caps\">IRC<\/span> proxies out there, such as\n<a class=\"reference external\" href=\"http:\/\/bip.t1r.net\/\"><span class=\"caps\">BIP<\/span><\/a>, so I doubt CtrlProxy will be missed if it were to disappear. Despite\nthat, if anybody is interested in taking over, please send me an email\n(<a class=\"reference external\" href=\"mailto:jelmer&#64;samba.org\">jelmer&#64;samba.org<\/a>) or contact me on <span class=\"caps\">IRC<\/span> (jelmer on the <span class=\"caps\">OFTC<\/span> and Freenode&nbsp;networks).<\/p>\n<p><em>Currently Playing: Anathema - Shroud of&nbsp;False<\/em><\/p>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"ctrlproxy"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Summer of Code\u00a02009","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/239-Summer-of-Code-2009.html","rel":"alternate"}},"published":"2009-09-11T14:22:06+02:00","updated":"2009-09-11T14:22:06+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-09-11:239-Summer-of-Code-2009.html","summary":"<p>For this years (the fifth?) <a class=\"reference external\" href=\"http:\/\/code.google.com\/soc\/\">Summer of Code<\/a>, I participated once again as a mentor for the Samba and OpenChange&nbsp;projects.<\/p>\n<p>Samba was assigned four slots this year: one was a <span class=\"caps\">CIFSFS<\/span> project mentored by\nSteve French and the other three were Python projects related to Samba 4,\nco-mentored by <a class=\"reference external\" href=\"http:\/\/samba.org\/~abartlet\/\">Andrew<\/a> and me. Our students did very well this year, although\nwe unfortunately had to drop one after the mid-term evaluations due to lack of\neffort. Nonetheless, we&#8217;re very happy with the results of the other two&nbsp;projects:<\/p>\n<p>Calin Crisan (France) converted the rest of the applications in <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/SambaGtk\">SambaGtk<\/a> to Python, and worked on a <span class=\"caps\">GTK<\/span>+ user manager for Samba and Windows. With his improvements, it is now possible to edit registries, manage users, inspect the endpoint mapper, plan tasks and manage services on a remote Windows machine using a <span class=\"caps\">GTK<\/span>+ application on a Linux&nbsp;workstation.<\/p>\n<p>Ricardo Velhote (Portugal) designed and implemented a new version of <span class=\"caps\">SWAT<\/span> - the Samba Web Administration Tool. Unlike the old <span class=\"caps\">SWAT<\/span>, his implementation is more than just a simple web-based editor for smb.conf. As we were expecting at the start of the Summer of Code, not all of the functionality could be implemented properly in a couple of months, not while getting the design and infrastructure right. With a basic version working, we now hope the remaining subsystems can be contributed with help from the&nbsp;community.<\/p>\n<p>I&#8217;m planning to merge Calin&#8217;s improvements to Samba-Gtk into the mainline in the next month or so. <span class=\"caps\">SWAT<\/span> is a standalone application and will continue to live as a separate project, while being a part of the Samba ecosystem. Congratulations, Calin and&nbsp;Ricardo!<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"soc"}}]},{"title":"DebCamp \/\u00a0DebConf9","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/237-DebCamp-DebConf9.html","rel":"alternate"}},"published":"2009-07-22T23:38:01+02:00","updated":"2009-07-22T23:38:01+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-07-22:237-DebCamp-DebConf9.html","summary":"<p>So far I&#8217;m very much enjoying my first <a class=\"reference external\" href=\"http:\/\/debconf9.debconf.org\/\">DebCamp \/ DebConf<\/a>. It&#8217;s nice to finally meet a lot of people in person that I have worked together with or talked to on <span class=\"caps\">IRC<\/span> in the last few years.  C\u00e1ceres is a relatively small town with a nice old city&nbsp;center.<\/p>\n<p>I arrived early for DebCamp and spent the first few days here working on fixing bugs in the Bazaar and Samba packages as well as discussing the integration between Samba 4 and Kerberos with <a class=\"reference external\" href=\"http:\/\/www.painless-security.com\/blog\/\">Sam<\/a> (both in general and on Debian specifically). In trying to set up a Samba 4 domain we found a number of bugs in the provisioning script, most of which seem to be fixed&nbsp;now.<\/p>\n<p>In the last few days I&#8217;ve mostly worked on getting Samba 4 and OpenChange ready to go into Sid (they&#8217;re in experimental only at the moment) and have discussed bzr-builddeb and related Bazaar issues with <a class=\"reference external\" href=\"http:\/\/jameswestby.net\/weblog\">James<\/a>.<\/p>\n<p><em>Currently Playing: Pixies -&nbsp;Velouria<\/em><\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"krb5"}},{"@attributes":{"term":"es"}}]},{"title":"DebConf","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/234-DebConf.html","rel":"alternate"}},"published":"2009-07-04T13:46:16+02:00","updated":"2009-07-04T13:46:16+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-07-04:234-DebConf.html","summary":"<img alt=\"\" class=\"align-left\" src=\"http:\/\/media.debconf.org\/dc9\/images\/debconf9-going-to.png\" \/>\n<p>I&#8217;m looking forward to going to my first DebCamp\/DebConf. I won&#8217;t be giving a talk, but I hope to work together with others on integrating Samba 3 and 4 better with the rest of the system and <span class=\"caps\">VCS<\/span>&nbsp;integration.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"travel"}},{"@attributes":{"term":"krb5"}},{"@attributes":{"term":"openchange"}},{"@attributes":{"term":"es"}}]},{"title":"\u201cFranky\u201d Talk at\u00a0SambaXP","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/233-Franky-Talk-at-SambaXP.html","rel":"alternate"}},"published":"2009-06-04T00:51:00+02:00","updated":"2009-06-04T00:51:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-06-04:233-Franky-Talk-at-SambaXP.html","summary":"<p>I&#8217;ll be giving a talk at the next <a class=\"reference external\" href=\"http:\/\/www.nllgg.nl\/\"><span class=\"caps\">NLLGG<\/span><\/a> <a class=\"reference external\" href=\"http:\/\/www.nllgg.nl\/bijeenkomst_20090606\">meeting<\/a> about <a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Franky\">the Franky project<\/a>.<\/p>\n<p><strong>Update<\/strong>: <a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/samba-nllgg2009.pdf\">Slides<\/a><\/p>\n","category":{"@attributes":{"term":"samba"}}},{"title":"SambaXP\u00a02009","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/228-SambaXP-2009.html","rel":"alternate"}},"published":"2009-04-20T00:27:00+02:00","updated":"2009-04-20T00:27:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-04-20:228-SambaXP-2009.html","summary":"<p>Last week most of the Samba team met again for our annual conference in G\u00f6ttingen. It was nice seeing everybody again, specially the folks I hadn&#8217;t seen since the last&nbsp;one.<\/p>\n<p>Together with Andrew and his wife Kirsty I took the train from Amsterdam into\nGermany a couple of days early and we did some sightseeing together with\nAnatoli and Nadezhda during the weekend. There&#8217;s still plenty of things to\ndiscover in G\u00f6ttingen for me, even though I&#8217;ve already been there about two\ndozen times. We did a tour of the city walls, visited some of the churches and\nclimbed the&nbsp;tower.<\/p>\n<p>Julien&#8217;s talk about OpenChange was interesting and humorous as always. Volkers&#8217;\ntutorial on asynchronous programming in C. Even though I&#8217;ve spent quite some\ntime working with and looking at these <span class=\"caps\">API<\/span>&#8217;s it was nice going through them\nstep by step once again. It&#8217;s a strange thing to wrap your head&nbsp;around.<\/p>\n<p>Andrew and I also gave our yearly <a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/samba4-status-xp09.pdf\">&#8220;State of Samba 4&#8221;<\/a> talk again. As I&#8217;ve\nmentioned in other places, I&#8217;m really excited about the social effects of the\n<a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Franky\">Franky<\/a> project. Once again I was\nreminded that giving a talk the morning after the conference party (this year\nin the &#8220;Oriental Lounge&#8221;) is a bad&nbsp;idea.<\/p>\n<p>Several of my fellow Debian Samba maintainers made it to SambaXP, it was nice to see Christian, Luk, Michael and No\u00ebl there. We made some decisions about the direction of the Samba packages, and a plan to allow the Samba 3 and Samba 4 packages to be installed on the same system. Unfortunately I had to miss <a class=\"reference external\" href=\"http:\/\/www.perrier.eu.org\/weblog\/2009\/05\/24#samba-news-200905224\">Christian&#8217;s talk<\/a> because it was in the same timeslot as Jeff&#8217;s talk about the <span class=\"caps\">CIFS<\/span> kernel&nbsp;module.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"travel"}},{"@attributes":{"term":"de"}}]},{"title":"Finally a DD","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/227-Finally-a-DD.html","rel":"alternate"}},"published":"2009-01-15T20:53:20+01:00","updated":"2009-01-15T20:53:20+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2009-01-15:227-Finally-a-DD.html","summary":"<p>After spending a little bit more than three years in the Debian New Maintainers\nqueue, I have finally become a Debian&nbsp;Developer.<\/p>\n<p>Many thanks to the various people who have helped me through <span class=\"caps\">NM<\/span> and have\nsponsored my uploads over the past few&nbsp;years.<\/p>\n","category":{"@attributes":{"term":"debian"}}},{"title":"bzr-builddeb FTW","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/226-bzr-builddeb-FTW.html","rel":"alternate"}},"published":"2008-11-07T18:01:30+01:00","updated":"2008-11-07T18:01:30+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-11-07:226-bzr-builddeb-FTW.html","summary":"<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\"> 1<\/span>\n<span class=\"normal\"> 2<\/span>\n<span class=\"normal\"> 3<\/span>\n<span class=\"normal\"> 4<\/span>\n<span class=\"normal\"> 5<\/span>\n<span class=\"normal\"> 6<\/span>\n<span class=\"normal\"> 7<\/span>\n<span class=\"normal\"> 8<\/span>\n<span class=\"normal\"> 9<\/span>\n<span class=\"normal\">10<\/span>\n<span class=\"normal\">11<\/span>\n<span class=\"normal\">12<\/span>\n<span class=\"normal\">13<\/span>\n<span class=\"normal\">14<\/span>\n<span class=\"normal\">15<\/span>\n<span class=\"normal\">16<\/span>\n<span class=\"normal\">17<\/span>\n<span class=\"normal\">18<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span>%<span class=\"w\"> <\/span>bzr<span class=\"w\"> <\/span>branch<span class=\"w\"> <\/span>deb:line6-usb-source<span class=\"w\"> <\/span>debian\nRetrieving<span class=\"w\"> <\/span>Vcs<span class=\"w\"> <\/span>locating<span class=\"w\"> <\/span>from<span class=\"w\"> <\/span>line6-usb-source<span class=\"w\"> <\/span>Debian<span class=\"w\"> <\/span>version<span class=\"w\"> <\/span><span class=\"m\">0<\/span>.7.4-1\nBranched<span class=\"w\"> <\/span><span class=\"m\">354<\/span><span class=\"w\"> <\/span>revision<span class=\"o\">(<\/span>s<span class=\"o\">)<\/span>.\n%<span class=\"w\"> <\/span>bzr<span class=\"w\"> <\/span>merge-upstream<span class=\"w\"> <\/span>https:\/\/line6linux.svn.sourceforge.net\/svnroot\/line6linux\/driver\/trunk\nAll<span class=\"w\"> <\/span>changes<span class=\"w\"> <\/span>applied<span class=\"w\"> <\/span>successfully.\nUsing<span class=\"w\"> <\/span>version<span class=\"w\"> <\/span>string<span class=\"w\"> <\/span><span class=\"m\">0<\/span>.7.4+svn511<span class=\"w\"> <\/span><span class=\"k\">for<\/span><span class=\"w\"> <\/span>upstream<span class=\"w\"> <\/span>branch.\nThe<span class=\"w\"> <\/span>new<span class=\"w\"> <\/span>upstream<span class=\"w\"> <\/span>version<span class=\"w\"> <\/span>has<span class=\"w\"> <\/span>been<span class=\"w\"> <\/span>imported.<span class=\"w\"> <\/span>You<span class=\"w\"> <\/span>should<span class=\"w\"> <\/span>now<span class=\"w\"> <\/span>update<span class=\"w\"> <\/span>the<span class=\"w\"> <\/span>changelog<span class=\"w\"> <\/span><span class=\"o\">(<\/span>try<span class=\"w\"> <\/span>dch<span class=\"w\"> <\/span>-v<span class=\"w\"> <\/span><span class=\"m\">0<\/span>.7.4+svn511-1<span class=\"w\"> <\/span><span class=\"s2\">&quot;New upstream snapshot.&quot;<\/span><span class=\"o\">)<\/span>,<span class=\"w\"> <\/span>resolve<span class=\"w\"> <\/span>any<span class=\"w\"> <\/span>conflicts,<span class=\"w\"> <\/span>and<span class=\"w\"> <\/span><span class=\"k\">then<\/span><span class=\"w\"> <\/span>commit.\n%<span class=\"w\"> <\/span>dch<span class=\"w\"> <\/span>-v<span class=\"w\"> <\/span><span class=\"m\">0<\/span>.7.4+svn511-1<span class=\"w\"> <\/span><span class=\"s2\">&quot;New upstream snapshot.<\/span>\n<span class=\"s2\">% bzr builddeb<\/span>\n<span class=\"s2\">Building using working tree<\/span>\n<span class=\"s2\">Preparing the build area: ..\/build-area<\/span>\n<span class=\"s2\">Purging the build dir: ..\/build-area\/line6-usb-0.7.4+svn511<\/span>\n<span class=\"s2\">[...]<\/span>\n<span class=\"s2\">Placing result in \/home\/jelmer\/bzr\/line6-usb\/result<\/span>\n<span class=\"s2\">% ls ..\/result<\/span>\n<span class=\"s2\">line6-usb_0.7.4+svn511-1_amd64.changes  line6-usb_0.7.4+svn511-1.dsc<\/span>\n<span class=\"s2\">line6-usb-source_0.7.4+svn511-1_all.deb<\/span>\n<span class=\"s2\">line6-usb_0.7.4+svn511-1.diff.gz        line6-usb_0.7.4+svn511.orig.tar.gz<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n<p><em>Currently Playing: Phideaux - Microdeath&nbsp;Softstar<\/em><\/p>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"bzr_svn"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Reconciling the Samba 3 and Samba 4 source code\u00a0trees","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/223-Reconciling-the-Samba-3-and-Samba-4-source-code-trees.html","rel":"alternate"}},"published":"2008-09-15T22:05:14+02:00","updated":"2008-09-15T22:05:14+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-09-15:223-Reconciling-the-Samba-3-and-Samba-4-source-code-trees.html","summary":"<p>While a few of us have been working very hard on Samba 4 to allow it to rock your socks off as an Active Directory Domain Controller, some of the other Samba developers have been working just as hard on improving the existing Samba 3 codebase and adding features to that. This situation has caused tension between developers as well as technical problems in the past - code with the same purpose is being developed in parallel, libraries diverge because features are only added in one branch and not in the other, one codebase is considered &#8220;obsolete&#8221; by some and the other is considered only a playground for experimental features by&nbsp;others.<\/p>\n<p>As of yesterday, we now have the two codebases living in one and the same git branch. This should make it a lot easier for the two to use the same libraries. Better yet, it should allow us to reconcile the copies of various libraries that exist in both codebases, all of which have diverged to some degree in the last few&nbsp;years.<\/p>\n<p>After <a class=\"reference external\" href=\"http:\/\/thread.gmane.org\/gmane.comp.version-control.git\/94861\">a few problems came up<\/a> merging the two branches the easy way (they both have a directory called &#8220;source&#8221; and git doesn&#8217;t deal well with renaming them to &#8220;source3&#8221; and &#8220;source4&#8221; respectively), we decided to replay the history of both branches . This has the disadvantage that all existing branches that are based on the Samba 3 and Samba 4 branches will have to be rebased against the new master branch, but it also means we keep the ability to run &#8220;git log&#8221; inside of our source directories and having it work&nbsp;right.<\/p>\n<p>Other than the fact that this makes it possible to share more code between the two codebases, one of the ideas we have is also to see if it is possible to provide an Active Directory <span class=\"caps\">DC<\/span> by glueing the best bits of Samba 3 and Samba 4 together (aka &#8220;<a class=\"reference external\" href=\"http:\/\/wiki.samba.org\/index.php\/Franky\">Franky<\/a>&#8221;) before they are eventually merged&nbsp;completely.<\/p>\n<p><em>Currently Playing: Phideaux -&nbsp;Formaldehyde<\/em><\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"git"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Oxegen\u00a0\u201808","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/221-Oxegen-08.html","rel":"alternate"}},"published":"2008-07-16T13:28:07+02:00","updated":"2008-07-16T13:28:07+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-07-16:221-Oxegen-08.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/www.oxegen.ie\/\">Oxegen<\/a> was a bit expensive but awesome. Irish people&nbsp;rock.<\/p>\n<p><strong>update<\/strong>: <a class=\"reference external\" href=\"http:\/\/wilmer.gaast.net\/\">Wilmer<\/a> has <a class=\"reference external\" href=\"http:\/\/wilmer.gaast.net\/blog\/archives\/40-Oxegen-2008.html\">details<\/a>.<\/p>\n","category":[{"@attributes":{"term":"music"}},{"@attributes":{"term":"festivals"}}]},{"title":"Microblogging","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/229-Microblogging.html","rel":"alternate"}},"published":"2008-07-06T00:32:00+02:00","updated":"2008-07-06T00:32:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-07-06:229-Microblogging.html","summary":"<p>I&#8217;ve joined the microblogging hype; I&#8217;ll be giving status updates on my coffee drinking habits and other uninteresting facts at <a class=\"reference external\" href=\"http:\/\/identi.ca\/jelmer\">http:\/\/identi.ca\/jelmer<\/a>.<\/p>\n"},{"title":"bzr-svn push without file\u00a0properties","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/220-bzr-svn-push-without-file-properties.html","rel":"alternate"}},"published":"2008-06-30T23:30:40+02:00","updated":"2008-06-30T23:30:40+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-06-30:220-bzr-svn-push-without-file-properties.html","summary":"<p>Ever since bzr-svn started supporting &#8220;true push&#8221;, people have been complaining about the extra file properties it&nbsp;sets.<\/p>\n<p>The key thing about &#8220;true&#8221; push is that it preserves the exact revisions that were present in Subversion. This lets bzr behave on Subversion branches transparently using the same <span class=\"caps\">UI<\/span> you also use for &#8220;native&#8221; Bazaar&nbsp;branches.<\/p>\n<p>In other words, if I push to a Subversion branch from my machine, then that branch in Subversion contains enough information for somebody else to reconstruct the exact bzr branch I&nbsp;had.<\/p>\n<p>Since some Bazaar metadata can not be represented in Subversion, it is stored in Bazaar-specific Subversion properties. Unfortunately, these file properties show up in email commit notifications and <a class=\"reference external\" href=\"http:\/\/trac.edgewall.org\/\">trac<\/a> and so they tend to annoy&nbsp;people.<\/p>\n<p>There are two ways around&nbsp;this:<\/p>\n<div class=\"section\" id=\"revision-properties\">\n<h2>Revision&nbsp;properties<\/h2>\n<p>Bazaar-specific metadata can be stored in in custom Subversion revision properties (these don&#8217;t show up in commit notifications). Unfortunately, this requires Subversion 1.5 or newer to run on the&nbsp;server.<\/p>\n<p>I hope to start setting revision properties instead of file properties when possible as of the next bzr-svn&nbsp;release.<\/p>\n<\/div>\n<div class=\"section\" id=\"less-strict-push\">\n<h2>less strict&nbsp;push<\/h2>\n<p>It&#8217;s also possible to throw away any data that can not be represented in Subversion. Since this means that the remote branch won&#8217;t end up an exact same copy of the local revisions, this isn&#8217;t true push. The two branches will have diverged (no matter how slightly) after such a push so it is necessary to rebase on the remote branch after&nbsp;pushing.<\/p>\n<p>This is similar to the way git-svn pushes data into Subversion - it calls it&nbsp;&#8220;dcommit&#8221;.<\/p>\n<p>Since this uses rebase it has the usual disadvantages of rebases, which I won&#8217;t get into right&nbsp;now.<\/p>\n<p>As of a couple of days ago, bzr-svn now also supports this mode of pushing using the &#8220;dpush&#8221; command, by popular&nbsp;demand.<\/p>\n<p><em>Currently Playing: Brandi Carlile - The&nbsp;Story<\/em><\/p>\n<\/div>\n","category":[{"@attributes":{"term":"bzr_svn"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"bzr-svn: now with its own Subversion Python\u00a0bindings","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/218-bzr-svn-now-with-its-own-Subversion-Python-bindings.html","rel":"alternate"}},"published":"2008-06-22T18:17:42+02:00","updated":"2008-06-22T18:17:42+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-06-22:218-bzr-svn-now-with-its-own-Subversion-Python-bindings.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/bazaar-vcs.org\/BzrSvn\">bzr-svn<\/a> has always been using the standard Python bindings that were\nprovided with Subversion itself. Unfortunately, I had to fix some issues in\nthese bindings since they were incomplete or broken and thus bzr-svn has always\ndepended on a development snapshot of&nbsp;Subversion.<\/p>\n<p>As of today, bzr-svn is using its own Python bindings for&nbsp;Subversion.<\/p>\n<p>There were several reasons for switching to our own&nbsp;bindings:<\/p>\n<ul class=\"simple\">\n<li>There are no requirements for backwards compatibility within bzr-svn. This\nmeans the <span class=\"caps\">API<\/span> can be made sane without worrying about the mess it was in the\npast and users who still rely on&nbsp;that.<\/li>\n<li>Deployment. It took 2 years for my fixes to the Subversion Python bindings to\nbe part of a release. It&#8217;ll be even longer before Subversion 1.5 makes it\ninto most available distributions. That makes it very hard to just download\nand install&nbsp;bzr-svn.<\/li>\n<li>They&#8217;re in plain C, not <span class=\"caps\">SWIG<\/span>. <span class=\"caps\">SWIG<\/span> has a big advantage for the Subversion\nfolks since it can generate python, ruby, java or tcl bindings all at once\nwithout a lot of overhead per language. However, it has issues as well that\nmake it a bad choice for bzr-svn.<ul>\n<li>It generates inefficient code - it generates proxy classes that add more\nlayers in the&nbsp;stack<\/li>\n<li>Bindings tend to be very much like the C <span class=\"caps\">API<\/span> rather than &#8220;Pythonic&#8221;. To make\nthem more Pythonic, you need tons of typemaps. For example, the Python\nbindings in bzr-svn provide an iterator when browsing the revision history\nrather than a callback as C and the <span class=\"caps\">SWIG<\/span> bindings&nbsp;do.<\/li>\n<li>Hard to write - personally at least, I write bindings in C faster than in\n<span class=\"caps\">SWIG<\/span><\/li>\n<li>Adds an extra dependency to the build process. Several people had trouble\nbuilding Subversion on their Mac machines because they didn&#8217;t have the right\nversion of <span class=\"caps\">SWIG<\/span>&nbsp;available.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Since all of the patches that bzr-svn depended on previously were in the Python\nbindings for Subversion, it is now possible to use bzr-svn with any version of\nSubversion newer than 1.4.0. Of course, you do need to have the development\nheaders installed as&nbsp;well.<\/p>\n<p><em>Currently Playing: Kathleen Edwards - Independent&nbsp;Thief<\/em><\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"subversion"}},{"@attributes":{"term":"bzr_svn"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Bazaar in the GNOME\u00a0world","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/217-Bazaar-in-the-GNOME-world.html","rel":"alternate"}},"published":"2008-06-19T15:13:20+02:00","updated":"2008-06-19T15:13:20+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-06-19:217-Bazaar-in-the-GNOME-world.html","summary":"<p>I was happy to see that <a class=\"reference external\" href=\"http:\/\/blogs.gnome.org\/johncarr\">John Carr<\/a> has set up a <a class=\"reference external\" href=\"http:\/\/bzr-mirror.gnome.org\/\">Bazaar Mirror<\/a> of all\nprojects in <span class=\"caps\">GNOME<\/span> Subversion, all created using bzr-svn.  There&#8217;s also a <a class=\"reference external\" href=\"http:\/\/live.gnome.org\/Bazaar\">quick\nintroduction to using Bazaar for <span class=\"caps\">GNOME<\/span> developers<\/a> on the <a class=\"reference external\" href=\"http:\/\/live.gnome.org\/\"><span class=\"caps\">GNOME<\/span> Wiki<\/a>.<\/p>\n<p><a class=\"reference external\" href=\"http:\/\/uwstopia.nl\/\">Wouter<\/a>, long time Bazaar user and <span class=\"caps\">GNOME<\/span> dude, recently blogged about <a class=\"reference external\" href=\"http:\/\/uwstopia.nl\/blog\/2008\/06\/gnome-specimen-now-in-gnome-svn\/\">pushing Bazaar branches<\/a> into <span class=\"caps\">GNOME<\/span> Subversion, working around the restrictions imposed by the pre-commit hooks in <span class=\"caps\">GNOME<\/span>&nbsp;Subversion.<\/p>\n<p>The problems John ran into with memory usage in the Python Subversion bindings\nencouraged me to continue the work on bzr-svn&#8217;s own Python bindings, thus\navoiding any dependency on unreleased versions of Subversion and several other&nbsp;issues.<\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"bzr_svn"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Git cutting\u00a0corners","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/216-Git-cutting-corners.html","rel":"alternate"}},"published":"2008-04-27T13:13:20+02:00","updated":"2008-04-27T13:13:20+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-04-27:216-Git-cutting-corners.html","summary":"<p>My relationship with git is still one of love and hate. It cuts corners to\nincrease performance in a couple of places and that can be really bloody&nbsp;annoying.<\/p>\n<p>For example, jerry renamed one of the top-level directories in Samba 3\n(revision 9f672c26d63955f613088489c6efbdc08b5b2d14). Git will skip rename\ndetection in this revision because of the number of files it affects, thus\ncausing the output of &#8220;git log &lt;path&gt;&#8221; of this particular directory to be&nbsp;useless.<\/p>\n<p>I&#8217;m the first to admit &#8220;bzr log&#8221; on directories and files in large history\nprojects is painfully slow, but at least it gets the output&nbsp;right.<\/p>\n<p><em>Currently Playing: Brandi Carlile - The&nbsp;Story<\/em><\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"rants"}},{"@attributes":{"term":"git"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"SambaXP and other\u00a0travel","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/215-SambaXP-and-other-travel.html","rel":"alternate"}},"published":"2008-04-26T10:03:04+02:00","updated":"2008-04-26T10:03:04+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-04-26:215-SambaXP-and-other-travel.html","summary":"<p>It&#8217;s been a busy two weeks.  Wilco and I drove up to G\u00f6ttingen on Sunday two weeks ago to spend some days hacking and meeting up with the other developers before the start of <a class=\"reference external\" href=\"http:\/\/www.sambaxp.org\/\">SambaXP<\/a>. It was really nice to see everybody again after more than 7&nbsp;months.<\/p>\n<p>SambaXP was a bit different this year. There were three tracks during the second part of the conference this year, one more than previously and of course, there were several engineers from Microsoft attending this time! Some of the interesting talks this year included Julien&#8217;s update on OpenChange, Tridge&#8217;s talk on <span class=\"caps\">PFIF<\/span>, the talk from the likewise folks and of course the talk from Microsofts&#8217; Wolfgang Grieskamp on <span class=\"caps\">SMB2<\/span>. We also had some other informal discussions with the Microsoft folks about specific topics - very&nbsp;useful!<\/p>\n<p>There are <a class=\"reference external\" href=\"http:\/\/sambaxp.org\/index.php?id=137\">some photos<\/a> up on the SambaXP homepage. And just to be ahead of the comments: yes, I know I need a&nbsp;haircut.<\/p>\n<p>I did some initial work on several bits and pieces of code that I hope to expand over the next few months. Volker has started working on ncacn_ip_tcp support and I have been working on making the Samba 3 <span class=\"caps\">DCE<\/span>\/<span class=\"caps\">RPC<\/span> library compatible with Samba 4. This should allow OpenChange to use Samba 3 in the&nbsp;future.<\/p>\n<p>Guenther, Wilco and I made some initial progress on the policy library, allowing client-side manipulation of (group) policies in Samba. I worked with Simo on trying to get rid of an evil hack in Samba4&#8217;s event&nbsp;subsystem.<\/p>\n<p>David Holder blogged about some of the IPv6 development that we did during the conference: <a class=\"reference external\" href=\"http:\/\/www.ipv6consultancy.com\/ipv6blog\/?p=34\">http:\/\/www.ipv6consultancy.com\/ipv6blog\/?p=34<\/a><\/p>\n<p>And lots of other things I can&#8217;t remember at the&nbsp;moment&#8230;<\/p>\n<p>After the conference Andrew, Wilco and I drove back to the Netherlands and I played tour guide for a bit showing Andrew around the country during the afternoon and hacking Samba together in the morning. Later this week we took the train to Brussels, Eurostar to London and visited Sam&#8217;s company\nin the <span class=\"caps\">UK<\/span> Midlands for a couple of&nbsp;days.<\/p>\n<p>And in the midst of all this, it seems Ubuntu Hardy was released. Congratulations to all those&nbsp;involved!<\/p>\n<p><em>Currently Playing: Brandi Carlile -&nbsp;Turpentine<\/em><\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"uk"}},{"@attributes":{"term":"de"}},{"@attributes":{"term":"be"}},{"@attributes":{"term":"nl"}},{"@attributes":{"term":"conferences"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Using bzr-builddeb as a svn-buildpackage\u00a0replacement","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/214-Using-bzr-builddeb-as-a-svn-buildpackage-replacement.html","rel":"alternate"}},"published":"2008-03-26T15:21:20+01:00","updated":"2008-03-26T15:21:20+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-03-26:214-Using-bzr-builddeb-as-a-svn-buildpackage-replacement.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/bzr-svn-buildpackage.diffThisslightlyevilhack\">This slightly evil hack<\/a> to bzr-svn allows using bzr-builddeb as a drop-in replacement for svn-buildpackage, making it recognize the &#8220;mergeWithUpstream&#8221; property svn-buildpackage&nbsp;uses.<\/p>\n<p><em>Currently Playing: Jeff Healey - Mess O&#8217;&nbsp;Blues<\/em><\/p>\n","category":[{"@attributes":{"term":"debian"}},{"@attributes":{"term":"bzr_svn"}},{"@attributes":{"term":"ubuntu"}},{"@attributes":{"term":"pkg"}}]},{"title":"Adaption blockers Bazaar\u00a0sprint","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/213-Adaption-blockers-Bazaar-sprint.html","rel":"alternate"}},"published":"2008-03-09T17:06:00+01:00","updated":"2008-03-09T17:06:00+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-03-09:213-Adaption-blockers-Bazaar-sprint.html","summary":"<p>The London Bazaar sprint is over again for this year. It was really good to meet\neverybody in person again and also to meet some of the folks who hadn&#8217;t been to\na sprint&nbsp;before.<\/p>\n<p>Last years sprint was mainly about improving performance; this year, we\ndiscussed adoption blockers and how to remove them. A short summary of the\n<a class=\"reference external\" href=\"http:\/\/bazaar-vcs.org\/SprintLondonMarch08\/Brainstorms\">brainstorming<\/a> is on the&nbsp;wiki.<\/p>\n<p><a class=\"reference external\" href=\"http:\/\/beuno.com.ar\/\">Martin&#8217;s Blog<\/a> has some&nbsp;pictures.<\/p>\n<div class=\"section\" id=\"tmv\">\n<h2><span class=\"caps\">TMV<\/span><\/h2>\n<p>The Mars Volta concert we went to last night in Tilburg was absolutely\nbrilliant. Very energetic and definitely one of the best acts I&#8217;ve ever seen\nlive. We were standing in the back of a completely packed venue for 3 hours,\nbut it was very much worth&nbsp;it.<\/p>\n<p><em>Currently Playing: Soft Machine -&nbsp;Teeth<\/em><\/p>\n<\/div>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"music"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"OpenChange Evolution plugin preview and Debian\u00a0packages","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/210-OpenChange-Evolution-plugin-preview-and-Debian-packages.html","rel":"alternate"}},"published":"2008-01-21T14:42:07+01:00","updated":"2008-01-21T14:42:07+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-01-21:210-OpenChange-Evolution-plugin-preview-and-Debian-packages.html","summary":"<p>Srini writes that a preview of the <a class=\"reference external\" href=\"http:\/\/blogs.gnome.org\/sragavan\/2008\/01\/21\/evolution-mapi-exchange-2007-preview\/\">Evolution OpenChange plugin<\/a> has just been\npublished. This plugin is now developed in the Evolution Subversion repository,\nbut is based on the original plugin that was written by the <a class=\"reference external\" href=\"http:\/\/www.epitech.eu\/\">Epitech<\/a> team\nthat was assigned to OpenChange earlier this&nbsp;year.<\/p>\n<p>I&#8217;ve packaged new snapshots of Samba and OpenChange for Debian\/Ubuntu.\nThey&#8217;re available from my <a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/debian\/\">personal apt repository<\/a> and will hopefully soon\nalso be available from Debian&nbsp;experimental.<\/p>\n<p><em>Update<\/em>: The packages are now in <a class=\"reference external\" href=\"http:\/\/packages.debian.org\/experimental\/\">Debian experimental<\/a> as well as the\nupcoming Intrepid release of Ubuntu. I have removed them from my personal\nrepository because I was running out of disk&nbsp;quota.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"debian"}},{"@attributes":{"term":"openchange"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Samba\u2019s tdbdump reimplemented in\u00a0Python","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/207-Sambas-tdbdump-reimplemented-in-Python.html","rel":"alternate"}},"published":"2008-01-10T20:24:29+01:00","updated":"2008-01-10T20:24:29+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2008-01-10:207-Sambas-tdbdump-reimplemented-in-Python.html","summary":"<p>Less than 150 characters in Python, while the original implementation in C requires more than 2000&nbsp;characters<\/p>\n<div class=\"highlight\"><table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre><span class=\"normal\">1<\/span>\n<span class=\"normal\">2<\/span>\n<span class=\"normal\">3<\/span>\n<span class=\"normal\">4<\/span>\n<span class=\"normal\">5<\/span>\n<span class=\"normal\">6<\/span><\/pre><\/div><\/td><td class=\"code\"><div><pre><span><\/span><span class=\"kn\">import<\/span> <span class=\"nn\">tdb<\/span><span class=\"o\">,<\/span> <span class=\"nn\">sys<\/span>\n\n<span class=\"n\">db<\/span> <span class=\"o\">=<\/span> <span class=\"n\">tdb<\/span><span class=\"o\">.<\/span><span class=\"n\">Tdb<\/span><span class=\"p\">(<\/span><span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">argv<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">])<\/span>\n<span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"n\">k<\/span><span class=\"p\">,<\/span> <span class=\"n\">v<\/span><span class=\"p\">)<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">db<\/span><span class=\"o\">.<\/span><span class=\"n\">iteritems<\/span><span class=\"p\">():<\/span>\n    <span class=\"nb\">print<\/span> <span class=\"s2\">&quot;{<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">key(<\/span><span class=\"si\">%d<\/span><span class=\"s2\">) = <\/span><span class=\"si\">%r<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">data(<\/span><span class=\"si\">%d<\/span><span class=\"s2\">) = <\/span><span class=\"si\">%r<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">}<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">&quot;<\/span> <span class=\"o\">%<\/span> <span class=\"p\">(<\/span><span class=\"nb\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">k<\/span><span class=\"p\">),<\/span> <span class=\"n\">k<\/span><span class=\"p\">,<\/span> <span class=\"nb\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">),<\/span> <span class=\"n\">v<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/pre><\/div><\/td><\/tr><\/table><\/div>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"tdb"}}]},{"title":"GTK+ LDB\u00a0Browser","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/204-GTK+-LDB-Browser.html","rel":"alternate"}},"published":"2007-12-16T20:49:05+01:00","updated":"2007-12-16T20:49:05+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-12-16:204-GTK+-LDB-Browser.html","summary":"<p>As some may have noticed, a large portion of my Samba 4 work during the last\nfew months has been focussed on adding Python bindings for our various public\nlibraries and the refactoring necessary to make it possible to add Python\nbindings. So far, we have bindings for <span class=\"caps\">LDB<\/span> and <span class=\"caps\">TDB<\/span> but I intend to add bindings\nfor most of our public <span class=\"caps\">API<\/span> so it is possible to, for example, open Windows\nregistry files, join domains, etc. from&nbsp;Python.<\/p>\n<p><a class=\"reference external\" href=\"http:\/\/ldb.samba.org\"><span class=\"caps\">LDB<\/span><\/a> is our <span class=\"caps\">LDAP<\/span>-like embedded database, and is for <span class=\"caps\">LDAP<\/span> what sqlite is for\n<span class=\"caps\">SQL<\/span>. Last night I decided to see how hard it would be to write a graphical\nbrowser for <span class=\"caps\">LDB<\/span> using Python, and it turned out to be quite easy, thanks to\nPyGTK. There is a screenshot of what it looks like <a class=\"reference external\" href=\"http:\/\/samba.org\/~jelmer\/gtkldb.png\">here<\/a>. Packages with the\nPython bindings for <span class=\"caps\">LDB<\/span> are <a class=\"reference external\" href=\"http:\/\/packages.debian.org\/python-ldb\">already in Debian<\/a>.<\/p>\n<p>The sources for gtkldb are available in the samba-gtk bzr branch at\n<a class=\"reference external\" href=\"http:\/\/people.samba.org\/bzr\/jelmer\/samba-gtk\/trunk\">http:\/\/people.samba.org\/bzr\/jelmer\/samba-gtk\/trunk<\/a>, along with some of the <span class=\"caps\">GTK<\/span>+\nfrontends for Samba 4 I wrote earlier (gregedit, gwcrontab, gwsvcctl, gepdump\nand&nbsp;gwsam).<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"ubuntu"}}]},{"title":"Building shared and static libs on different\u00a0platforms","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/201-Building-shared-and-static-libs-on-different-platforms.html","rel":"alternate"}},"published":"2007-11-14T00:48:58+01:00","updated":"2007-11-14T00:48:58+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-11-14:201-Building-shared-and-static-libs-on-different-platforms.html","summary":"<p>One of the main portability problems across different <span class=\"caps\">POSIX<\/span> implementations is the way shared and static libs should be&nbsp;built.<\/p>\n<p>Just came across a nice overview of the flags to use on the different platforms: <a class=\"reference external\" href=\"http:\/\/www.fortran-2000.com\/ArnaudRecipes\/sharedlib.html\">http:\/\/www.fortran-2000.com\/ArnaudRecipes\/sharedlib.html<\/a><\/p>\n<p>it would be nice if <span class=\"caps\">POSIX<\/span> could standardise this at some&nbsp;point.<\/p>\n"},{"title":"Epitech\/OpenChange\u00a0meeting","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/199-EpitechOpenChange-meeting.html","rel":"alternate"}},"published":"2007-11-12T20:10:05+01:00","updated":"2007-11-12T20:10:05+01:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-11-12:199-EpitechOpenChange-meeting.html","summary":"<p>I&#8217;ve had a lot of time to practice my French skills this weekend while visiting\n<a class=\"reference external\" href=\"http:\/\/www.epitech.fr\/\">Epitech<\/a> and meeting up with Julien, Ali, Dan and the\nother OpenChange folks in&nbsp;Paris.<\/p>\n<p>There was a forum at Epitech where student teams present the projects that\nthey&#8217;ve been working on over the course of the last year. One of the Epitech\nstudent teams has done an excellent job on an OpenChange plugin for Evolution\nthat now even appears to have been picked up by upstream. The other projects\nwere also quite interesting as well and varied from a fun to play 3D racing\ngame to a much improved <span class=\"caps\">LGPL<\/span>&#8217;ed implementation of the ClamAv virus scanner or a\npersonal logging application for diabetics. Afterwards there was a little bit\nof an Open Source conference, where Dan and I gave <a class=\"reference external\" href=\"http:\/\/www.epitech.eu\/v4\/conferences-open-source-art404.html\">talks<\/a> about Open Source\nand Samba,&nbsp;respectively.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"fr"}},{"@attributes":{"term":"openchange"}}]},{"title":"OpenChange team\u00a0member","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/195-OpenChange-team-member.html","rel":"alternate"}},"published":"2007-10-22T22:53:12+02:00","updated":"2007-10-22T22:53:12+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-10-22:195-OpenChange-team-member.html","summary":"<p>As of today, I&#8217;m officially a member of the <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/\">OpenChange<\/a> development team. I\nalready had access to the Subversion server and have contributed a number of\npatches in the last couple of years, mainly related to the build&nbsp;system.<\/p>\n","category":{"@attributes":{"term":"openchange"}}},{"title":"Bazaar: Need for a \u201cProduct\u201d\u00a0object?","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/192-Bazaar-Need-for-a-Product-object.html","rel":"alternate"}},"published":"2007-10-10T13:17:02+02:00","updated":"2007-10-10T13:17:02+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-10-10:192-Bazaar-Need-for-a-Product-object.html","summary":"<p>This is something that&#8217;s been lingering in the back of my head for the last\nyear or so. I think I am missing something in the sequence of [Branch,\nRepository, WorkingTree]. Here are some of the reasons why I think this is the&nbsp;case:<\/p>\n<ul class=\"simple\">\n<li>Tags should ideally be shared amongst a set of related branches. This has\ncome up often during discussions about where tags&nbsp;belong.<\/li>\n<li>Management of sets of bzr branches is hard<ul>\n<li>It seems to make sense for the configuration of several plugins to be\nproject-specific:<ul>\n<li>bzr-pqm-submit&#8217;s pqm&nbsp;address<\/li>\n<li>bzr-email target&nbsp;address<\/li>\n<li>bzr-cia&#8217;s project&nbsp;setting<\/li>\n<li>&#8230;<\/li>\n<\/ul>\n<\/li>\n<li>may be useful to override&nbsp;whoami<\/li>\n<li>having a way to group branches allows&nbsp;mass-pushes\/pulls<\/li>\n<\/ul>\n<\/li>\n<li>I often find that the public_location I set is almost the same for related branches, with only the last part of the url differing and containing the branch&nbsp;nick<\/li>\n<li>It would be nice if &#8220;bzr register-branch&#8221; could automatically determine what product to register&nbsp;as<\/li>\n<\/ul>\n<p>I&#8217;m not looking for repositories:\n- repositories can contain data from multiple totally unrelated  branches. a tag &#8220;1.0&#8221; could conflict because there are multiple unrelated projects that have it.\n- repositories are a storage optimization and I like them that&nbsp;way<\/p>\n<p>although other projects (mercurial, git) seem to be using repositories to allow talking about a group of related&nbsp;branches.<\/p>\n<p>I&#8217;m not looking for &#8220;just&#8221; directories:\n- There&#8217;s no place in a directory to store settings or tags\n- Having a long list of settings in ~\/bazaar\/locations.conf doesn&#8217;t scale and the settings won&#8217;t be able to&nbsp;propagate<\/p>\n<p>Having another semantic object (&#8221;Product&#8221;?) on which options\/tags can be set would help. Perhaps based on the root id (where available)&nbsp;?<\/p>\n<p><em>Currently Playing: Symphony X - The&nbsp;Odyssey<\/em><\/p>\n","category":{"@attributes":{"term":"bzr"}}},{"title":"SerNet asks Microsoft for\u00a0specs","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/191-SerNet-asks-Microsoft-for-specs.html","rel":"alternate"}},"published":"2007-10-07T12:38:42+02:00","updated":"2007-10-07T12:38:42+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-10-07:191-SerNet-asks-Microsoft-for-specs.html","summary":"<p>Now that the European court has decided SerNet <a class=\"reference external\" href=\"http:\/\/www.heise.de\/newsticker\/meldung\/96788\/\">has asked<\/a> Microsoft to publish specifications on <span class=\"caps\">SMB<\/span>\/<span class=\"caps\">CIFS<\/span>.<\/p>\n<p>Martijn has <a class=\"reference external\" href=\"http:\/\/martijn.van.steenbergen.nl\/journal\/2007\/10\/07\/kamelot\/\">posted some photos<\/a> of the concert we went to a couple of days&nbsp;ago.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"de"}}]},{"title":"Podcast with the Samba\u00a0team","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/190-samba-podcast.html","rel":"alternate"}},"published":"2007-10-02T20:23:26+02:00","updated":"2007-10-02T20:23:26+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-10-02:190-samba-podcast.html","summary":"<p>Last week was the annual Samba get-together in the <span class=\"caps\">US<\/span>. Jeremy and Leslie from\nGoogle organized a somewhat more informal event than the <a class=\"reference external\" href=\"http:\/\/www.cifs2006.org\/\"><span class=\"caps\">SNIA<\/span> <span class=\"caps\">CIFS<\/span><\/a>\ninterop lab that we usually&nbsp;attend.<\/p>\n<p>Several Samba team members, including myself, took part in a <a class=\"reference external\" href=\"http:\/\/googlesummerofcode.blogspot.com\/2007\/10\/cifs-samba-and-summer-of-code.html\">podcast<\/a>\nabout our involvement in the Summer of Code&nbsp;afterwards.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"conferences"}},{"@attributes":{"term":"ca"}},{"@attributes":{"term":"travel"}},{"@attributes":{"term":"google"}}]},{"title":"Converting CSV files to QIF","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/188-Converting-CSV-files-to-QIF.html","rel":"alternate"}},"published":"2007-09-07T01:42:09+02:00","updated":"2007-09-07T01:42:09+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-09-07:188-Converting-CSV-files-to-QIF.html","summary":"<p>Recently I&#8217;ve started using <a class=\"reference external\" href=\"http:\/\/www.gnucash.org\/\">GnuCash<\/a> for my personal finances. Eventually I got it running well, after I recompiled it myself, because the version in Debian was segfaulting on start-up (it is also very&nbsp;outdated).<\/p>\n<p>My bank, <a class=\"reference external\" href=\"http:\/\/www.postbank.nl\/\">PostBank<\/a> only supports exporting transactions in it&#8217;s own custom <span class=\"caps\">CSV<\/span> files which, of course, aren&#8217;t supported by Gnucash. I wrote a simple Python script that converts PostBank <span class=\"caps\">CSV<\/span> files to <a class=\"reference external\" href=\"http:\/\/en.wikipedia.org\/wiki\/QIF\"><span class=\"caps\">QIF<\/span><\/a>, which Gnucash can handle&nbsp;ok.<\/p>\n<p>I&#8217;m publishing the script here for others interested in importing PostBank <span class=\"caps\">CSV<\/span> files in their finance&nbsp;apps:<\/p>\n<pre class=\"code python literal-block\">\n<span class=\"ch\">#!\/usr\/bin\/python<\/span><span class=\"w\">\n<\/span><span class=\"c1\"># Very simple converter from PostBank mijn.postbank.nl .csv files to<\/span><span class=\"w\">\n<\/span><span class=\"c1\"># QIF files for use by (among others) gnucash.<\/span><span class=\"w\">\n<\/span><span class=\"c1\">#<\/span><span class=\"w\">\n<\/span><span class=\"c1\"># Written by Jelmer Vernoo\u0133 &lt;jelmer&#64;samba.org&gt;, 2007<\/span><span class=\"w\">\n\n<\/span><span class=\"kn\">import<\/span> <span class=\"nn\">csv<\/span><span class=\"o\">,<\/span> <span class=\"nn\">sys<\/span><span class=\"w\">\n\n<\/span><span class=\"n\">rows<\/span> <span class=\"o\">=<\/span> <span class=\"n\">csv<\/span><span class=\"o\">.<\/span><span class=\"n\">reader<\/span><span class=\"p\">(<\/span><span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">stdin<\/span><span class=\"p\">)<\/span><span class=\"w\">\n\n<\/span><span class=\"n\">header<\/span> <span class=\"o\">=<\/span> <span class=\"n\">rows<\/span><span class=\"o\">.<\/span><span class=\"n\">next<\/span><span class=\"p\">()<\/span><span class=\"w\">\n\n<\/span><span class=\"k\">assert<\/span> <span class=\"n\">header<\/span> <span class=\"o\">==<\/span> <span class=\"p\">([<\/span><span class=\"s1\">'Datum'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'Naam \/ Omschrijving'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'Rekening'<\/span><span class=\"p\">]<\/span><span class=\"w\">\n<\/span>    <span class=\"o\">+<\/span> <span class=\"p\">[<\/span><span class=\"s1\">'Tegenrekening'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'Code'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'Af Bij'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'Bedrag (EUR)'<\/span><span class=\"p\">]<\/span><span class=\"w\">\n<\/span>    <span class=\"o\">+<\/span> <span class=\"p\">[<\/span><span class=\"s1\">'MutatieSoort'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'Mededelingen'<\/span><span class=\"p\">])<\/span><span class=\"w\">\n\n<\/span><span class=\"nb\">print<\/span> <span class=\"s1\">'!Type:Bank<\/span><span class=\"se\">\\n<\/span><span class=\"s1\">'<\/span><span class=\"w\">\n\n<\/span><span class=\"k\">for<\/span> <span class=\"n\">l<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">rows<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span>    <span class=\"k\">if<\/span> <span class=\"s2\">&quot;-&quot;<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]:<\/span><span class=\"w\">\n<\/span>        <span class=\"n\">p<\/span> <span class=\"o\">=<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span><span class=\"o\">.<\/span><span class=\"n\">split<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;-&quot;<\/span><span class=\"p\">)<\/span><span class=\"w\">\n<\/span>        <span class=\"nb\">print<\/span> <span class=\"s2\">&quot;D<\/span><span class=\"si\">%s<\/span><span class=\"s2\">\/<\/span><span class=\"si\">%s<\/span><span class=\"s2\">\/<\/span><span class=\"si\">%s<\/span><span class=\"s2\">&quot;<\/span> <span class=\"o\">%<\/span> <span class=\"p\">(<\/span><span class=\"n\">p<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">],<\/span> <span class=\"n\">p<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">],<\/span> <span class=\"n\">p<\/span><span class=\"p\">[<\/span><span class=\"mi\">2<\/span><span class=\"p\">])<\/span><span class=\"w\">\n<\/span>    <span class=\"k\">else<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span>        <span class=\"nb\">print<\/span> <span class=\"s1\">'D<\/span><span class=\"si\">%s<\/span><span class=\"s1\">\/<\/span><span class=\"si\">%s<\/span><span class=\"s1\">\/<\/span><span class=\"si\">%s<\/span><span class=\"s1\">'<\/span> <span class=\"o\">%<\/span> <span class=\"p\">(<\/span><span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">][<\/span><span class=\"mi\">4<\/span><span class=\"p\">:<\/span><span class=\"mi\">6<\/span><span class=\"p\">],<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">][<\/span><span class=\"mi\">6<\/span><span class=\"p\">:<\/span><span class=\"mi\">8<\/span><span class=\"p\">],<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">][<\/span><span class=\"mi\">0<\/span><span class=\"p\">:<\/span><span class=\"mi\">4<\/span><span class=\"p\">])<\/span> <span class=\"c1\"># date<\/span><span class=\"w\">\n<\/span>    <span class=\"k\">if<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"s1\">'Bij'<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span>        <span class=\"nb\">print<\/span> <span class=\"s1\">'T<\/span><span class=\"si\">%s<\/span><span class=\"s1\">'<\/span> <span class=\"o\">%<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">6<\/span><span class=\"p\">]<\/span> <span class=\"c1\"># amount<\/span><span class=\"w\">\n<\/span>    <span class=\"k\">elif<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"s1\">'Af'<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span>        <span class=\"nb\">print<\/span> <span class=\"s1\">'T-<\/span><span class=\"si\">%s<\/span><span class=\"s1\">'<\/span> <span class=\"o\">%<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">6<\/span><span class=\"p\">]<\/span> <span class=\"c1\"># amount<\/span><span class=\"w\">\n<\/span>    <span class=\"k\">else<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span>        <span class=\"k\">raise<\/span> <span class=\"n\">Error<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;Unknown field value '<\/span><span class=\"si\">%s<\/span><span class=\"s2\">'&quot;<\/span> <span class=\"o\">%<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">])<\/span><span class=\"w\">\n<\/span>    <span class=\"nb\">print<\/span> <span class=\"s1\">'P<\/span><span class=\"si\">%s<\/span><span class=\"s1\">'<\/span> <span class=\"o\">%<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"c1\"># payee \/ description<\/span><span class=\"w\">\n<\/span>    <span class=\"nb\">print<\/span> <span class=\"s1\">'M<\/span><span class=\"si\">%s<\/span><span class=\"s1\">'<\/span> <span class=\"o\">%<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">8<\/span><span class=\"p\">]<\/span> <span class=\"c1\"># comment<\/span><span class=\"w\">\n<\/span>    <span class=\"nb\">print<\/span> <span class=\"s1\">'L<\/span><span class=\"si\">%s<\/span><span class=\"s1\">'<\/span> <span class=\"o\">%<\/span> <span class=\"n\">l<\/span><span class=\"p\">[<\/span><span class=\"mi\">7<\/span><span class=\"p\">]<\/span><span class=\"w\">\n<\/span>    <span class=\"nb\">print<\/span> <span class=\"s1\">'^<\/span><span class=\"se\">\\n<\/span><span class=\"s1\">'<\/span> <span class=\"c1\"># end transaction<\/span>\n<\/pre>\n"},{"title":"Bzr-Svn","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/185-Bzr-Svn.html","rel":"alternate"}},"published":"2007-08-03T19:55:36+02:00","updated":"2007-08-03T19:55:36+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-08-03:185-Bzr-Svn.html","summary":"<p>The next major release of <a class=\"reference external\" href=\"http:\/\/bazaar-vcs.org\/BzrSvn\">bzr-svn<\/a>, 0.4, has now been released. The main\nchange in this release is that the behaviour of push is now intuitive. The big\nhack that allowed push to somewhat work in the previous release has been\nreplaced by proper push which behaves the same way as it would against a Bazaar&nbsp;branch.<\/p>\n<p>It&#8217;s now also possible to branch from non-standard branch locations such as\n\/foo in a repository and not necessarily standard locations like \/trunk or\n\/trunk\/foo. See the <a class=\"reference external\" href=\"https:\/\/lists.ubuntu.com\/archives\/bazaar\/2007q3\/029189.html\">release announcement<\/a> for a list of other&nbsp;changes.<\/p>\n<p>It&#8217;s interesting to see what other people are saying about bzr-svn on their&nbsp;blogs:<\/p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"http:\/\/blog.venthur.de\/2007\/04\/20\/reportbug-ng-migrated-from-svn-to-bzr\/\">Migrating to bzr using&nbsp;bzr-svn<\/a><\/li>\n<li><a class=\"reference external\" href=\"http:\/\/raraavisresearch.com\/memo\/archives\/2007\/06\/09\/saturday-night-2\/\">Missing support for&nbsp;svn:externals<\/a><\/li>\n<li><a class=\"reference external\" href=\"http:\/\/matthew.loar.name\/blog\/archives\/2007\/06\/18.html\">Issues with branching&nbsp;schemes<\/a><\/li>\n<li><a class=\"reference external\" href=\"http:\/\/swik.net\/Ubuntu\/Planet+Ubuntu\/James+Henstridge:+FM+Radio+in+Rhythmbox+%E2%80%93+The+Code\/77rb\">using bzr-svn for&nbsp;rhythmbox<\/a><\/li>\n<li><a class=\"reference external\" href=\"http:\/\/blogger.malept.com\/2007\/03\/awn-bzr-branch-bazaar-overlay.html\">bzr-svn on&nbsp;Gentoo<\/a><\/li>\n<li><a class=\"reference external\" href=\"http:\/\/slipperysnippets.blogspot.com\/2007\/07\/wherefore-art-thou-not-working-under.html\">issues with Windows&nbsp;support<\/a><\/li>\n<\/ul>\n<p>Note that bzr-svn 0.4 has been tested on Windows and that branching schemes are now more&nbsp;flexible.<\/p>\n","category":{"@attributes":{"term":"bzr_svn"}}},{"title":"LUG Radio\u00a0Live","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/180-LUG-Radio-Live.html","rel":"alternate"}},"published":"2007-07-09T12:58:09+02:00","updated":"2007-07-09T12:58:09+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-07-09:180-LUG-Radio-Live.html","summary":"<p>Just got back to the hotel after <span class=\"caps\">LUG<\/span> Radio Live and the afterparty event. I\nguess the best way to describe <span class=\"caps\">LUG<\/span> Radio live is as a your average geek\nconference but with a bit of a rock concert flavor: lots of cheering on,\ngroupies, swearing, simple humor and metal music being played in between\nbetween&nbsp;sessions.<\/p>\n<p>The talks were very good; in particular I liked Nat Friedman&#8217;s talk about,\namong other things, the way the Oxford English Dictionary was developed\n(although he still doesn&#8217;t seem to understand what is so bad about the\n<span class=\"caps\">MS<\/span>-Novell deal) and Aaron Seigo&#8217;s talk on <span class=\"caps\">KDE<\/span> 4 (made my fingers itchy and want\nto contribute..). The short talk Szilveszter and I gave on bzr-gtk went ok, but\nwas probably not all that entertaining right after Malcolm&#8217;s talk on zombies\nand&nbsp;Ubuntu.<\/p>\n<p>The major thing I disliked is the fact that the wireless was very crappy. I got\nit to work on two occassions, just long enough to read a few emails. It took a\nwhile to get used to the weird accent with which they speak English around here\nand I seem to&#8217;ve picked up a few swearwords that I now have to unlearn again.&nbsp;Doh.<\/p>\n<p>All in all really worth the trip from Amsterdam and definitely something to\nkeep in mind for next&nbsp;year!<\/p>\n<p>Erik and I decided to stay an extra day to see a bit of Wolverhampton and\nBirmingham, but it turns out this isn&#8217;t your typical tourist&nbsp;spot.<\/p>\n","category":[{"@attributes":{"term":"uk"}},{"@attributes":{"term":"lugradio"}}]},{"title":"Ohloh - Statistics on Free Software\u00a0projects","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/178-Ohloh-Statistics-on-Free-Software-projects.html","rel":"alternate"}},"published":"2007-07-03T14:51:40+02:00","updated":"2007-07-03T14:51:40+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-07-03:178-Ohloh-Statistics-on-Free-Software-projects.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/www.ohloh.net\/\">Ohloh<\/a> is a nice web 2.0 site that contains stats on various Free Software projects. At the moment, they only support Subversion, <span class=\"caps\">CVS<\/span> and Git. They&#8217;re <a class=\"reference external\" href=\"http:\/\/www.ohloh.net\/suggestions\/new\">open to feature requests<\/a> though. If enough people ask for it, hopefully they&#8217;ll support Bazaar at some&nbsp;point.<\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"ohloh"}},{"@attributes":{"term":"git"}}]},{"title":"OpenChange\u00a0Interview","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/173-OpenChange-Interview.html","rel":"alternate"}},"published":"2007-06-04T11:24:04+02:00","updated":"2007-06-04T11:24:04+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-06-04:173-OpenChange-Interview.html","summary":"<p>Linux Weekly News had a good interview with Julien Kerihuel, lead developer of\nOpenChange, two weeks ago. It&#8217;s now <a class=\"reference external\" href=\"http:\/\/lwn.net\/Articles\/234642\/\">also available<\/a> for those who are not&nbsp;subscribed.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"interview"}},{"@attributes":{"term":"openchange"}}]},{"title":"Using a pqm with\u00a0Subversion","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/172-Using-a-pqm-with-Subversion.html","rel":"alternate"}},"published":"2007-05-25T12:04:14+02:00","updated":"2007-05-25T12:04:14+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-05-25:172-Using-a-pqm-with-Subversion.html","summary":"<p>One of the things that I&#8217;ve always missed in <span class=\"caps\">DVCS<\/span> is the ability to refuse\ncommits in a branch that&#8217;s shared by multiple people based on a test suite run.\nSure, it&#8217;s possible to have a pre-commit hook - but that would mean that you&#8217;d\nhave to wait for the full test suite to run until the commit finishes.\nWith the time it takes to run the Samba testsuite, this is not really an&nbsp;option.<\/p>\n<p>One of the things that would work is to have everybody work in a separate\nbranch and then have some sort of tool that merges those revisions from\neverybody&#8217;s personal branches that worked ok. However, to my knowledge, there\nis no such tool for&nbsp;Subversion.<\/p>\n<p>Bazaar uses a tool called <span class=\"caps\">PQM<\/span> (Patch Queue Manager). <span class=\"caps\">PQM<\/span> usually controls the\nmain branch (for example for Bazaar, it controls bzr.dev), and waits for\n<span class=\"caps\">GPG<\/span>-signed requests to merge a specific revision into that main branch. Before\naccepting such a revision, it will try to run the testsuite to make sure it\npasses. This guarantees that the main branch never contains broken code (as far\nas can be indicated by the&nbsp;testsuite).<\/p>\n<p>Now that bzr-svn supports true push, it is possible to actually use a <span class=\"caps\">PQM<\/span> with\na Subversion branch. I&#8217;ve tried it on a smaller branch last week, and am now\nlooking into using this for my Samba&nbsp;work.<\/p>\n","category":[{"@attributes":{"term":"samba"}},{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"subversion"}},{"@attributes":{"term":"bzr_svn"}}]},{"title":"London","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/171-London.html","rel":"alternate"}},"published":"2007-05-19T14:56:19+02:00","updated":"2007-05-19T14:56:19+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-05-19:171-London.html","summary":"<p>I&#8217;m currently doing a bit of sightseeing in London, after attending the\nBazaar sprint at the Canonical office. It was a good sprint, and quite\ndifferent from the previous ones -  in that there was only a limited amount of\nactual coding involved. The view from the Canonical office is magnificent, so\nwe were even able to do some sightseeing while&nbsp;working&#8230;<\/p>\n<p>Bazaars&#8217; focus has previously mainly been on correctness and features. The\nfirst has always been one of our strengths, and we&#8217;re in pretty good shape\nregarding the second. Performance has been one of the main complaints from\nusers about Bazaar and so we have recently tried to improve in that&nbsp;area.<\/p>\n<p>Since 0.12, we have already tried to optimise some of the common code paths and\nsome people have been working on a high performance smart server (to speed up\nremote&nbsp;operations).<\/p>\n<p>During the first two-and-a-half days of the sprint, we analysed 20\nof the most common use cases with Bazaar and determined what complexity they\nshould ideally require to be able to work. After this analysis, we looked at\nways to change our data structures to reach these&nbsp;goals.<\/p>\n<p>I have mainly been a spectator during the latter parts of these discussion, but\nthey were interesting to&nbsp;follow.<\/p>\n<p>One of the things I worked on was support for true push in bzr-svn. This was\none of the bugs that has bitten a lot of users of bzr-svn. The upcoming bzr-svn\n0.4 now supports true push as well as commits in heavyweight checkouts. I hope\nto release 0.4 after adding nested tree and ignores support so that I don&#8217;t\nhave to change the internal mapping mechanisms&nbsp;again.<\/p>\n<p>And now, it is time for some more sightseeing. After that I hope to get\nback to the reason I&#8217;m doing all of this in the first place:&nbsp;Samba!<\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"subversion"}},{"@attributes":{"term":"uk"}},{"@attributes":{"term":"bzr_svn"}}]},{"title":"SambaXP: a year with leaps of\u00a0progress","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/169-SambaXP-a-year-with-leaps-of-progress.html","rel":"alternate"}},"published":"2007-04-30T11:35:00+02:00","updated":"2007-04-30T11:35:00+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-04-30:169-SambaXP-a-year-with-leaps-of-progress.html","summary":"<p>Like most of the Samba team, I attended <a class=\"reference external\" href=\"http:\/\/www.sambaxp.org\/\">SambaXP<\/a> in Goettingen again last week. This year we were able to announce a couple of big leaps&nbsp;forward:<\/p>\n<div class=\"section\" id=\"openchange\">\n<h2>OpenChange<\/h2>\n<p>Julien&#8217;s talk about <a class=\"reference external\" href=\"http:\/\/www.openchange.org\/\">OpenChange<\/a> was probably the most interesting and surprising one this year. After three years of hard work (I remember spending a lot of time in front of a beamer looking at network packets in 2004 when they started), the OpenChange team has figured out the enough bits of the <span class=\"caps\">MAPI<\/span> (Exchange\/Outlook) protocol that they can fetch and send emails using an Exchange&nbsp;server.<\/p>\n<p>At the moment, there is a simple command-line client that can fetch into a mbox file and send mails in a way somewhat similar to the &#8220;mail&#8221; command. There also is a highly experimental plugin for&nbsp;evolution.<\/p>\n<p>Most work will now have to focus on the most interesting bit - providing a Free Software implementation of a <span class=\"caps\">MAPI<\/span>&nbsp;server.<\/p>\n<\/div>\n<div class=\"section\" id=\"drsuapi\">\n<h2><span class=\"caps\">DRSUAPI<\/span><\/h2>\n<p>Metze announced that he&#8217;s been able to work out how the directory replication protocol that is used between <span class=\"caps\">DC<\/span>&#8217;s in an Active Directory environment works. This is very important, because we need that protocol in order to be able to live as a <span class=\"caps\">DC<\/span> in an Active Directory environment that has more than one <span class=\"caps\">DC<\/span>.<\/p>\n<p>Halfway through preparing our (now yearly) talk about the status of Samba 4, Andrew and I realized we&#8217;re actually not too far away from being able to do the first alpha of Samba 4. We hope we can release one in the next few&nbsp;months.<\/p>\n<\/div>\n","category":{"@attributes":{"term":"samba"}}},{"title":"UK\u00a0Summer","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/166-UK-Summer.html","rel":"alternate"}},"published":"2007-04-16T12:22:57+02:00","updated":"2007-04-16T12:22:57+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-04-16:166-UK-Summer.html","summary":"<p>Great Britain appears to be the place to be this summer; a lot of the annual\nconferences are held in various cities around the <span class=\"caps\">UK<\/span> this year: <a class=\"reference external\" href=\"http:\/\/www.debconf.org\">DebConf<\/a>\n(Edinborough, 17-23 June), <a class=\"reference external\" href=\"http:\/\/www.guadec.org\/\"><span class=\"caps\">GUADEC<\/span><\/a> (Birmingham, 15-21 July), <a class=\"reference external\" href=\"http:\/\/akademy.kde.org\/\">Akademy<\/a>\n(Glasgow, 30 June-7 July) and last but not least the\nnext <a class=\"reference external\" href=\"http:\/\/bazaar-vcs.org\/SprintLondonMay07\">Bazaar sprint<\/a> (London, 14-20&nbsp;May).<\/p>\n<p>I&#8217;ll be attending at least the Bazaar sprint and <a class=\"reference external\" href=\"http:\/\/www.lugradio.org\/live\/2007\/index.php\/Schedule\"><span class=\"caps\">LUG<\/span> Radio Live<\/a>, and I\nhope to be present at <span class=\"caps\">GUADEC<\/span>, time&nbsp;permitting.<\/p>\n","category":{"@attributes":{"term":"uk"}}},{"title":"Bazaar for dvcs\u00a0users","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/165-Bazaar-for-dvcs-users.html","rel":"alternate"}},"published":"2007-03-31T22:36:12+02:00","updated":"2007-03-31T22:36:12+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-03-31:165-Bazaar-for-dvcs-users.html","summary":"<p><a class=\"reference external\" href=\"http:\/\/changelog.complete.org\/\">John Goerzen<\/a> has been evaluating various version control systems and his\nblogs posts on the subject have been interesting. One of the most interesting\npoints he raises about Bazaar is that there is no &#8220;darcs send&#8221;-like support.\nThe <a class=\"reference external\" href=\"http:\/\/launchpad.net\/bzr-submit\">&#8220;submit&#8221;<\/a> plugin gets close, but I think it misses some important\nfeatures - and I agree it should be part of the&nbsp;core.<\/p>\n<p>I&#8217;m not sure that the merge support in Bazaar is worse than that in Mercurial\nor Git. I&#8217;ve never had problems with it, and I use it <em>a lot<\/em>. Performance,\nother than remote access, is also no longer a problem for medium size projects\nas of 0.15. <em>Update<\/em>: it&#8217;s no longer as much of a problem as it used to be.\nRemote access is still significantly slower than it can be, but people are\nworking hard on fixing that&nbsp;problem.<\/p>\n<p>It&#8217;s also interesting to see that the Bazaar user interface and documentation\nis apparently confusing to people who are mostly familiar with other\ndistributed version control systems rather than centralized systems. We\ndefinitely need to work on&nbsp;that.<\/p>\n<p>The fact that John doesn&#8217;t come from <span class=\"caps\">CVS<\/span> or Subversion also explains that\ncheckouts don&#8217;t appeal to&nbsp;him.<\/p>\n","category":{"@attributes":{"term":"vc"}}},{"title":"Bazaar and Subversion nested tree\u00a0support","link":{"@attributes":{"href":"https:\/\/www.jelmer.uk\/164-Bazaar-and-Subversion-nested-tree-support.html","rel":"alternate"}},"published":"2007-03-31T22:15:56+02:00","updated":"2007-03-31T22:15:56+02:00","author":{"name":"Jelmer Vernoo\u0133"},"id":"tag:www.stationary-traveller.eu,2007-03-31:164-Bazaar-and-Subversion-nested-tree-support.html","summary":"<p>As of 0.15, Bazaar will have initial support for nested trees. Nested trees\nbasically allow you to add a &#8216;magic&#8217; directory to a Bazaar branch that in\nitself is another Bazaar branch. A very good use case of this is\nif you have a project for which you need to include some library (e.g. popt).\nNested trees allow you to add a reference to the upstream popt branch, avoiding\nthe need to synchronize every time upstream fixes a&nbsp;bug.<\/p>\n<p>Subversion has similar functionality, although the term used there is\n&#8216;externals&#8217;.  Externals are quite easy to use - using them only requires setting\nthe svn:externals&nbsp;property.<\/p>\n<p>I&#8217;ve done some early work on supporting externals in bzr-svn and mapping them\nto nested trees. At the moment, bzr-svn is able to track nested trees that are\nbeing added. Removes and changes to existing nested tree locations are still on\nmy todo list, but will definitely be supported in bzr-svn&nbsp;0.4.0.<\/p>\n","category":[{"@attributes":{"term":"bzr"}},{"@attributes":{"term":"subversion"}},{"@attributes":{"term":"bzr_svn"}}]}]}