If you’re curious how I made the code samples in my earlier post on running old games in containers, read on!
You’ll note that this was a step-by-step tutorial, with a lot of
trial-and-error, and I wanted to show the reader all the errors and issues I
ran into, and what changes I had to make for each step, and I showed how the
runner script and the Dockerfile
changed along the way.
During the writing of the blog post, I had to update the code, clarify it add comments, and fix issues. It would have been quite tedious to manually update each of the step-by-step diffs in the blog post every time, so I wrote a script to automatically update all the diffs between each of the steps, and the blog post automatically included the diffs inline, and linked to the complete code.
Of course, if I wanted to make a change to the script in step 3, I would have to manually propagate it to the scripts in all the subsequent steps, but I would just update the shell script, and regenerate all the diffs automatically, which were sourced into the post with a Hugo shortcode.
Here’s the script that I used to create the diffs:
#!/bin/bash
#
# Copyright 2020 Misha Brukman
# SPDX-License-Identifier: Apache-2.0
# http://misha.brukman.net/blog/2020/04/running-decade-old-games-in-containers/
for dir in v*; do
declare -i version_num="${dir:1}"
if [ ${version_num} == 1 ]; then
continue;
fi
for file in Dockerfile runner.sh; do
# For consistency in Markdown rendering, convert all <Tab> characters,
# mostly visible in the --- and +++ lines to two spaces, so they render
# well.
#
# Hugo seems to render the first line with <Tab> longer than the second,
# creating less-than-clean output due to lack of alignment.
#
# While we're at it, we can drop the first 3 lines of the output to make
# it even cleaner.
diff -u "${dir:0:1}$((version_num - 1))/${file}" "${dir}/${file}" \
| sed "s/\t/ /g" \
| tail -n +4 \
> "${dir}/${file}.diff"
done
done
As you can see, all the version subdirectories are named v{number}
, e.g.,
v1
, v2
, up to v10
. The script processes the files runner.sh
and
Dockerfile
from one version to the next, ignoring the v1
directory since
there is nothing before it.
The primary delta computation is really the following:
diff -u "${dir:0:1}$((version_num - 1))/${file}" "${dir}/${file}" \
> "${dir}/${file}.diff"
which computes the delta from v{number - 1}
to v{number}
and outputs it
into the target directory of v{number}
, with a .diff
suffix for the
filename.
Then, I would include the file into the blog post as follows:
{{%
code
file="/blog/2020/04/running-decade-old-games-in-containers/v4/runner.sh.diff"
lang="diff"
%}}
Here, code
is a custom Hugo shortcode, which I discussed in an earlier
post.
To improve the readability and succinctness of the diff output, I added the other two filter lines you see in the script:
| sed "s/\t/ /g" \
| tail -n +4 \
As the comments in the script say, the sed
command replaces tabs with
2-spaces for consistency with my personal indentation style being 2 spaces for
code, particularly those used in that post.
Then, the tail
command drops the standard header that you see in the diff
output, which is quote verbose and would be repetitive if you had to see it 10
times in a single post.
Let’s consider a simple example:
$ echo 1 > foo
$ echo 2 > bar
$ diff -u foo bar > foo-bar.diff
If we include the above diff output as-is, we would get the following:
--- foo 2020-12-15 23:16:58.486504105 -0500
+++ bar 2020-12-15 23:16:58.486504105 -0500
@@ -1 +1 @@
-1
+2
However, if we preprocess the diff output with tail -n +4
, we will get a much
cleaner and simpler version:
-1
+2
which is the style of diffs that you see in my post.
Hope this was interesting and/or helpful! Let me know if you end up using this approach in your own writing.