<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Galagic</title><link>https://galagic.com/</link><atom:link href="https://galagic.com/index.xml" rel="self" type="application/rss+xml"/><description>Galagic</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Fri, 15 Nov 2024 15:08:02 +0000</lastBuildDate><image><url>https://galagic.com/media/logo_hu81c75902260345a3fdaa46a679b16cf4_3068_300x300_fit_lanczos_3.png</url><title>Galagic</title><link>https://galagic.com/</link></image><item><title>Moving On</title><link>https://galagic.com/post/20241115150802/moving-on/</link><pubDate>Fri, 15 Nov 2024 15:08:02 +0000</pubDate><guid>https://galagic.com/post/20241115150802/moving-on/</guid><description>&lt;p>It&amp;rsquo;s been a while since the last update. This week we&amp;rsquo;ve moved the website
you&amp;rsquo;re reading from one web host (Gandi) to another (GitLab Pages) and in the
process open sourced the code behind it. So if you&amp;rsquo;re curious about the code
itself you can check it out at &lt;a href="https://gitlab.com/thegalagic/galagic_com" target="_blank" rel="noopener">galagic_com
(gitlab.com)&lt;/a>.&lt;/p>
&lt;p>We do need to update the theme on this site as it&amp;rsquo;s got seriously out of date
and I&amp;rsquo;m not happy with its performance/load. I think we&amp;rsquo;ll be looking for something
a lot simpler as all we need is good old text and images. That&amp;rsquo;s a job for
another day though.&lt;/p>
&lt;p>Bigger changes have been afoot but I think I&amp;rsquo;ll save those for another post.
If you do want to know what we&amp;rsquo;ve been working on take a look at our in-progress
educational game: &lt;a href="https://innercitylearners.com/" target="_blank" rel="noopener">Inner City Learners&lt;/a>.&lt;/p></description></item><item><title>Hacking on a Ledger</title><link>https://galagic.com/post/20231201155114/hacking-on-a-ledger/</link><pubDate>Fri, 01 Dec 2023 15:51:14 +0000</pubDate><guid>https://galagic.com/post/20231201155114/hacking-on-a-ledger/</guid><description>&lt;p>&lt;a href="https://ledger-cli.org/" target="_blank" rel="noopener">Ledger (ledger-cli.org)&lt;/a> is a gem of a program for
managing your finances. Dating from 2003 it embodies the UNIX philosophy of
being highly minimalist and modular. In the form of a command-line tool it lets
you run queries on your financial data, held in ledger files that have a simple,
textual format. The format is so simple in fact you can easily write them by
hand.&lt;/p>
&lt;p>The elegant design of Ledger birthed a whole ecosystem and a new approach to
personal accounting. For an excellent guide visit &lt;a href="https://plaintextaccounting.org/" target="_blank" rel="noopener">Plain Text Accounting
(plaintextaccounting.org)&lt;/a>.&lt;/p>
&lt;p>I&amp;rsquo;ve been using Ledger for a long time but one thing has always caused me a
problem. In the UK our tax year starts on the 6th April. It&amp;rsquo;s useful to
organise your financial records around this date, starting and ending each year
on that day. Ledger however always considers months, weeks and years to start on
the first day of the calendar period. You &lt;strong>can&lt;/strong> change which day Ledger considers
a week to start on, but this is not enough to cope with the UK&amp;rsquo;s tax year.&lt;/p>
&lt;p>Why does the UK use such a strange date? Like many things in the UK we should
probably blame/thank Henry VIII. For a deeper dive into that see &lt;a href="https://theconversation.com/why-the-uk-tax-year-begins-on-april-6-its-a-very-strange-tale-57247" target="_blank" rel="noopener">Why the UK tax
year begins on April 6
(theconversation.com)&lt;/a>.&lt;/p>
&lt;p>I found some discussion of this problem in Ledger&amp;rsquo;s forums and repository but it
looked like no one had ever gone as far as adding a feature. For a project that
had made my life a lot easier I was happy to make a contribution and see if I
could fix this myself.&lt;/p>
&lt;h2 id="getting-set">Getting set&lt;/h2>
&lt;p>Ledger has some good help to get started on development &lt;a href="https://github.com/ledger/ledger#for-the-impatient" target="_blank" rel="noopener">for-the-impatient
(github.com)&lt;/a>. Most usefully
it has a big python script &lt;code>acprep&lt;/code> that attempts to configure your machine for
development. The only drawback was the uncertainty about exactly what it would
do to my system. Would the system changes live happily alongside other projects
I&amp;rsquo;m working on? I didn&amp;rsquo;t want to risk breaking anything so using a development
container seemed the obvious choice to isolate any changes.&lt;/p>
&lt;p>I am a Fedora user and &lt;a href="https://containertoolbx.org/" target="_blank" rel="noopener">toolbx
(containertoolbx.org)&lt;/a> is integrated so well that
it&amp;rsquo;s always what I try first. First I create a new container just for ledger:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&amp;gt; toolbox create -c ledger
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;gt; toolbox enter ledger
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Next I check out the ledger code and try the big script:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&amp;gt; git clone git@github.com:ledger/ledger.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;gt; &lt;span class="nb">cd&lt;/span> ledger
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;gt; ./acprep dependencies
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It completes without error so I try to build the project:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&amp;gt; ./acprep update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: INFO: Invoking primary phase: update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: INFO: Executing phase: update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: INFO: Executing phase: pull
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Already up to date.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: INFO: Executing phase: make
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: INFO: Executing phase: config
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: INFO: Executing phase: configure
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: INFO: System &lt;span class="nb">type&lt;/span> &lt;span class="nv">is&lt;/span> &lt;span class="o">=&lt;/span>&amp;gt; Linux
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: INFO: Setting up build &lt;span class="nv">flavor&lt;/span> &lt;span class="o">=&lt;/span>&amp;gt; debug
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">acprep: ERROR: Cannot find CMake, please check your PATH
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>CMake is missing. I guess this is probably the build tool for the project, but
I&amp;rsquo;m a bit surprised it wasn&amp;rsquo;t installed by &lt;code>acprep dependencies&lt;/code>. I install it
via &lt;code>dnf&lt;/code> and try the build again. This time I&amp;rsquo;m missing a C++ compiler. Taking
a step back I realise I probably need to start by installing the basic tools.
Perhaps the &lt;code>acprep&lt;/code> script assumes the compiler etc are already present. So to
try and save myself some time I use a dnf groupinstall to try and get a fully
working development setup:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&amp;gt; sudo dnf groupinstall &lt;span class="s2">&amp;#34;Development Tools&amp;#34;&lt;/span> &lt;span class="s2">&amp;#34;Development Libraries&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I try the build again - no difference! I am surprised again but perhaps
&amp;ldquo;Development Tools&amp;rdquo; does not cover C++ tools. Let&amp;rsquo;s address that:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&amp;gt; sudo dnf install gcc-c++
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Later I discover the dnf group &amp;ldquo;Development Tools&amp;rdquo; in fact contains things like
git, subversion, patching, diffing tools etc but no actual compilers. You can
see this with command &lt;code>dnf group info &amp;quot;Development Tools&amp;quot;&lt;/code>. My mistake. I
thought it might contain such things to actually work on the Linux kernel and
distro itself.&lt;/p>
&lt;p>Anyway back to the build. We get further now but still no success:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&amp;gt; ./acprep update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">CMake Error at CMakeLists.txt:233 &lt;span class="o">(&lt;/span>message&lt;span class="o">)&lt;/span>:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Ledger requires GMP version or greater, but only GMP version .. was found
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This looks odd. Some kind of complaint about GMP but the message seems to be
missing a few details. First I try install to GMP: it takes a bit of hunting
around for the right package name but it&amp;rsquo;s already installed anyway so it can&amp;rsquo;t
be that.&lt;/p>
&lt;p>Jumping into &lt;code>CMakeLists.txt&lt;/code> at line 233 I can see its doing some kind of work
to pull a version number from wherever it finds &lt;code>gmp.h&lt;/code>. I find this file in my
container and take a look at the contents. It doesn&amp;rsquo;t have any version
information in it but it does have a very useful comment at the top:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-c++" data-lang="c++">&lt;span class="line">&lt;span class="cl"> &lt;span class="o">*&lt;/span> &lt;span class="n">This&lt;/span> &lt;span class="n">gmp&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">h&lt;/span> &lt;span class="n">is&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="n">wrapper&lt;/span> &lt;span class="n">include&lt;/span> &lt;span class="n">file&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">the&lt;/span> &lt;span class="n">original&lt;/span> &lt;span class="n">gmp&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">which&lt;/span> &lt;span class="n">has&lt;/span> &lt;span class="n">been&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">*&lt;/span> &lt;span class="n">renamed&lt;/span> &lt;span class="n">to&lt;/span> &lt;span class="n">gmp&lt;/span>&lt;span class="o">-&amp;lt;&lt;/span>&lt;span class="n">arch&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Eventually I find that I have a file &lt;code>gmp-x86_64.h&lt;/code> and I think this is what
ledger actually wants to use. A quick hack in &lt;code>CMakeLists.txt&lt;/code> and we finally
have a successful build!&lt;/p>
&lt;p>This problem is very specific to developing with Linux I think. Small changes
between how things are packaged on different distros can cause these little road
bumps where you might have to hunt around for the right package name or file.
It&amp;rsquo;s probably best to try and use the distro that the authors of Ledger use
themselves. In the &lt;code>README.md&lt;/code> Ubuntu, Debian and Fedora are all
mentioned though so it&amp;rsquo;s not exactly clear what is the best choice.&lt;/p>
&lt;p>As I said earlier I also prefer toolbx for development containers but toolbx
defaults to using your host distro. More support for other distros is coming:
&lt;a href="https://blogs.gnome.org/uraeus/2023/11/29/fedora-workstation-39-and-beyond/" target="_blank" rel="noopener">Fedora Workstation 39 and beyond
(gnome.org)&lt;/a>.
I might also explore &lt;a href="https://distrobox.it/" target="_blank" rel="noopener">Distrobox (distrobox.it)&lt;/a> in future
which I think is more flexible, but you have to do a little more configuration.&lt;/p>
&lt;p>Anyway we&amp;rsquo;ve got Ledger building and the &lt;code>acprep&lt;/code> script they provide worked
fine once we got the right dependencies installed. After a bit of digging I also
find the command to run the tests: &lt;code>ctest .&lt;/code> - they all pass. So we&amp;rsquo;re in a
nice place to start poking at the code.&lt;/p>
&lt;h2 id="poking-the-bear">Poking the bear&lt;/h2>
&lt;p>I have an idea of where I might need to make my changes (&lt;code>times.cc&lt;/code>) but initially
I just want to run Ledger and get some debug output to see what&amp;rsquo;s going on.&lt;/p>
&lt;p>For compiled languages you of course need to ensure you have run a build before
any changes can take effect. Coming recently from a python project the extra
delay that compilation causes feels like a real drag on progress, adding minutes
to each investigative change I make.&lt;/p>
&lt;p>I discover that setting the environment variable &lt;code>LEDGER_DEBUG&lt;/code> enables debug
output from Ledger which is very flexible. In fact I later find that the debug
options are very nicely documented in the Ledger manual: &lt;a href="https://ledger-cli.org/doc/ledger3.html#Debug-Options" target="_blank" rel="noopener">debug options
(ledger-cli.org)&lt;/a>. In
addition Ledger already has many useful debug messages included so you can learn
a lot just by turning them on.&lt;/p>
&lt;p>I add a lot of my own debug print messages but I&amp;rsquo;m struggling to really get a
handle on what&amp;rsquo;s happening by the time execution reaches the point of
calculating time periods. There&amp;rsquo;s some funky chained function
calls/handlers/filters that get setup early and then executed in order to
produce reports and it&amp;rsquo;s not yet clear to me how it all hangs together. See for
example the code in &lt;a href="https://github.com/ledger/ledger/blob/master/src/chain.cc" target="_blank" rel="noopener">chain.cc
(github.com)&lt;/a>.&lt;/p>
&lt;p>I realise I need to see the call stack whilst ledger is running to understand
what&amp;rsquo;s happening but have been wary of messing with a debugger. The last time I
used one was from within an IDE. It was very easy but I&amp;rsquo;m using vim and have
never tried debugging with it. However there&amp;rsquo;s no other option if I&amp;rsquo;m going to
make progress.&lt;/p>
&lt;p>Before we can debug we need to build the binary with debug symbols. This is as
simple as adding a flag to the compiler&amp;rsquo;s options but I end up hacking this into
the build process as I cannot see how to enable it easily through the &lt;code>acprep&lt;/code>
script I&amp;rsquo;m using to build. There must be a simpler way I&amp;rsquo;ve missed. I later
discover this is documented in &lt;a href="https://github.com/ledger/ledger/blob/master/CONTRIBUTING.md#building" target="_blank" rel="noopener">CONTRIBUTING.md
(github.com)&lt;/a>.
If only I had the patience to reads the docs first!&lt;/p>
&lt;p>So now I&amp;rsquo;ve got a debug build with symbols (which adds a bit more time to the
build unfortunately). With some trepidation I install &lt;code>gdb&lt;/code> and open its manual
expecting to wrestle with it for some time. Happily I find &lt;code>gdb&lt;/code> is actually
very approachable and has an excellent manual. I simply prepend my desired
ledger command with &lt;code>gdb&lt;/code> and I get a command line interface from which I can
set breakpoints, step, continue etc with very obvious commands. In no time at
all I find I can print the backtrace I wish to see and walk up and down it
examining the variables in each frame.&lt;/p>
&lt;p>Ledger makes use of the boost library which I understand is pretty standard in
C++. I see a lot of boost in the backtraces but largely I can just ignore it and
step into the source code before and after it.&lt;/p>
&lt;p>The only confusion I suffer with &lt;code>gdb&lt;/code> is around some mysterious SIGTTOU signals
which keep stopping execution. It initially misleads me into thinking some
Ledger code is being called twice (it isn&amp;rsquo;t) as &lt;code>gdb&lt;/code> stops before and after
the signals are received on my breakpoints it seems.&lt;/p>
&lt;p>It turns out this is a common issue when debugging a process that writes to the
terminal. &lt;code>Gdb&lt;/code> also writes to the same terminal causing the process under
observation to be signalled. The way around this is to remotely debug the
process from another terminal. It sounds complicated but in fact you just need
to use &lt;code>gdbserver&lt;/code> instead of &lt;code>gdb&lt;/code> and open another terminal window to connect
from. There&amp;rsquo;s a good summary of the process in the article &lt;a href="https://developers.redhat.com/articles/2022/12/27/debugging-binaries-invoked-scripts-gdb#using_gdbserver_to_avoid_writing_to_the_same_terminal_as_gdb" target="_blank" rel="noopener">Debugging binaries
invoked from scripts with GDB
(redhat.com)&lt;/a>.&lt;/p>
&lt;p>It all feels like hard work. Did I mention that I haven&amp;rsquo;t touched any C++ code
in over two decades?&lt;/p>
&lt;h2 id="making-the-change">Making the change&lt;/h2>
&lt;p>I was finally in a position to be able to make changes, debug and run tests -
the full dev cycle. Throughout this I made repeated use of &lt;code>git commit&lt;/code> and &lt;code>git stash&lt;/code> to make small steps forward/backward as I stumbled towards a better
understanding of what was going on.&lt;/p>
&lt;p>Most of the time was spent understanding how Ledger sets up report handlers in
one context and then runs them later in another with populated data. I
repeatedly had to jump into the debugger to check my understanding and print out
backtraces. A visual debugger which let me jump forward and backward in
execution time would have been useful. I believe &lt;code>gdb&lt;/code> can let you move forward
and backward in time but when I tried it said it was not supported with the
Ledger binary.&lt;/p>
&lt;p>I made heavy use of ripgrep to find code references and definitions but ideally
my editor (vim) should be setup to do this. I&amp;rsquo;ve used language servers with
other codebases before via the &lt;a href="https://microsoft.github.io/language-server-protocol/" target="_blank" rel="noopener">Language Server Protocol
(github.io)&lt;/a>. I need to
look into this for C++ though.&lt;/p>
&lt;p>Another point of difficulty for me was the use of macros in the source code.
Their presence makes debugging just a bit more tricky as the debugger could not
map from macro code back to the source files. There are ways around this
e.g. &lt;a href="https://stackoverflow.com/questions/985403/seeing-expanded-c-macros" target="_blank" rel="noopener">expanded C macros
(stackoverflow.com)&lt;/a>
but I could not get anything to work. Probably my inexperience here. I did read
a stack overflow answer suggesting macros are best avoided these days but I
don&amp;rsquo;t know how popular that opinion is in the C++ world.&lt;/p>
&lt;p>Eventually I worked out the right changes to make and where to put them. I added
some tests for my changes and got them passing. Running the full test suite I
discovered I&amp;rsquo;d broken the forecasting feature somehow. A little exception was
needed in the code for that and to save some time I learned how to run
individual tests with &lt;code>ctest&lt;/code>. It seems a little fiddly compared to other test
runners - having to specify a start test number, a stop test number, a step,
etc: &lt;a href="https://cmake.org/cmake/help/latest/manual/ctest.1.html#cmdoption-ctest-I" target="_blank" rel="noopener">ctest -I
(cmake.org)&lt;/a>.&lt;/p>
&lt;p>By this point my source tree is polluted with a lot of build artifacts, test
files, temporary files and others bits. Git status gives me two pages of
untracked files which makes seeing my real changes difficult. Maybe I&amp;rsquo;m doing
this wrong as I can&amp;rsquo;t believe people would put up with that. I prefer to have my
build outside of the source tree for exactly this reason and to keep a clean
separation. There&amp;rsquo;s probably some way to tell cmake to do that but I don&amp;rsquo;t know
it yet.&lt;/p>
&lt;p>Just one failing test remains - a test that runs all the code in Ledger&amp;rsquo;s
documentation to make sure all the examples are correct (which is great).
However I haven&amp;rsquo;t changed anything in there. I do a quick git stash, jump back
to master to check the tests were ok before all my changes. They are. I unstash
again and run the tests again. They all pass now, weird. Never mind then!&lt;/p>
&lt;h2 id="flagging-it-up">Flagging it up&lt;/h2>
&lt;p>To finish I add documentation on my changes into the Ledger manual. As I&amp;rsquo;m
writing I realise how weird my change is - it only works on periods of months
and years, not weeks. I avoided changing weeks as it made a bunch of existing
tests break. Hold on, that doesn&amp;rsquo;t feel right.&lt;/p>
&lt;p>The next day while doing something totally different, the idea to put my
changes behind a command line flag pops into my head. If I do that then I can
have my change work for all periods and not break existing users and tests.
Seems obvious now!&lt;/p>
&lt;p>I add a flag to the command line and now I can also put all my tests into their
own file, much cleaner. But &lt;code>ctest&lt;/code> doesn&amp;rsquo;t pick up my new test file. Turns out
that requires a full clean according to a chat from 2014(!): &lt;a href="https://groups.google.com/g/ledger-cli/c/_TikKtiq1SE/m/v7dasDBnoUcJ" target="_blank" rel="noopener">new tests not
being run
(groups.google.com)&lt;/a>.
Weird.&lt;/p>
&lt;p>All that&amp;rsquo;s left is just some final tidy-ups to the code to make sure variables
have sensible names. I realise I should probably rename the whole feature to
&amp;lsquo;align intervals&amp;rsquo; as I am starting to understand the jargon that&amp;rsquo;s used in the
manual around time periods. It makes sense. I do a bit more casual testing with
various weird intervals but it all seems to work fine. Ok we&amp;rsquo;re nearly there.&lt;/p>
&lt;h2 id="reaching-out">Reaching out&lt;/h2>
&lt;p>How to approach a project when you are ready to put forward a change? Not all
projects make it clear how they like to receive suggestions. The docs suggest
raising a bug. I feel this is the best approach, particularly as the issue has
been discussed previously and code changes were welcomed at the time. I could
have gone to the forums to discuss it first but feel that as I am ready to
suggest a code change the repository is best.&lt;/p>
&lt;p>I&amp;rsquo;ve seen projects cheerfully welcome PRs in chat but when you do submit
something it gets overlooked. There&amp;rsquo;s a lot written about maintainer burnout and
a PR adds to the workload of a busy team, so I don&amp;rsquo;t think you should ever
expect a reply.&lt;/p>
&lt;p>Anyway I get my branch into shape with some git cherry-picking, pulling out the
bits that are personal to my setup and push it all up. I create a &lt;a href="https://github.com/ledger/ledger/issues/2304" target="_blank" rel="noopener">bug
(github.com)&lt;/a> and then a &lt;a href="https://github.com/ledger/ledger/pull/2305" target="_blank" rel="noopener">pull
request (github.com)&lt;/a> to resolve it.&lt;/p>
&lt;h2 id="final-thoughts">Final thoughts&lt;/h2>
&lt;p>The delays in working with a compiled language are significant. Having just come
from a Python project where the change/test/investigate cycle was very fast the
difference was stark. I had to be strategic about when to kick off a compile as
it took several minutes. The lack of a REPL also stopped me trying things out
quickly.&lt;/p>
&lt;p>It makes me wonder if there&amp;rsquo;s a JIT for C++, even just for use during the
dev/test cycle to speed things up. I had a quick look and it seems there is a
thing called CLing: &lt;a href="https://softwareengineering.stackexchange.com/questions/29344/jit-compiler-for-c-c-and-the-likes" target="_blank" rel="noopener">JIT compiler for C, C++, and the likes
(stackexchange.com)&lt;/a>.
I might try that next time.&lt;/p>
&lt;p>I had apprehensions at the start, I&amp;rsquo;ve not touched C++ in decades. I thought it
would be a relatively simple change - in the end it was - but the process to get
there was not smooth. However I learned a lot and grew some confidence.
Particularly when I got gdb working and could really see what was going on
inside Ledger.&lt;/p>
&lt;p>I hope my change is useful to the project, even if it&amp;rsquo;s not accepted in its
current form but here&amp;rsquo;s hoping.&lt;/p></description></item><item><title>Flatpaking</title><link>https://galagic.com/post/20231103130047/flatpaking/</link><pubDate>Fri, 03 Nov 2023 13:00:47 +0000</pubDate><guid>https://galagic.com/post/20231103130047/flatpaking/</guid><description>&lt;p>I only use one snap app on my system and I wanted to see if it could be made
available as a flatpak as well. The app in question is the &lt;a href="https://github.com/trustcrypto/OnlyKey-App/" target="_blank" rel="noopener">OnlyKey-App
(github.com)&lt;/a>, for use with their
excellent USB security key: &lt;a href="https://onlykey.io/" target="_blank" rel="noopener">OnlyKey (onlykey.io)&lt;/a>. The app
is written to run on node/Chromium (NW.js). This was my first time building a flatpak
and I thought it might be straightforward. It was not.&lt;/p>
&lt;p>The flatpak build process is quite particular - builds are performed in a
forced offline environment which means a lot of work must go into obtaining
online sources/dependencies before the build starts and language tools such as
npm must be able to work offline too. I believe this stems from a desire of the
flatpak project to achieve reproducible builds in future, though I could not find
any official statement of this goal anywhere (see also: &lt;a href="https://ranfdev.com/blog/flatpak-builds-are-not-reproducible/" target="_blank" rel="noopener">Flatpak builds are not
reproducible and why that&amp;rsquo;s a practical
problem (ranfdev.com)&lt;/a>)&lt;/p>
&lt;p>Building a flatpak is mostly about crafting a suitable
&lt;a href="https://docs.flatpak.org/en/latest/first-build.html#add-a-manifest" target="_blank" rel="noopener">manifest
(flatpak.org)&lt;/a>
that describes how to build and package your app. You can look at the manifest
of &lt;a href="https://github.com/flathub" target="_blank" rel="noopener">existing apps (github.com)&lt;/a> to see how it works
or the handy quick start examples in &lt;a href="https://github.com/flatpak/flatpak-builder-tools/" target="_blank" rel="noopener">flatpak-builder-tools
(github.com)&lt;/a>.&lt;/p>
&lt;p>That last repo also contains language-specific tools from the flatpak project
that are essential for creating a working manifest. Luckily there&amp;rsquo;s a tool just
for node and it&amp;rsquo;s aware of NW.js too: &lt;code>flatpak-node-generator&lt;/code>. Essentially it
examines your package.json/package-lock.json and for each dependency it&amp;rsquo;ll
replace it with a local file reference and an instruction to flatpak-builder to
download and store the dependency before the offline build step.&lt;/p>
&lt;p>Unfortunately I hit two problems with the tool that I had to first
overcome:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/flatpak/flatpak-builder-tools/issues/377" target="_blank" rel="noopener">Npm provider&amp;rsquo;s generated-sources.json missing many packages
(ENOTCACHED) (github.com).&lt;/a>
My manifest did not include all the packages needed by the app, so the build
failed. The fix involved clearing up the way the tool looked through the
package-lock.json. I put a
&lt;a href="https://github.com/flatpak/flatpak-builder-tools/pull/378" target="_blank" rel="noopener">PR&lt;/a> together for
that.&lt;/li>
&lt;/ul>
&lt;p>Once this was solved I hit a separate issue - the installer for NW.js does not
work offline and of course that is required for flatpak. There was already a bug
filed (&lt;a href="https://github.com/nwjs/npm-installer/issues/77" target="_blank" rel="noopener">#77 (github.com)&lt;/a>) and
it was fixed recently but not yet released. So I had to fork that and patch our
app so it uses the fork.&lt;/p>
&lt;p>This caused me to run into the second problem with the flatpak-node-generator
tool:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/flatpak/flatpak-builder-tools/issues/381" target="_blank" rel="noopener">NotImplementedError: Git sources in lockfile v2 format are not supported
yet
(github.com)&lt;/a>.
It&amp;rsquo;s not possible to use a git reference with the tool whilst on the latest
version of node (actually the latest lockfile format). This was also solveable
but in the process I couldn&amp;rsquo;t really ignore all the various ways in which npm
can add a git reference to a project. So I ended making quite a few tests to
try and cover it all and submitted another
&lt;a href="https://github.com/flatpak/flatpak-builder-tools/pull/382" target="_blank" rel="noopener">PR&lt;/a>.&lt;/li>
&lt;/ul>
&lt;p>Finally after all this I got the flatpak built and running on my own machine
🎉 The final results are here: &lt;a href="https://github.com/Ian2020/io.onlykey.OnlyKey-App" target="_blank" rel="noopener">OnlyKey-App:
Unofficial flatpak build of the OnlyKey
app&lt;/a>&lt;/p>
&lt;p>Unfortunately this result is marred somewhat as it&amp;rsquo;s teetering on a pile
of outstanding PRs and patches. I hope the PRs get accepted in some form and
also the upstream OnlyKey project decide to take on the maintenance of the
flatpak I&amp;rsquo;ve created so other users can find it easily.&lt;/p>
&lt;p>Overall though this was a enjoyable challenge and I learnt much about building
flatpaks.&lt;/p></description></item><item><title>Figular got corked</title><link>https://galagic.com/post/20230919120725/figular-got-corked/</link><pubDate>Tue, 19 Sep 2023 12:07:25 +0100</pubDate><guid>https://galagic.com/post/20230919120725/figular-got-corked/</guid><description>&lt;p>The Figular domain is being retired shortly. Existing posts and content have
been archived to the Figular
&lt;a href="https://gitlab.com/thegalagic/figular/-/wikis/Home" target="_blank" rel="noopener">wiki&lt;/a> and historical links
on this site have been updated to point there. The code for Figular will remain
available at &lt;a href="https://gitlab.com/thegalagic/figular" target="_blank" rel="noopener">gitlab&lt;/a>.&lt;/p>
&lt;p>I&amp;rsquo;m still in love with the idea of creating diagrams from code and making a
universal language in which to do it. However I can no longer see a possible
path to making a living from it as an libre/free/open source product, at least
in a reasonable timeline.&lt;/p>
&lt;p>If you&amp;rsquo;re looking for something similar to Figular then
&lt;a href="https://mermaid.js.org/" target="_blank" rel="noopener">Mermaid&lt;/a> and &lt;a href="https://www.mermaidchart.com/" target="_blank" rel="noopener">Mermaid
Chart&lt;/a> (a new company providing development) look
to be going in a similar direction. I just hope the code remains completely
open.&lt;/p>
&lt;p>I must also mention the &lt;a href="https://kroki.io/" target="_blank" rel="noopener">Kroki&lt;/a> project who generously host
a huge list of textual diagramming tools. They are looking for sponsors to
continue covering their service.&lt;/p></description></item><item><title>Figular: style unleashed</title><link>https://galagic.com/post/20221006135620/figular-style-unleashed/</link><pubDate>Thu, 06 Oct 2022 13:56:20 +0100</pubDate><guid>https://galagic.com/post/20221006135620/figular-style-unleashed/</guid><description>&lt;p>Figular has had a recent release and adds lots of new options for styling
Figures. The example above shows some of the alternative colours and fonts
available with the
&lt;a href="https://gitlab.com/thegalagic/figular/-/blob/main/docs/figures/concept/circle.md" target="_blank" rel="noopener">Circle&lt;/a>
figure.&lt;/p>
&lt;p>To read more see the announcement on Figular.com: &lt;a href="https://gitlab.com/thegalagic/figular/-/wikis/Figular_Com/Posts/Style-Unleashed" target="_blank" rel="noopener">style unleashed&lt;/a>&lt;/p></description></item><item><title>Figular: org chart released</title><link>https://galagic.com/post/20220217144028/figular-org-chart-released/</link><pubDate>Thu, 17 Feb 2022 14:40:28 +0000</pubDate><guid>https://galagic.com/post/20220217144028/figular-org-chart-released/</guid><description>&lt;p>Figular has just released a new figure, check it out over on the Figular site at
&lt;a href="https://gitlab.com/thegalagic/figular/-/blob/main/docs/figures/org/orgchart.md" target="_blank" rel="noopener">Org
Chart&lt;/a>.
It lets you quickly create an org chart from plain text and you can diagram
other hierarchies too.&lt;/p>
&lt;p>To see a complex example and read more about it check out the announcement: &lt;a href="https://gitlab.com/thegalagic/figular/-/wikis/Figular_Com/Posts/A-new-Figure-the-Org-Chart" target="_blank" rel="noopener">A
new Figure - the Org Chart&lt;/a>.&lt;/p></description></item><item><title>Figular: first prototype available</title><link>https://galagic.com/post/20211105101500/figular-first-prototype-available/</link><pubDate>Fri, 05 Nov 2021 10:15:00 +0100</pubDate><guid>https://galagic.com/post/20211105101500/figular-first-prototype-available/</guid><description>&lt;p>An early version of Figular is now available and ready for you to
explore. Head over to the site to &lt;a href="https://gitlab.com/thegalagic/figular/-/wikis/Figular_Com/Try-It" target="_blank" rel="noopener">try it&lt;/a>.&lt;/p>
&lt;p>The release announcement &lt;a href="https://gitlab.com/thegalagic/figular/-/wikis/Figular_Com/Posts/First-steps" target="_blank" rel="noopener">&amp;ldquo;First
Steps&amp;rdquo;&lt;/a>
describes what it can do. Your feedback will shape the next version so do get in
touch to let us know what you think :-)&lt;/p></description></item><item><title>Figular: beautiful docs from plain text</title><link>https://galagic.com/post/20210917101500/figular-beautiful-docs-from-plain-text/</link><pubDate>Fri, 17 Sep 2021 10:15:00 +0100</pubDate><guid>https://galagic.com/post/20210917101500/figular-beautiful-docs-from-plain-text/</guid><description>&lt;p>I am happy to reveal that the first official Galagic creation will be called
&amp;lsquo;Figular&amp;rsquo;.&lt;/p>
&lt;p>Creating beautiful documents can mean fussing with design in Word
Processors, drawing and presentation software. What if we describe our content
and design entirely in plain text instead?&lt;/p>
&lt;p>Find out more about the motivation behind Figular in the blog post over on our
sister site: &lt;a href="https://gitlab.com/thegalagic/figular/-/wikis/Figular_Com/Posts/Why-Figular" target="_blank" rel="noopener">Why Figular&lt;/a>&lt;/p></description></item><item><title>Why does Galagic exist?</title><link>https://galagic.com/post/20200304134200/why-does-galagic-exist/</link><pubDate>Wed, 04 Mar 2020 13:42:00 +0000</pubDate><guid>https://galagic.com/post/20200304134200/why-does-galagic-exist/</guid><description>&lt;p>There are three things that brought me to the point of starting my own company:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Ideas worth building&lt;/strong> Over the years I&amp;rsquo;ve kept a note of interesting ideas
but many have only been tangentially related to my day job. Now I am at the
point of having the time and skills to build them.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Aligning effort with passion&lt;/strong> I have been lucky to have roles in the past that
have been totally absorbing and I am the type to be consumed by my work. However
this leaves little energy for anything else. I realised if I didn&amp;rsquo;t align my
occupation with the ideas I wanted to pursue they would never happen.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Perfect working conditions&lt;/strong> The most productive times I&amp;rsquo;ve had were working
in small teams that were left alone with a clear goal. However these moments have
been short-lived. I want to create a working environment that is always agile.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>What kind of software company will Galagic be? Free and sustainable:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Free&lt;/strong> As the use of computer technology grows in daily life so does the
need for the software running it to be open, respectful and available to all.
Free/libre and open source software (FLOSS) offers the best way to guarantee
this.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Sustainable&lt;/strong> I was always struck by the idea of &lt;a href="http://www.extremeprogramming.org/rules/overtime.html" target="_blank" rel="noopener">sustainable
pace&lt;/a> from Extreme
Programming. This concept now has its equivalent in business:
&lt;a href="https://www.zebrasunite.org/" target="_blank" rel="noopener">zebras&lt;/a>. These are companies that aim
for sustainable prosperity over exponential growth.&lt;/p>
&lt;/li>
&lt;/ul></description></item><item><title>Privacy Policy</title><link>https://galagic.com/privacy/</link><pubDate>Fri, 17 Jan 2020 17:21:05 +0000</pubDate><guid>https://galagic.com/privacy/</guid><description>&lt;p>This is version 1.2 of the Privacy Policy, as published 4th March 2021.&lt;/p>
&lt;h2 id="in-general">In General&lt;/h2>
&lt;p>We do not track you. We try our best to minimise the data we gather. We use
free and open tools whenever possible and we do not share your data with third
parties except as compelled by law. Unless prevented from doing so by law or
court order we will make a reasonable effort to notify users of any disclosure
of their information.&lt;/p>
&lt;p>We are not responsible for and do not have control over the privacy practices of
third-party sites that appear as links on this site. We encourage users to read
the privacy policies of any website visited via links from our website.&lt;/p>
&lt;h2 id="no-cookies">No Cookies&lt;/h2>
&lt;p>We do not use any cookies.&lt;/p>
&lt;h2 id="analytics">Analytics&lt;/h2>
&lt;p>We collect a minimum of data to ensure the website functions correctly and to
understand how the site is used.&lt;/p>
&lt;p>Our only data source are the logs written by &lt;a href="https://httpd.apache.org/" target="_blank" rel="noopener">apache
server (apache.org)&lt;/a> as configured by our hosting
provider &lt;a href="http://gandi.net/" target="_blank" rel="noopener">Gandi (gandi.net)&lt;/a>.&lt;/p>
&lt;p>These logs collect information your browser sends when you use our website:&lt;/p>
&lt;ul>
&lt;li>Your IP address&lt;/li>
&lt;li>Your &lt;a href="https://en.wikipedia.org/wiki/HTTP_referer" target="_blank" rel="noopener">&amp;lsquo;referer&amp;rsquo; (wikipedia.org)&lt;/a> -
the address of the web page you visited before our website&lt;/li>
&lt;li>Your &lt;a href="https://en.wikipedia.org/wiki/User_agent" target="_blank" rel="noopener">&amp;lsquo;user-agent string&amp;rsquo;
(wikipedia.org)&lt;/a> - the content
varies depending on your browser but typically might contain information on
your browser, system, platform and extensions.&lt;/li>
&lt;li>The URL you visited on our website&lt;/li>
&lt;li>The date and time of your visit&lt;/li>
&lt;/ul>
&lt;p>We retain the first three fields (IP address, referer and user-agent) in the
logs for &lt;strong>7 days&lt;/strong> to combat abuse and diagnose technical problems, after that
the fields are removed. &lt;strong>All data is deleted after 28 days&lt;/strong>.&lt;/p>
&lt;h2 id="attribution">Attribution&lt;/h2>
&lt;p>This policy is derived from:&lt;/p>
&lt;ul>
&lt;li>The &lt;a href="https://small-tech.org/privacy/" target="_blank" rel="noopener">Privacy
Policy (small-tech.org)&lt;/a> of the &lt;a href="https://small-tech.org" target="_blank" rel="noopener">Small Technology
Foundation (small-tech.org)&lt;/a> which is licensed under the
&lt;a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">Creative Commons Attribution-ShareAlike 4.0 International (creativecommons.org)&lt;/a>.&lt;/li>
&lt;li>The &lt;a href="https://www.eff.org/policy" target="_blank" rel="noopener">Privacy Policy (eff.org)&lt;/a> of the &lt;a href="https://www.eff.org/" target="_blank" rel="noopener">Electronic
Frontier Foundation (eff.org)&lt;/a> which is licensed under
the &lt;a href="http://creativecommons.org/licenses/by/3.0/us/" target="_blank" rel="noopener">Creative Commons Attribution 3.0 United States
License (creativecommons.org)&lt;/a>.&lt;/li>
&lt;/ul>
&lt;h2 id="licenses">Licenses&lt;/h2>
&lt;p>Everything we create is free and open source.&lt;/p>
&lt;p>All content on the Galagic website, excluding our trademarks and unless
otherwise stated, is licensed under the &lt;a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">Creative Commons Attribution-ShareAlike
4.0 International
(creativecommons.org)&lt;/a>.&lt;/p>
&lt;h2 id="feedback">Feedback&lt;/h2>
&lt;p>Please contact us with any feedback, data rectification or erasure requests
by email: &lt;a href="mailto:data.protection@galagic.com">data.protection@galagic.com&lt;/a>.&lt;/p>
&lt;h2 id="changes-to-this-policy">Changes to this policy&lt;/h2>
&lt;p>If anything in this policy changes the differences will be noted below.&lt;/p>
&lt;ul>
&lt;li>Updated 4th March 2021 to version 1.2. Added provision to inform users if
we are compelled to disclose their personal data.&lt;/li>
&lt;li>Updated 1st March 2021 to version 1.1. Provided a new email address for data
protection requests.&lt;/li>
&lt;/ul></description></item></channel></rss>