<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>The journey that counts</title><link>https://blog.journeythatcounts.nl/</link><description>Recent content on The journey that counts</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 28 Dec 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.journeythatcounts.nl/index.xml" rel="self" type="application/rss+xml"/><item><title>My Emacs package Orgox to publish my notes</title><link>https://blog.journeythatcounts.nl/posts/2025/12/28/my-emacs-package-orgox-to-publish-my-notes/</link><pubDate>Sun, 28 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2025/12/28/my-emacs-package-orgox-to-publish-my-notes/</guid><description>&lt;p>Currently you&amp;rsquo;re reading a note from a repository of notes I maintain on GitHub,
&lt;a href="https://github.com/swinkels/notes">swinkels/notes&lt;/a>. Each note is an Org file and because GitHub has some support for
org-mode, the notes are rendered &amp;ldquo;ok-ish&amp;rdquo; when you view them in your browser. To
also have a more &amp;ldquo;professional&amp;rdquo; presence in the blogosphere, earlier this year I
published my notes at my &lt;a href="https://blog.journeythatcounts.nl">blog.journeythatcounts.nl&lt;/a> using the static website
generator &lt;a href="https://gohugo.io/">Hugo&lt;/a>. This note introduces the Emacs package I developed to convert
the notes to the Markdown files that Hugo expects, named &lt;a href="https://github.com/swinkels/orgox">Orgox&lt;/a>.&lt;/p></description></item><item><title>Automate a developer workflow in Emacs</title><link>https://blog.journeythatcounts.nl/posts/2025/03/23/automate-a-developer-workflow-in-emacs/</link><pubDate>Sun, 23 Mar 2025 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2025/03/23/automate-a-developer-workflow-in-emacs/</guid><description>&lt;p>During development of an application, multiple times I had to reset a process
that the application depended. This reset required a cumbersome sequence of
steps both in and outside of my IDE, Emacs. This note describes how I reduced
that workflow to a single call to an Emacs Lisp function.&lt;/p>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>For one of my clients I&amp;rsquo;ve been working on an application that creates a report
in the form of a static website. The application retrieves data from several
sources, processes it and reports the results through Markdown files, PNG files
for plots and HTML files for tables. The static website generator &lt;a href="https://squidfunk.github.io/mkdocs-material/">Material for
MkDocs&lt;/a>, MkDocs for short, builds a static website from these files.&lt;/p></description></item><item><title>Spacemacs and ruff to sort Python imports on save</title><link>https://blog.journeythatcounts.nl/posts/2025/01/08/spacemacs-and-ruff-to-sort-python-imports-on-save/</link><pubDate>Wed, 08 Jan 2025 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2025/01/08/spacemacs-and-ruff-to-sort-python-imports-on-save/</guid><description>&lt;p>Recently I introduced &lt;a href="https://docs.astral.sh/ruff/">ruff&lt;/a> in a Python project of a client to format the code
base and to sort the imports. Most of the developers there use PyCharm, which is
easy to configure to use ruff. Surprisingly, it turned out to be more difficult
in Spacemacs. To cut a long story short, Spacemacs&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> does not support the
use of ruff to sort Python imports &lt;em>on save&lt;/em>. For this it relies on the LSP
server but the official &lt;a href="https://docs.astral.sh/ruff/editors/#language-server-protocol">ruff LSP server&lt;/a> also does not support it.&lt;/p></description></item><item><title>Looking over the fence at Doom Emacs</title><link>https://blog.journeythatcounts.nl/posts/2024/12/28/looking-over-the-fence-at-doom-emacs/</link><pubDate>Sat, 28 Dec 2024 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2024/12/28/looking-over-the-fence-at-doom-emacs/</guid><description>&lt;p>In May of this year I decided to have a look at another Emacs starter kit&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>,
&lt;a href="https://github.com/doomemacs/doomemacs">Doom Emacs&lt;/a>. It&amp;rsquo;s not that I was dissatisfied with &lt;a href="https://www.spacemacs.org/">Spacemacs&lt;/a>, which has been my
trusty day-to-day driver for years, but it can be good to look over the fence
every once in a while and see what &amp;ldquo;the others&amp;rdquo; are doing.&lt;/p>
&lt;p>This note describes my experience with Doom as it was in May 2024, almost half a
year ago now. Since then, issues I encountered may have been resolved and new
ones may have been introduced. Also, part of what this note describes is from
memory and I &lt;em>will&lt;/em> have forgotten some of the good &lt;strong>and&lt;/strong> bad.&lt;/p></description></item><item><title>Using Emacs profiles side-by-side</title><link>https://blog.journeythatcounts.nl/posts/2024/12/24/using-emacs-profiles-side-by-side/</link><pubDate>Tue, 24 Dec 2024 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2024/12/24/using-emacs-profiles-side-by-side/</guid><description>&lt;p>This is very short note about &lt;a href="https://github.com/plexus/chemacs2">Chemacs2&lt;/a>, &amp;ldquo;an Emacs profile switcher, [which]
makes it easy to run multiple Emacs configurations side by side&amp;rdquo;. It&amp;rsquo;s something
I need to do that every now and then, for example when I want to test-drive the
latest &lt;a href="https://develop.spacemacs.org/">Spacemacs&lt;/a> without affecting my main development environment.&lt;/p>
&lt;p>Emacs 29 and later support the command-line option &lt;code>--init-directory=DIR&lt;/code> to
specify where Emacs should for its init files. Sometimes I have to use an older
Emacs version which makes that solution less ideal&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>. Until now I managed my
Emacs profiles using &lt;a href="https://www.gnu.org/software/stow/">stow&lt;/a>, which is a nice tool to manage symlinks. However, its
use case is not &amp;ldquo;Emacs profile switching&amp;rdquo; and that makes it somewhat cumbersome
to use.&lt;/p></description></item><item><title>Use Guix to build &amp; install an older Emacs version</title><link>https://blog.journeythatcounts.nl/posts/2024/07/24/use-guix-to-build--install-an-older-emacs-version/</link><pubDate>Wed, 24 Jul 2024 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2024/07/24/use-guix-to-build--install-an-older-emacs-version/</guid><description>&lt;p>I use Guix to manage the installation of some of my development tools, Emacs
being one of them. At the time of writing, Guix gives me Emacs 29.4 but what if
I need an older version? This note describes how I use Guix to install older
Emacs versions next to the most-recent one.&lt;/p>
&lt;p>Before I continue, a big shoutout to Steve George, whose &lt;a href="https://www.futurile.net/resources/guix/">Futurile blog&lt;/a> contains
a &lt;a href="https://www.futurile.net/resources/guix/">treasure trove of Guix documentation&lt;/a>.&lt;/p></description></item><item><title>Upgrading Spacemacs</title><link>https://blog.journeythatcounts.nl/posts/2024/03/24/upgrading-spacemacs/</link><pubDate>Sun, 24 Mar 2024 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2024/03/24/upgrading-spacemacs/</guid><description>&lt;p>Spacemacs consists of 2 parts,&lt;/p>
&lt;ul>
&lt;li>Spacemacs to manage and configure a set of third-party Emacs packags and&lt;/li>
&lt;li>the third-party packages themselves.&lt;/li>
&lt;/ul>
&lt;p>The Spacemacs code itself is continuously updated. These update bring new
features and fix bugs, or contain changes to take into account features or bugs
in the third-party packages. This means Spacemacs is coupled to the state of the
most-recent third-party packages. As Boromir would tell you,&lt;/p>
&lt;figure>&lt;img src="https://blog.journeythatcounts.nl/20240324/you-do-not-simply-upgrade-spacemacs.jpg">
&lt;/figure>
&lt;p>To avoid any issues, I always update Spacemacs from scratch whenever I update
Spacemacs. This means I have to update &lt;a href="https://github.com/swinkels/spacemacs-config">my Spacemacs configuration&lt;/a>, and install
the latest versions of the third-party packages. The last time I did that was
than a year ago - October 19, 2022 - and it was time for an update.&lt;/p></description></item><item><title>What makes a design object-oriented?</title><link>https://blog.journeythatcounts.nl/posts/2024/01/03/what-makes-a-design-object-oriented/</link><pubDate>Wed, 03 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2024/01/03/what-makes-a-design-object-oriented/</guid><description>&lt;p>On HackerNews there was &lt;a href="https://news.ycombinator.com/item?id=38781277">a discussion&lt;/a> about the presentation &amp;ldquo;&lt;a href="https://harmful.cat-v.org/software/OO_programming/_pdf/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf">Pitfalls of object
oriented programming&lt;/a>&amp;rdquo; (PDF). The HackerNews comments contain &lt;a href="https://news.ycombinator.com/item?id=38792682">a thread&lt;/a> about 4
characteristics of object-oriented programming (OOP), viz.&lt;/p>
&lt;ul>
&lt;li>abstraction,&lt;/li>
&lt;li>polymorphism,&lt;/li>
&lt;li>inheritance, and&lt;/li>
&lt;li>encapsulation.&lt;/li>
&lt;/ul>
&lt;p>I first encountered these characteristics in the early 2000s through the
mnemonic &amp;ldquo;A PIE&amp;rdquo;. I always found it to be a fuzzy &amp;ldquo;definition&amp;rdquo; as abstraction,
polymorphism and encapsulation aren&amp;rsquo;t unique to OOP. Another &lt;a href="https://news.ycombinator.com/item?id=38791122">thread&lt;/a> in the
comments made me wonder what it is that makes a design (or implementation)
&amp;ldquo;object-oriented&amp;rdquo;? This note tries to clarify that.&lt;/p></description></item><item><title>Using older documentation with Dash</title><link>https://blog.journeythatcounts.nl/posts/2023/12/17/using-older-documentation-with-dash/</link><pubDate>Sun, 17 Dec 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/12/17/using-older-documentation-with-dash/</guid><description>&lt;p>In note &lt;a href="https://blog.journeythatcounts.nl/posts/2023/01/16/accessing-offline-api-documentation-from-emacs/">20230116&lt;/a> I talked about the offline API browser &lt;a href="https://kapeli.com/dash">Dash&lt;/a>, a MacOS
application that lets you download the HTML documentation for various software
packages and search it offline. Dash doesn&amp;rsquo;t download the HTML documentation
from the original package location, but from its own sites. Other clients than
Dash can download these so-called docsets, but only Dash can download docsets
for older versions of a software package. Other clients can only access the most
recent build. This note describes how to build the docsets for older versions
yourself and install them side-by-side.&lt;/p></description></item><item><title>Creating animated GIFs of a desktop area</title><link>https://blog.journeythatcounts.nl/posts/2023/11/28/creating-animated-gifs-of-a-desktop-area/</link><pubDate>Tue, 28 Nov 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/11/28/creating-animated-gifs-of-a-desktop-area/</guid><description>&lt;p>In &lt;a href="https://blog.journeythatcounts.nl/posts/2023/10/29/introducing-pydor-an-emacs-package-to-run-doctests/">my previous note&lt;/a> I created &lt;a href="../10/pydor-runs-doctests.gif">an animated GIF&lt;/a> of how I used Emacs package pydor
to run Python doctests, of course from Emacs. An animated GIF is a really good
way to show how a tool like that works. I wouldn&amp;rsquo;t say that &amp;ldquo;an image says more
than a thousand words&amp;rdquo;, but it does add a lot to a textual description.&lt;/p>
&lt;p>The following two tools made it really easy to create the animated GIF:&lt;/p></description></item><item><title>Introducing pydor, an Emacs package to run doctests</title><link>https://blog.journeythatcounts.nl/posts/2023/10/29/introducing-pydor-an-emacs-package-to-run-doctests/</link><pubDate>Sun, 29 Oct 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/10/29/introducing-pydor-an-emacs-package-to-run-doctests/</guid><description>&lt;p>&lt;a href="https://develop.spacemacs.org/">Spacemacs&lt;/a> configures several key bindings to run Python unit tests, such as &amp;ldquo;run
test at point&amp;rdquo; and &amp;ldquo;run tests in current module&amp;rdquo;. It lacks the functionality to
run doctests so I wrote a small Emacs package for that: &lt;a href="https://github.com/swinkels/pydor">pydor&lt;/a>, the Python
doctest runner. The following animated GIF shows how it works in Spacemacs:&lt;/p>
&lt;figure>&lt;img src="https://blog.journeythatcounts.nl/20231029/pydor-runs-doctests.gif">
&lt;/figure>
&lt;p>The Emacs package is implemented by an Emacs Lisp file to determine the location
of the docstring at point and a Python file to load and run the doctests in that
docstring.&lt;/p></description></item><item><title>Build another Python version than Guix provides</title><link>https://blog.journeythatcounts.nl/posts/2023/08/03/build-another-python-version-than-guix-provides/</link><pubDate>Thu, 03 Aug 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/08/03/build-another-python-version-than-guix-provides/</guid><description>&lt;p>&lt;a href="https://git.savannah.gnu.org/cgit/guix.git/commit/?id=676508ac858928a2ec66f18ccfae17c9cec3dda2">My Guix installation&lt;/a>&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> provides Python 3 version 3.10.7. This note describes
how to use Guix to install another Python 3 version. This turned out to be much
more elaborate than expected&amp;hellip;&lt;/p>
&lt;h2 id="management-summary">Management summary&lt;/h2>
&lt;p>To build a Python version that Guix does not provide out-of-the-box, you&lt;/p>
&lt;ul>
&lt;li>find the package specification of the most recent Python version that &lt;em>is&lt;/em>
supported by Guix but still &lt;em>precedes&lt;/em> the version you need,&lt;/li>
&lt;li>create a package variant that derives from that specification and&lt;/li>
&lt;li>build the variant.&lt;/li>
&lt;/ul>
&lt;p>To give an example, Guix repo file &lt;a href="https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/python.scm?id=676508ac858928a2ec66f18ccfae17c9cec3dda2#n422">gnu/packages/python.scm&lt;/a> contains the package
specification of Python 3.10.7 that my Guix installation uses. I have created a
package variant that inherits this specification and that overrides the parts
required to build 3.10.12, see &lt;a href="https://blog.journeythatcounts.nl/20230803/python-3.10.12.scm">20230803/python-3.10.12.scm&lt;/a>. The following
command builds that Python version:&lt;/p></description></item><item><title>Trying out Visual Studio (WIP)</title><link>https://blog.journeythatcounts.nl/posts/2023/04/23/trying-out-visual-studio-wip/</link><pubDate>Sun, 23 Apr 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/04/23/trying-out-visual-studio-wip/</guid><description>&lt;p>For the first time in 6 years, I had to use Windows for Python development for
one of my contracts. Using Windows isn&amp;rsquo;t a problem, but it turned out that using
Spacemacs on Windows wasn&amp;rsquo;t as seamless an experience as I remember the use of a
rather standard Emacs config was. It takes about 40 seconds to load my Spacemacs
config, magit is almost unusably slow and the biggest issue: several times a
week I have to kill Emacs because the helm interface locks up.&lt;/p></description></item><item><title>Create DataFrame from string table</title><link>https://blog.journeythatcounts.nl/posts/2023/03/18/create-dataframe-from-string-table/</link><pubDate>Sat, 18 Mar 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/03/18/create-dataframe-from-string-table/</guid><description>&lt;p>You can find the code for the &lt;code>read_table&lt;/code> function mentioned in this note in
subdirectory &lt;a href="https://github.com/swinkels/notes/tree/main/2023/03/20230318">20230318&lt;/a>.&lt;/p>
&lt;p>The really handy Pandas function &lt;code>read_fwf&lt;/code> creates a &lt;code>DataFrame&lt;/code> from a
fixed-width text table, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">io&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">table&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">FirstName LastName FirstAppearance
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">Donald Duck 1934
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">Mickey Mouse 1928
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">Goofy 1932
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># read_fwf expects a filename, either as a string, a path object, or as the&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># next line shows, a stream/file-like object&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">read_fwf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">io&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">StringIO&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">table&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"> FirstName LastName FirstAppearance
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">0 Donald Duck 1934
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1 Mickey Mouse 1928
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2 Goofy NaN 1932
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I mostly use it in unit tests, when I need to set up &lt;code>DataFrame&lt;/code> instances.
They&amp;rsquo;re easier to create using &lt;code>read_fwf&lt;/code> and the resulting code is more
readable, more communicative.&lt;/p></description></item><item><title>Using dash-docs from Spacemacs</title><link>https://blog.journeythatcounts.nl/posts/2023/02/26/using-dash-docs-from-spacemacs/</link><pubDate>Sun, 26 Feb 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/02/26/using-dash-docs-from-spacemacs/</guid><description>&lt;p>Spacemacs has a &lt;a href="https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Breaders/dash">Dash layer&lt;/a> but it doesn&amp;rsquo;t seem to add much to the functionality
the &lt;a href="https://github.com/dash-docs-el/helm-dash/blob/a599ec77d296c3725d684ebd241db9b96e3c975f/helm-dash.el#L40">dash-docs&lt;/a> packages provides out of the box. So instead of using that layer,
I&amp;rsquo;m using these packages directly and this note describes how.&lt;/p>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;p>To install a third-party package like &lt;code>helm-dash&lt;/code> in Spacemacs, you add it to
variable &lt;code>dotspacemacs-additional-packages&lt;/code>. &lt;code>helm-dash&lt;/code> &lt;em>requires&lt;/em> &lt;code>dash-docs&lt;/code>
so when Spacemacs installs &lt;code>helm-dash&lt;/code>, it will download &lt;code>dash-docs&lt;/code> from Melpa
&lt;em>unless it&amp;rsquo;s already installed&lt;/em>. However, I want Spacemacs to use my custom
version of &lt;code>dash-docs&lt;/code>, so I need to specify that too:&lt;/p></description></item><item><title> Fix "cannot open" error messages when using dash-docs</title><link>https://blog.journeythatcounts.nl/posts/2023/01/28/fix-cannot-open-error-messages-when-using-dash-docs/</link><pubDate>Sat, 28 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/01/28/fix-cannot-open-error-messages-when-using-dash-docs/</guid><description>&lt;p>Haha, initially this note described a fix I made for an issue in &lt;a href="https://github.com/dash-docs-el/helm-dash">helm-dash&lt;/a> and
that I created a pull request to get it merged upstream. However, while writing
this note I realized I implemented the wrong approach and that I had to close
the pull request unmerged. Let&amp;rsquo;s describe the problem first.&lt;/p>
&lt;h2 id="the-problem">The problem&lt;/h2>
&lt;p>In &lt;a href="https://blog.journeythatcounts.nl/posts/2023/01/16/accessing-offline-api-documentation-from-emacs/">my note&lt;/a> about helm-dash, an Emacs package to access offline documentation
provided by &lt;a href="https://kapeli.com/dash">Dash&lt;/a>, I mentioned the &lt;code>*dash-docs-error*&lt;/code> buffer opens with messages
like this:&lt;/p></description></item><item><title>Accessing offline API documentation from Emacs</title><link>https://blog.journeythatcounts.nl/posts/2023/01/16/accessing-offline-api-documentation-from-emacs/</link><pubDate>Mon, 16 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/01/16/accessing-offline-api-documentation-from-emacs/</guid><description>&lt;p>Prominent Python developer and blogger Hynek Schlawack wrote a &lt;a href="https://hynek.me/articles/productive-fruit-fly-programmer/">blog post&lt;/a> about
the offline API browser &lt;a href="https://kapeli.com/dash">Dash&lt;/a>. Dash is a MacOS application that lets you download
the API documentation of multiple software packages and search it offline. You
start it with a press of a button, enter your search terms and it searches the
documentation you downloaded. At the time of writing this, the Dash website
states that it has the documentation of over 200+ software packages, for example
C++, Pandas, Python and Qt.&lt;/p></description></item><item><title>Error dialog about pythoncom39.dll in conda virtualenv</title><link>https://blog.journeythatcounts.nl/posts/2023/01/05/error-dialog-about-pythoncom39.dll-in-conda-virtualenv/</link><pubDate>Thu, 05 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/01/05/error-dialog-about-pythoncom39.dll-in-conda-virtualenv/</guid><description>&lt;p>At a client I had to review the code of a new Python project. I cloned the repo,
used conda to create a virtualenv and finally let Poetry install all Python
dependencies. This went without a hitch but after the installation of the
dependencies, each subsequent Poetry command would show me an error dialog like
this:&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-nil" data-lang="nil">(my-venv) C:\Users\Pieter\repos\my-venv&amp;gt;poetry cache list --help
&lt;/code>&lt;/pre>&lt;figure>&lt;img src="https://blog.journeythatcounts.nl/20230105/poetry-error.png">
&lt;/figure>
&lt;p>So each Poetry command triggered a failing search for a specific procedure in a
DLL in my &lt;em>base&lt;/em> conda environment. Some googling (and trial &amp;amp; error) lead me to
&lt;a href="https://github.com/mhammond/pywin32/blob/main/README.md#the-specified-procedure-could-not-be-found--entry-point-not-found-errors">this section&lt;/a> of the README of the pywin32 package:&lt;/p></description></item><item><title>Poetry dependency resolution and Python versions</title><link>https://blog.journeythatcounts.nl/posts/2023/01/04/poetry-dependency-resolution-and-python-versions/</link><pubDate>Wed, 04 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/01/04/poetry-dependency-resolution-and-python-versions/</guid><description>&lt;p>In a virtualenv using Python 3.9.15, a &lt;code>poetry install&lt;/code> failed with the
following message:&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-nil" data-lang="nil">Updating dependencies
Resolving dependencies...
The current project&amp;#39;s Python requirement (&amp;gt;=3.9,&amp;lt;4.0) is not compatible with some of the required packages Python requirement:
- numpy requires Python &amp;gt;=3.7,&amp;lt;3.11, so it will not be satisfied for Python &amp;gt;=3.11,&amp;lt;4.0
&lt;/code>&lt;/pre>&lt;p>As Python 3.9.1 satisfies both the &amp;ldquo;current project&amp;rsquo;s Python requirement&amp;rdquo; and
that of numpy, I wondered why the command failed. Some googling lead me to &lt;a href="https://python-poetry.org/docs/master/faq/#why-is-poetry-telling-me-that-the-current-projects-python-requirement-is-not-compatible-with-one-or-more-packages-python-requirements">this
question&lt;/a> in the poetry FAQ:&lt;/p></description></item><item><title> James Shore's "Testing without Mocks"</title><link>https://blog.journeythatcounts.nl/posts/2023/01/01/james-shores-testing-without-mocks/</link><pubDate>Sun, 01 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2023/01/01/james-shores-testing-without-mocks/</guid><description>&lt;p>James Shore released &lt;a href="https://www.jamesshore.com/v2/projects/testing-without-mocks/testing-without-mocks">an update&lt;/a> of this article &amp;ldquo;Testing without Mocks: A Pattern
Language&amp;rdquo;. The article is about 40 pages long and it is accompanied by a
&lt;a href="https://mastodon.online/@jamesshore/109560187641736554">Mastodon thread&lt;/a> to explain it all. This note is my one-page summary of that
thread.&lt;/p>
&lt;p>Shore wants to avoid mocks as they have a tend to have &amp;ldquo;lots of detail about the
interactions the code&amp;rdquo;. This locks in in your implementation and makes bigger
refactorings really hard.&lt;/p></description></item><item><title>When I update version numbers</title><link>https://blog.journeythatcounts.nl/posts/2022/12/28/when-i-update-version-numbers/</link><pubDate>Wed, 28 Dec 2022 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2022/12/28/when-i-update-version-numbers/</guid><description>&lt;p>When a colleague asked me when to update the version number of a software
package, and how, this is what I answered.&lt;/p>
&lt;p>First of all, I strive to follow &lt;a href="https://semver.org/">semver&lt;/a>, even though there are scenario&amp;rsquo;s where
semver is less applicable. First a recap about semver, for a version x.y.z you&lt;/p>
&lt;ul>
&lt;li>increase z if there is a bug fix that leaves the new version backward-compatible;&lt;/li>
&lt;li>increase y if there is new functionality that leaves the new version backward-compatible;&lt;/li>
&lt;li>increase x if the new version is not backward-compatible.&lt;/li>
&lt;/ul>
&lt;p>Second, I only update the version number when I make a release. I go through the
list of changes in the CHANGELOG and decide whether to update z, y or x. I only
increment one of them and the rest I either leave as-is or reset to 0. To give
some examples of version changes:&lt;/p></description></item><item><title>GitHub fine-grained personal access tokens</title><link>https://blog.journeythatcounts.nl/posts/2022/12/26/github-fine-grained-personal-access-tokens/</link><pubDate>Mon, 26 Dec 2022 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2022/12/26/github-fine-grained-personal-access-tokens/</guid><description>&lt;p>If you need to push a commit to a GitHub repo over HTTPS and you don&amp;rsquo;t want to
provide a username &amp;amp; password, a GitHub &amp;ldquo;fine-grained personal access token&amp;rdquo; is
the way to go&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>. The owner of the repo can create that token and configure
(1) to which repo(s) it provides access and (2) the kind of access it allows to
these repo(s), the &lt;em>repository permissions&lt;/em>. The following screenshot shows some
of these permissions:&lt;/p></description></item><item><title>Git for Windows protocol error when using Pageant</title><link>https://blog.journeythatcounts.nl/posts/2022/12/08/git-for-windows-protocol-error-when-using-pageant/</link><pubDate>Thu, 08 Dec 2022 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2022/12/08/git-for-windows-protocol-error-when-using-pageant/</guid><description>&lt;p>On Windows I use the SSH agent &lt;code>pageant&lt;/code> to manage my keys for Git. This allows
me to use the same agent process from Windows and MSYS2 Zsh sessions. But after
I switched to &lt;code>pageant&lt;/code> on a workstation that previously used the &lt;a href="https://github.com/GitCredentialManager/git-credential-manager">Git Credential
Manager&lt;/a>, Git commands that accessed a remote, failed:&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-nil" data-lang="nil">C:\Users\Pieter\repos\my-repo&amp;gt; git pull
fatal: protocol error: bad line length character: logi
FATAL ERROR: Error reading from console: Error 109: The pipe has been ended.
&lt;/code>&lt;/pre>&lt;p>The first hit by Google was this question on StackOverflow, &lt;a href="https://stackoverflow.com/questions/8170436/git-remote-error-fatal-protocol-error-bad-line-length-character-unab">Git Remote: Error:
fatal: protocol error: bad line length character: Unab&lt;/a>. Most answers pointed in
the direction of &lt;code>pageant&lt;/code> and &lt;code>plink&lt;/code>, where &lt;code>plink&lt;/code> replaces the &lt;code>ssh&lt;/code> command
as it can talk to &lt;code>pageant&lt;/code>. Was &lt;code>pageant&lt;/code> running? Were the keys loaded? Those
all checked out so I focussed on &lt;code>plink&lt;/code>.&lt;/p></description></item><item><title>Let Git for Windows use Pageant as SSH agent</title><link>https://blog.journeythatcounts.nl/posts/2022/11/29/let-git-for-windows-use-pageant-as-ssh-agent/</link><pubDate>Tue, 29 Nov 2022 00:00:00 +0000</pubDate><guid>https://blog.journeythatcounts.nl/posts/2022/11/29/let-git-for-windows-use-pageant-as-ssh-agent/</guid><description>&lt;p>If you want &lt;a href="https://gitforwindows.org/">Git for Windows&lt;/a> to use Pageant as an SSH agent, you have to set
environment variable &lt;code>GIT_SSH&lt;/code> to the path of the Plink executable. Here,&lt;/p>
&lt;ul>
&lt;li>&lt;code>GIT_SSH&lt;/code> &amp;ldquo;is a program that is invoked instead of ssh when Git tries to
connect to an SSH host&amp;rdquo;&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>, and&lt;/li>
&lt;li>Plink is a Windows command-line tool to establish an SSH connection and comes
with the Putty suite of tools.&lt;/li>
&lt;/ul>
&lt;p>So Git for Windows will use Plink to connect to the repo server and Plink will
query a running Pageant instance for the SSH key-pair.&lt;/p></description></item></channel></rss>