<feed
    xmlns="http://www.w3.org/2005/Atom"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xml:lang="en">
  <link rel="self"      type="application/atom+xml" href="https://euandre.org/en/til/feed.xml" />
  <link rel="alternate" type="text/html"            href="https://euandre.org/en/til/" hreflang="en" />
  <title>EuAndreh&apos;s website</title>
  <subtitle>TIL</subtitle>
  <id>https://euandre.org/en/til/feed.xml</id>
  <updated>2026-09-13T12:14:51+00:00</updated>
  <author>
    <name>EuAndreh</name>
    <email>eu@euandre.org</email>
  </author>
  <entry xml:lang="en">
    <title type="html">
      Multiline comments in POSIX sh
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2026/09/05/multiline-sh-comments.html" title="Multiline comments in POSIX sh" />
    <published>
      2026-09-05T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2026/09/05/multiline-sh-comments.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I realized one can use heredocs for multiline comments in sh:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2026/09/05/multiline-sh-comments.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I realized one can use heredocs for multiline comments in sh:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;cat &amp;lt;&amp;lt;&apos;COMMENT&apos; &amp;gt; /dev/null
if wip; then
        unfinished and broken syntax &amp;gt;
fii
COMMENT&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;multiline-sh-comments.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;…​instead of:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;# if wip; then
#       unfinished and broken syntax &amp;gt;
# fii&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;multiline-sh-comments.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;What is going on: the &lt;a href=
          &quot;https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_07_04&quot;&gt;language defines&lt;/a&gt;
          &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; as a redirect of the &quot;here-document&quot; type. After &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; you can put
          anything, and sh will use that as a token to look for on the following lines:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;cat &amp;lt;&amp;lt;&apos;bleh&apos;
...
bleh&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;multiline-sh-comments.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Make sure to include the &lt;code&gt;’quotes’&lt;/code&gt; around the word, otherwise anything with a &lt;code&gt;$&lt;/code&gt;
          would get replaced just like a &lt;code&gt;&quot;double-quoted&quot;&lt;/code&gt; string.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;&quot;bleh&quot; works fine, like any word would.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;But that example left as-is would print the string to stdout. To avoid that, we shove the contents to
          &lt;code&gt;/dev/null&lt;/code&gt;. So it isn’t technically a comment, its more like a constant string that gets emitted
          and discarded.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Sure its hacky, but at this point what in sh isn’t? It even supports nesting!&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L3&quot;
     href=&quot;#B4-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L4&quot;
     href=&quot;#B4-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L5&quot;
     href=&quot;#B4-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L6&quot;
     href=&quot;#B4-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L7&quot;
     href=&quot;#B4-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L8&quot;
     href=&quot;#B4-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L9&quot;
     href=&quot;#B4-L9&quot;&gt;9&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;cat &amp;lt;&amp;lt;&apos;COMMENT1&apos; &amp;gt; /dev/null

cat &amp;lt;&amp;lt;&apos;COMMENT&apos; &amp;gt; /dev/null

# ... code ...

COMMENT

COMMENT1&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;multiline-sh-comments.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I’ve never committed any code with this, just used while debugging sh code. Make sure to handle with
          care&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Encoding and decoding JavaScript BigInt values with reviver
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2021/08/11/js-bigint-reviver.html" title="Encoding and decoding JavaScript BigInt values with reviver" />
    <published>
      2021-08-11T00:00:00+00:00
    </published>
    <updated>
      2021-08-13T00:00:00+00:00
    </updated>
    <id>
      https://euandre.org/en/til/2021/08/11/js-bigint-reviver.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;&lt;code&gt;JSON.parse()&lt;/code&gt; accepts a second parameter: a &lt;a href=
          &quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#using_the_reviver_parameter&quot;&gt;
          &lt;code&gt;reviver()&lt;/code&gt; function&lt;/a&gt;. It is a function that can be used to transform the &lt;code&gt;JSON&lt;/code&gt;
          values as they’re being parsed.&lt;/p&gt;
    </summary>
    <content type="html" xml:base="en/til/2021/08/11/js-bigint-reviver.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;&lt;code&gt;JSON.parse()&lt;/code&gt; accepts a second parameter: a &lt;a href=
          &quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#using_the_reviver_parameter&quot;&gt;
          &lt;code&gt;reviver()&lt;/code&gt; function&lt;/a&gt;. It is a function that can be used to transform the &lt;code&gt;JSON&lt;/code&gt;
          values as they’re being parsed.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As it turns out, when combined with JavaScript’s &lt;a href=
          &quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt&quot;&gt;&lt;code&gt;BigInt&lt;/code&gt;&lt;/a&gt;
          type, you can parse and encode JavaScript &lt;code&gt;BigInt&lt;/code&gt; numbers via JSON:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;const bigIntReviver = (_, value) =&amp;gt;
    typeof value === &quot;string&quot; &amp;amp;&amp; value.match(/^-?[0-9]+n$/)
        ? BigInt(value.slice(0, value.length - 1))
        : value;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;js-bigint-reviver.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I chose to interpret strings that contains only numbers and an ending &lt;code&gt;n&lt;/code&gt; suffix as
          &lt;code&gt;BigInt&lt;/code&gt; values, similar to how JavaScript interprets &lt;code&gt;123&lt;/code&gt; (a number) differently from
          &lt;code&gt;123n&lt;/code&gt; (a &lt;code&gt;bigint&lt;/code&gt;);&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;We do those checks before constructing the &lt;code&gt;BigInt&lt;/code&gt; to avoid throwing needless exceptions and
          catching them on the parsing function, as this could easily become a bottleneck when parsing large JSON
          values.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;In order to do the full roundtrip, we now only need the &lt;code&gt;toJSON()&lt;/code&gt; counterpart:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;BigInt.prototype.toJSON = function() {
    return this.toString() + &quot;n&quot;;
};&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;js-bigint-reviver.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;With both &lt;code&gt;bigIntReviver&lt;/code&gt; and &lt;code&gt;toJSON&lt;/code&gt; defined, we can now successfully parse and
          encode JavaScript objects with &lt;code&gt;BigInt&lt;/code&gt; values transparently:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L12&quot;
     href=&quot;#B3-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L13&quot;
     href=&quot;#B3-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L14&quot;
     href=&quot;#B3-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L15&quot;
     href=&quot;#B3-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L16&quot;
     href=&quot;#B3-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L17&quot;
     href=&quot;#B3-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L18&quot;
     href=&quot;#B3-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L19&quot;
     href=&quot;#B3-L19&quot;&gt;19&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;const s = `[
    null,
    true,
    false,
    -1,
    3.14,
    &quot;a string&quot;,
    { &quot;a-number&quot;: &quot;-123&quot; },
    { &quot;a-bigint&quot;: &quot;-123n&quot; }
]`;

const parsed = JSON.parse(s, bigIntReviver);
const s2 = JSON.stringify(parsed);

console.log(parsed);
console.log(s2);

console.log(typeof parsed[6][&quot;a-number&quot;])
console.log(typeof parsed[7][&quot;a-bigint&quot;])&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;js-bigint-reviver.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The output of the above is:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L3&quot;
     href=&quot;#B4-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L4&quot;
     href=&quot;#B4-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L5&quot;
     href=&quot;#B4-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L6&quot;
     href=&quot;#B4-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L7&quot;
     href=&quot;#B4-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L8&quot;
     href=&quot;#B4-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L9&quot;
     href=&quot;#B4-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L10&quot;
     href=&quot;#B4-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L11&quot;
     href=&quot;#B4-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L12&quot;
     href=&quot;#B4-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L13&quot;
     href=&quot;#B4-L13&quot;&gt;13&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;[
  null,
  true,
  false,
  -1,
  3.14,
  &apos;a string&apos;,
  { &apos;a-number&apos;: &apos;-123&apos; },
  { &apos;a-bigint&apos;: -123n }
]
[null,true,false,-1,3.14,&quot;a string&quot;,{&quot;a-number&quot;:&quot;-123&quot;},{&quot;a-bigint&quot;:&quot;-123n&quot;}]
string
bigint&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;js-bigint-reviver.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;If you’re on a web browser, you can probably try copying and pasting the above code on the console right
          now, as is.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Even though &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc8259&quot;&gt;&lt;code&gt;JSON&lt;/code&gt;&lt;/a&gt; doesn’t include
          &lt;code&gt;BigInt&lt;/code&gt; number, encoding and decoding them as strings is quite trivial on JavaScript.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      GPG verification of Git repositories without TLS
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2021/07/23/git-tls-gpg.html" title="GPG verification of Git repositories without TLS" />
    <published>
      2021-07-23T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2021/07/23/git-tls-gpg.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;For online Git repositories that use the [Git Protocol] for serving code, you can can use GPG to handle
          authentication, if you have the committer’s public key.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2021/07/23/git-tls-gpg.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;For online Git repositories that use the [Git Protocol] for serving code, you can can use GPG to handle
          authentication, if you have the committer’s public key.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Here’s how I’d verify that I’ve cloned an authentic version of &lt;a href=
          &quot;https://euandreh.xyz/remembering/&quot;&gt;remembering&lt;/a&gt;footnote:not-available[ Funnily enough, not available
          anymore via the Git Protocol, now only with HTTPS. ]:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L10&quot;
     href=&quot;#B1-L10&quot;&gt;10&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;$ wget -qO- https://euandre.org/public.asc | gpg --import -
gpg: clef 81F90EC3CD356060 : « EuAndreh &amp;lt;eu@euandre.org&amp;gt; » n&apos;est pas modifiée
gpg:       Quantité totale traitée : 1
gpg:                 non modifiées : 1
$ pushd `mktemp -d`
$ git clone git://euandreh.xyz/remembering .
$ git verify-commit HEAD
gpg: Signature faite le dim. 27 juin 2021 16:50:21 -03
gpg:                avec la clef RSA 5BDAE9B8B2F6C6BCBB0D6CE581F90EC3CD356060
gpg: Bonne signature de « EuAndreh &amp;lt;eu@euandre.org&amp;gt; » [ultime]&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;git-tls-gpg.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;On the first line we import the public key (funnily enough, available via HTTPS), and after cloning the
          code via the insecure &lt;code&gt;git://&lt;/code&gt; protocol, we use &lt;code&gt;git verify-commit&lt;/code&gt; to check the
          signature.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The verification is successful, and we can see that the public key from the signature matches the
          fingerprint of the imported one. However &lt;code&gt;git verify-commit&lt;/code&gt; doesn’t have an option to check which
          public key you want to verify the commit against. Which means that if a MITM attack happens, the attacker
          could very easily serve a malicious repository with signed commits, and you’d have to verify the public key
          by yourself. That would need to happen for subsequent fetches, too.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Even though this is possible, it is not very convenient, and certainly very brittle. Despite the fact that
          the Git Protocol is much faster, it being harder to make secure is a big downside.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Three-way conditional for number signs on Lisp
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2021/04/24/scm-nif.html" title="Three-way conditional for number signs on Lisp" />
    <published>
      2021-04-24T00:00:00+00:00
    </published>
    <updated>
      2021-08-14T00:00:00+00:00
    </updated>
    <id>
      https://euandre.org/en/til/2021/04/24/scm-nif.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;A useful macro from Paul Graham’s &lt;a href=&quot;https://www.paulgraham.com/onlisptext.html&quot;&gt;On Lisp&lt;/a&gt;
          book:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2021/04/24/scm-nif.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;A useful macro from Paul Graham’s &lt;a href=&quot;https://www.paulgraham.com/onlisptext.html&quot;&gt;On Lisp&lt;/a&gt;
          book:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;(defmacro nif (expr pos zero neg)
  (let ((g (gensym)))
    `(let ((,g ,expr))
       (cond ((plusp ,g) ,pos)
             ((zerop ,g) ,zero)
             (t ,neg)))))&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;scm-nif.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;After I looked at this macro, I started seeing opportunities to using it in many places, and yet I didn’t
          see anyone else using it.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The latest example I can think of is section 1.3.3 of &lt;a href=
          &quot;https://mitpress.mit.edu/sites/default/files/sicp/index.html&quot;&gt;Structure and Interpretation of Computer
          Programs&lt;/a&gt;, which I was reading recently:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L5&quot;
     href=&quot;#B2-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L6&quot;
     href=&quot;#B2-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L7&quot;
     href=&quot;#B2-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L8&quot;
     href=&quot;#B2-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L9&quot;
     href=&quot;#B2-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L10&quot;
     href=&quot;#B2-L10&quot;&gt;10&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;(define (search f neg-point pos-point)
  (let ((midpoint (average neg-point pos-point)))
    (if (close-enough? neg-point post-point)
        midpoint
        (let ((test-value (f midpoint)))
          (cond ((positive? test-value)
                 (search f neg-point midpoint))
                ((negative? test-value)
                 (search f midpoint pos-point))
                (else midpoint))))))&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;scm-nif.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Not that the book should introduce such macro this early, but I couldn’t avoid feeling bothered by not
          using the &lt;code&gt;nif&lt;/code&gt; macro, which could even remove the need for the intermediate
          &lt;code&gt;test-value&lt;/code&gt; variable:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;(define (search f neg-point pos-point)
  (let ((midpoint (average neg-point pos-point)))
    (if (close-enough? neg-point post-point)
        midpoint
        (nif (f midpoint)
             (search f neg-point midpoint)
             (midpoint)
             (search f midpoint pos-point)))))&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;scm-nif.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;It also avoids &lt;code&gt;cond&lt;/code&gt;’s extra clunky parentheses for grouping, which is unnecessary but
          built-in.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As a macro, I personally feel it tilts the balance towards expressivenes despite its extra cognitive load
          toll.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Clojure auto curry
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2021/04/24/clojure-autocurry.html" title="Clojure auto curry" />
    <published>
      2021-04-24T00:00:00+00:00
    </published>
    <updated>
      2021-04-27T00:00:00+00:00
    </updated>
    <id>
      https://euandre.org/en/til/2021/04/24/clojure-autocurry.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Here’s a simple macro defined by &lt;a href=
              &quot;https://lorettahe.github.io/clojure/2016/09/22/clojure-auto-curry&quot;&gt;Loretta He&lt;/a&gt; to create Clojure
    </summary>
    <content type="html" xml:base="en/til/2021/04/24/clojure-autocurry.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Here’s a simple macro defined by &lt;a href=
              &quot;https://lorettahe.github.io/clojure/2016/09/22/clojure-auto-curry&quot;&gt;Loretta He&lt;/a&gt; to create Clojure
              functions that are curried on all arguments, relying on Clojure’s multi-arity support:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;(defmacro defcurry
  [name args &amp; body]
  (let [partials (map (fn [n]
                        `(~(subvec args 0 n) (partial ~name ~@(take n args))))
                      (range 1 (count args)))]
    `(defn ~name
       (~args ~@body)
       ~@partials)))&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;clojure-autocurry.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;A naive &lt;code&gt;add&lt;/code&gt; definition, alongside its usage and macroexpansion:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L5&quot;
     href=&quot;#B2-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L6&quot;
     href=&quot;#B2-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L7&quot;
     href=&quot;#B2-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L8&quot;
     href=&quot;#B2-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L9&quot;
     href=&quot;#B2-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L10&quot;
     href=&quot;#B2-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L11&quot;
     href=&quot;#B2-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L12&quot;
     href=&quot;#B2-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L13&quot;
     href=&quot;#B2-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L14&quot;
     href=&quot;#B2-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L15&quot;
     href=&quot;#B2-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L16&quot;
     href=&quot;#B2-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L17&quot;
     href=&quot;#B2-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L18&quot;
     href=&quot;#B2-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L19&quot;
     href=&quot;#B2-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L20&quot;
     href=&quot;#B2-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L21&quot;
     href=&quot;#B2-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L22&quot;
     href=&quot;#B2-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L23&quot;
     href=&quot;#B2-L23&quot;&gt;23&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L24&quot;
     href=&quot;#B2-L24&quot;&gt;24&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L25&quot;
     href=&quot;#B2-L25&quot;&gt;25&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L26&quot;
     href=&quot;#B2-L26&quot;&gt;26&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L27&quot;
     href=&quot;#B2-L27&quot;&gt;27&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L28&quot;
     href=&quot;#B2-L28&quot;&gt;28&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L29&quot;
     href=&quot;#B2-L29&quot;&gt;29&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L30&quot;
     href=&quot;#B2-L30&quot;&gt;30&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L31&quot;
     href=&quot;#B2-L31&quot;&gt;31&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L32&quot;
     href=&quot;#B2-L32&quot;&gt;32&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L33&quot;
     href=&quot;#B2-L33&quot;&gt;33&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L34&quot;
     href=&quot;#B2-L34&quot;&gt;34&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;user=&amp;gt; (defcurry add
         [a b c d e]
         (+ 1 2 3 4 5))
#&apos;user/add

user=&amp;gt; (add 1)
#object[clojure.core$partial$fn__5857 0x2c708440 &quot;clojure.core$partial$fn__5857@2c708440&quot;]

user=&amp;gt; (add 1 2 3 4)
#object[clojure.core$partial$fn__5863 0xf4c0e4e &quot;clojure.core$partial$fn__5863@f4c0e4e&quot;]

user=&amp;gt; ((add 1) 2 3 4 5)
15

user=&amp;gt; (((add 1) 2 3) 4 5)
15

user=&amp;gt; (use &apos;clojure.pprint)
nil

user=&amp;gt; (pprint
        (macroexpand
         &apos;(defcurry add
            [a b c d e]
            (+ 1 2 3 4 5))))
(def
 add
 (clojure.core/fn
  ([a b c d e] (+ 1 2 3 4 5))
  ([a] (clojure.core/partial add a))
  ([a b] (clojure.core/partial add a b))
  ([a b c] (clojure.core/partial add a b c))
  ([a b c d] (clojure.core/partial add a b c d))))
nil&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;clojure-autocurry.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;This simplistic &lt;code&gt;defcurry&lt;/code&gt; definition doesn’t support optional parameters, multi-arity,
              &lt;code&gt;&amp;&lt;/code&gt; rest arguments, docstrings, etc., but it could certainly evolve to do so.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;I like how &lt;code&gt;defcurry&lt;/code&gt; is so short, and abdicates the responsability of doing the
              multi-arity logic to Clojure’s built-in multi-arity support. Simple and elegant.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Same Clojure as before, now with auto-currying via macros.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;comparison-with-common-lisp&quot;&gt;Comparison with Common Lisp&lt;a class=&quot;anchor&quot;
             href=&quot;#comparison-with-common-lisp&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;My attempt at writing an equivalent for Common Lisp gives me:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L12&quot;
     href=&quot;#B3-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L13&quot;
     href=&quot;#B3-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L14&quot;
     href=&quot;#B3-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L15&quot;
     href=&quot;#B3-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L16&quot;
     href=&quot;#B3-L16&quot;&gt;16&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;(defun partial (fn &amp;amp;rest args)
  (lambda (&amp;amp;rest args2)
    (apply fn (append args args2))))

(defun curry-n (n func)
  (cond ((&amp;lt; n 0) (error &quot;Too many arguments&quot;))
        ((zerop n) (funcall func))
        (t (lambda (&amp;amp;rest rest)
             (curry-n (- n (length rest))
                      (apply #&apos;partial func rest))))))

(defmacro defcurry (name args &amp;amp;body body)
  `(defun ,name (&amp;amp;rest rest)
     (let ((func (lambda ,args ,@body)))
       (curry-n (- ,(length args) (length rest))
                (apply #&apos;partial func rest)))))&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;clojure-autocurry.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Without built-in multi-arity support, we have to do more work, like tracking the number of arguments
              consumed so far. We also have to write &lt;code&gt;#’partial&lt;/code&gt; ourselves. That is, without dependending on
              any library, sticking to ANSI Common Lisp.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The usage is pretty similar:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L3&quot;
     href=&quot;#B4-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L4&quot;
     href=&quot;#B4-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L5&quot;
     href=&quot;#B4-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L6&quot;
     href=&quot;#B4-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L7&quot;
     href=&quot;#B4-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L8&quot;
     href=&quot;#B4-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L9&quot;
     href=&quot;#B4-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L10&quot;
     href=&quot;#B4-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L11&quot;
     href=&quot;#B4-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L12&quot;
     href=&quot;#B4-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L13&quot;
     href=&quot;#B4-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L14&quot;
     href=&quot;#B4-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L15&quot;
     href=&quot;#B4-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L16&quot;
     href=&quot;#B4-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L17&quot;
     href=&quot;#B4-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L18&quot;
     href=&quot;#B4-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L19&quot;
     href=&quot;#B4-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L20&quot;
     href=&quot;#B4-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L21&quot;
     href=&quot;#B4-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L22&quot;
     href=&quot;#B4-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L23&quot;
     href=&quot;#B4-L23&quot;&gt;23&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;* (defcurry add (a b c d e)
    (+ a b c d e))
ADD

* (add 1)
#&amp;lt;FUNCTION (LAMBDA (&amp;amp;REST REST) :IN CURRY-N) {100216419B}&amp;gt;

* (funcall (add 1) 2 3 4)
#&amp;lt;FUNCTION (LAMBDA (&amp;amp;REST REST) :IN CURRY-N) {100216537B}&amp;gt;

* (funcall (add 1) 2 3 4 5)
15

* (funcall (funcall (add 1) 2 3) 4 5)
15

* (macroexpand-1
    &apos;(defcurry add (a b c d e)
       (+ a b c d e)))
(DEFUN ADD (&amp;amp;REST REST)
  (LET ((FUNC (LAMBDA (A B C D E) (+ A B C D E))))
    (CURRY-N (- 5 (LENGTH REST)) (APPLY #&apos;PARTIAL FUNC REST))))
T&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;clojure-autocurry.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;This also require `funcall`s, since we return a &lt;code&gt;lambda&lt;/code&gt; that doesn’t live in the function
              namespace.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Like the Clojure one, it doesn’t support optional parameters, &lt;code&gt;&amp;amp;rest&lt;/code&gt; rest arguments,
              docstrings, etc., but it also could evolve to do so.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Common Lisp argument precedence order parameterization of a generic function
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2021/04/24/cl-generic-precedence.html" title="Common Lisp argument precedence order parameterization of a generic function" />
    <published>
      2021-04-24T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2021/04/24/cl-generic-precedence.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;When CLOS dispatches a method, it picks the most specific method definition to the argument list:&lt;/p&gt;
            &lt;/div&gt;
    </summary>
    <content type="html" xml:base="en/til/2021/04/24/cl-generic-precedence.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;When CLOS dispatches a method, it picks the most specific method definition to the argument list:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L10&quot;
     href=&quot;#B1-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L11&quot;
     href=&quot;#B1-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L12&quot;
     href=&quot;#B1-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L13&quot;
     href=&quot;#B1-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L14&quot;
     href=&quot;#B1-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L15&quot;
     href=&quot;#B1-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L16&quot;
     href=&quot;#B1-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L17&quot;
     href=&quot;#B1-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L18&quot;
     href=&quot;#B1-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L19&quot;
     href=&quot;#B1-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L20&quot;
     href=&quot;#B1-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L21&quot;
     href=&quot;#B1-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L22&quot;
     href=&quot;#B1-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L23&quot;
     href=&quot;#B1-L23&quot;&gt;23&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;* (defgeneric a-fn (x))
#&amp;lt;STANDARD-GENERIC-FUNCTION A-FN (0) {5815ACB9}&amp;gt;

* (defmethod a-fn (x) :default-method)
#&amp;lt;STANDARD-METHOD A-FN (T) {581DB535}&amp;gt;

* (defmethod a-fn ((x number)) :a-number)
#&amp;lt;STANDARD-METHOD A-FN (NUMBER) {58241645}&amp;gt;

* (defmethod a-fn ((x (eql 1))) :number-1)
#&amp;lt;STANDARD-METHOD A-FN ((EQL 1)) {582A7D75}&amp;gt;

* (a-fn nil)
:DEFAULT-METHOD

* (a-fn &quot;1&quot;)
:DEFAULT-METHOD

* (a-fn 0)
:A-NUMBER

* (a-fn 1)
:NUMBER-1&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;cl-generic-precedence.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;CLOS uses a similar logic when choosing the method from parent classes, when multiple ones are
              available:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L5&quot;
     href=&quot;#B2-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L6&quot;
     href=&quot;#B2-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L7&quot;
     href=&quot;#B2-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L8&quot;
     href=&quot;#B2-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L9&quot;
     href=&quot;#B2-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L10&quot;
     href=&quot;#B2-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L11&quot;
     href=&quot;#B2-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L12&quot;
     href=&quot;#B2-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L13&quot;
     href=&quot;#B2-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L14&quot;
     href=&quot;#B2-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L15&quot;
     href=&quot;#B2-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L16&quot;
     href=&quot;#B2-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L17&quot;
     href=&quot;#B2-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L18&quot;
     href=&quot;#B2-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L19&quot;
     href=&quot;#B2-L19&quot;&gt;19&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;* (defclass class-a () ())

#&amp;lt;STANDARD-CLASS CLASS-A {583E0B25}&amp;gt;
* (defclass class-b () ())

#&amp;lt;STANDARD-CLASS CLASS-B {583E7F6D}&amp;gt;
* (defgeneric another-fn (obj))

#&amp;lt;STANDARD-GENERIC-FUNCTION ANOTHER-FN (0) {583DA749}&amp;gt;
* (defmethod another-fn ((obj class-a)) :class-a)
; Compiling LAMBDA (.PV-CELL. .NEXT-METHOD-CALL. OBJ):
; Compiling Top-Level Form:

#&amp;lt;STANDARD-METHOD ANOTHER-FN (CLASS-A) {584523C5}&amp;gt;
* (defmethod another-fn ((obj class-b)) :class-b)
; Compiling LAMBDA (.PV-CELL. .NEXT-METHOD-CALL. OBJ):
; Compiling Top-Level Form:

#&amp;lt;STANDARD-METHOD ANOTHER-FN (CLASS-B) {584B8895}&amp;gt;&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;cl-generic-precedence.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Given the above definitions, when inheriting from &lt;code&gt;class-a&lt;/code&gt; and &lt;code&gt;class-b&lt;/code&gt;, the
              order of inheritance matters:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;* (defclass class-a-coming-first (class-a class-b) ())
#&amp;lt;STANDARD-CLASS CLASS-A-COMING-FIRST {584BE6AD}&amp;gt;

* (defclass class-b-coming-first (class-b class-a) ())
#&amp;lt;STANDARD-CLASS CLASS-B-COMING-FIRST {584C744D}&amp;gt;

* (another-fn (make-instance &apos;class-a-coming-first))
:CLASS-A

* (another-fn (make-instance &apos;class-b-coming-first))
:CLASS-B&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;cl-generic-precedence.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Combining the order of inheritance with generic functions with multiple arguments, CLOS has to make a
              choice of how to pick a method given two competing definitions, and its default strategy is prioritizing
              from left to right:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L3&quot;
     href=&quot;#B4-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L4&quot;
     href=&quot;#B4-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L5&quot;
     href=&quot;#B4-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L6&quot;
     href=&quot;#B4-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L7&quot;
     href=&quot;#B4-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L8&quot;
     href=&quot;#B4-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L9&quot;
     href=&quot;#B4-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L10&quot;
     href=&quot;#B4-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L11&quot;
     href=&quot;#B4-L11&quot;&gt;11&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;* (defgeneric yet-another-fn (obj1 obj2))
#&amp;lt;STANDARD-GENERIC-FUNCTION YET-ANOTHER-FN (0) {584D9EC9}&amp;gt;

* (defmethod yet-another-fn ((obj1 class-a) obj2) :first-arg-specialized)
#&amp;lt;STANDARD-METHOD YET-ANOTHER-FN (CLASS-A T) {5854269D}&amp;gt;

* (defmethod yet-another-fn (obj1 (obj2 class-b)) :second-arg-specialized)
#&amp;lt;STANDARD-METHOD YET-ANOTHER-FN (T CLASS-B) {585AAAAD}&amp;gt;

* (yet-another-fn (make-instance &apos;class-a) (make-instance &apos;class-b))
:FIRST-ARG-SPECIALIZED&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;cl-generic-precedence.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;CLOS has to make a choice between the first and the second definition of &lt;code&gt;yet-another-fn&lt;/code&gt;,
              but its choice is just a heuristic. What if we want the choice to be based on the second argument,
              instead of the first?&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;For that, we use the &lt;code&gt;:argument-precedence-order&lt;/code&gt; option when declaring a generic
              function:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L1&quot;
     href=&quot;#B5-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L2&quot;
     href=&quot;#B5-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L3&quot;
     href=&quot;#B5-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L4&quot;
     href=&quot;#B5-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L5&quot;
     href=&quot;#B5-L5&quot;&gt;5&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;* (defgeneric yet-another-fn (obj1 obj2) (:argument-precedence-order obj2 obj1))
#&amp;lt;STANDARD-GENERIC-FUNCTION YET-ANOTHER-FN (2) {584D9EC9}&amp;gt;

* (yet-another-fn (make-instance &apos;class-a) (make-instance &apos;class-b))
:SECOND-ARG-SPECIALIZED&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;cl-generic-precedence.html.4.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;I liked that the &lt;code&gt;:argument-precedence-order&lt;/code&gt; option exists. We shouldn’t have to change
              the arguments from &lt;code&gt;(obj1 obj2)&lt;/code&gt; to &lt;code&gt;(obj2 obj1)&lt;/code&gt; just to make CLOS pick the method
              that we want. We can configure its default behaviour if desired, and keep the order of arguments however
              it best fits the generic function.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;comparison-with-clojure&quot;&gt;Comparison with Clojure&lt;a class=&quot;anchor&quot;
             href=&quot;#comparison-with-clojure&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Clojure has an equivalent, when using &lt;code&gt;defmulti&lt;/code&gt;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Since when declaring a multi-method with &lt;code&gt;defmulti&lt;/code&gt; we must define the dispatch function,
              Clojure uses it to pick the method definition. Since the dispatch function is required, there is no need
              for a default behaviour, such as left-to-right.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;anchor&quot;
             href=&quot;#conclusion&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Making the argument precedence order configurable for generic functions but not for class definitions
              makes a lot of sense.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;When declaring a class, we can choose the precedence order, and that is about it. But when defining a
              generic function, the order of arguments is more important to the function semantics, and the argument
              precedence being left-to-right is just the default behaviour.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;One shouldn’t change the order of arguments of a generic function for the sake of tailoring it to the
              CLOS priority ranking algorithm, but doing it for a class definition is just fine.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;TIL.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;references&quot;&gt;References&lt;a class=&quot;anchor&quot;
             href=&quot;#references&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;olist arabic&quot;&gt;
              &lt;ol class=&quot;arabic&quot;&gt;
                &lt;li&gt;
                  &lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Object-Oriented_Programming_in_Common_Lisp&quot;&gt;Object-Oriented
                  Programming in Common Lisp: A Programmer’s Guide to CLOS&lt;/a&gt;, by Sonja E. Keene&lt;/p&gt;
                &lt;/li&gt;
              &lt;/ol&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      POSIX sh and shebangs
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2021/01/17/posix-shebang.html" title="POSIX sh and shebangs" />
    <published>
      2021-01-17T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2021/01/17/posix-shebang.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As I &lt;a href=&quot;../../../2020/12/15/shellcheck-repo.html&quot;&gt;keep moving&lt;/a&gt; &lt;a href=
          &quot;../12/curl-awk-emails.html&quot;&gt;towards POSIX&lt;/a&gt;, I’m on the process of migrating all my Bash scripts to POSIX
          sh.&lt;/p&gt;
        &lt;/div&gt;
    </summary>
    <content type="html" xml:base="en/til/2021/01/17/posix-shebang.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As I &lt;a href=&quot;../../../2020/12/15/shellcheck-repo.html&quot;&gt;keep moving&lt;/a&gt; &lt;a href=
          &quot;../12/curl-awk-emails.html&quot;&gt;towards POSIX&lt;/a&gt;, I’m on the process of migrating all my Bash scripts to POSIX
          sh.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As I dropped &lt;code&gt;[[&lt;/code&gt;, arrays and other Bashisms, I was left staring at the first line of every
          script, wondering what to do: what is the POSIX sh equivalent of &lt;code&gt;#!/usr/bin/env bash&lt;/code&gt;? I already
          knew that POSIX says nothing about shebangs, and that the portable way to call a POSIX sh script is &lt;code&gt;sh
          script.sh&lt;/code&gt;, but I didn’t know what to do with that first line.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;What I had previously was:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;#!/usr/bin/env bash
set -Eeuo pipefail
cd &quot;$(dirname &quot;${BASH_SOURCE[0]}&quot;)&quot;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;posix-shebang.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Obviously, the &lt;code&gt;$BASH_SOURCE&lt;/code&gt; would be gone, and I would have to adapt some of my scripts to
          not rely on the script location. The &lt;code&gt;-E&lt;/code&gt; and &lt;code&gt;-o pipefail&lt;/code&gt; options were also gone, and
          would be replaced by nothing.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I converted all of them to:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;#!/bin/sh -eu&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;posix-shebang.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I moved the &lt;code&gt;-eu&lt;/code&gt; options to the shebang line itself, striving for conciseness. But as I
          changed callers from &lt;code&gt;./script.sh&lt;/code&gt; to &lt;code&gt;sh script.sh&lt;/code&gt;, things started to fail. Some
          tests that should fail reported errors, but didn’t return 1.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;My first reaction was to revert back to &lt;code&gt;./script.sh&lt;/code&gt;, but the POSIX bug I caught is a strong
          strain, and when I went back to it, I figured that the callers were missing some flags. Specifically,
          &lt;code&gt;sh -eu script.sh&lt;/code&gt;.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Then it clicked: when running with &lt;code&gt;sh script.sh&lt;/code&gt;, the shebang line with the sh options is
          ignored, as it is a comment!&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Which means that the shebang most friendly with POSIX is:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;#!/bin/sh
set -eu&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;posix-shebang.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;olist arabic&quot;&gt;
          &lt;ol class=&quot;arabic&quot;&gt;
            &lt;li&gt;
              &lt;p&gt;when running via &lt;code&gt;./script.sh&lt;/code&gt;, if the system has an executable at &lt;code&gt;/bin/sh&lt;/code&gt;, it
              will be used to run the script;&lt;/p&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;when running via &lt;code&gt;sh script.sh&lt;/code&gt;, the sh options aren’t ignored as previously.&lt;/p&gt;
            &lt;/li&gt;
          &lt;/ol&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;TIL.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Awk snippet: send email to multiple recipients with cURL
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2021/01/12/curl-awk-emails.html" title="Awk snippet: send email to multiple recipients with cURL" />
    <published>
      2021-01-12T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2021/01/12/curl-awk-emails.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As I experiment with &lt;a href=&quot;https://neomutt.org/&quot;&gt;Neomutt&lt;/a&gt;, I wanted to keep being able to enqueue
          emails for sending later like my previous setup, so that I didn’t rely on having an internet connection.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2021/01/12/curl-awk-emails.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As I experiment with &lt;a href=&quot;https://neomutt.org/&quot;&gt;Neomutt&lt;/a&gt;, I wanted to keep being able to enqueue
          emails for sending later like my previous setup, so that I didn’t rely on having an internet connection.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;My requirements for the &lt;code&gt;sendmail&lt;/code&gt; command were:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;olist arabic&quot;&gt;
          &lt;ol class=&quot;arabic&quot;&gt;
            &lt;li&gt;
              &lt;p&gt;store the email in a file, and send it later;&lt;/p&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;send from different addresses, using different SMTP servers.&lt;/p&gt;
            &lt;/li&gt;
          &lt;/ol&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I couldn’t find an MTA that could accomplish that, but I was able to quickly write a solution.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The first part was the easiest: store the email in a file:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;# ~/.config/mutt/muttrc:
set sendmail=~/bin/enqueue-email.sh

# ~/bin/enqueue-email.sh:
#!/bin/sh -eu

cat - &amp;gt; &quot;$HOME/mbsync/my-queued-emails/$(date -Is)&quot;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;curl-awk-emails.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Now that I had the email file store locally, I needed a program to send the email from the file, so that I
          could create a cronjob like:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;for f in ~/mbsync/my-queued-emails/*; do
  ~/bin/dispatch-email.sh &quot;$f&quot; &amp;amp;&amp; rm &quot;$f&quot;
done&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;curl-awk-emails.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The &lt;code&gt;dispatch-email.sh&lt;/code&gt; would have to look at the &lt;code&gt;From:&lt;/code&gt; header and decide which
          SMTP server to use. As I &lt;a href=&quot;https://blog.edmdesigner.com/send-email-from-linux-command-line/&quot;&gt;found
          out&lt;/a&gt; that &lt;a href=&quot;https://curl.se/&quot;&gt;curl&lt;/a&gt; supports SMTP and is able to send emails, this is what I
          ended up with:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L12&quot;
     href=&quot;#B3-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L13&quot;
     href=&quot;#B3-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L14&quot;
     href=&quot;#B3-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L15&quot;
     href=&quot;#B3-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L16&quot;
     href=&quot;#B3-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L17&quot;
     href=&quot;#B3-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L18&quot;
     href=&quot;#B3-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L19&quot;
     href=&quot;#B3-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L20&quot;
     href=&quot;#B3-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L21&quot;
     href=&quot;#B3-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L22&quot;
     href=&quot;#B3-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L23&quot;
     href=&quot;#B3-L23&quot;&gt;23&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L24&quot;
     href=&quot;#B3-L24&quot;&gt;24&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L25&quot;
     href=&quot;#B3-L25&quot;&gt;25&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L26&quot;
     href=&quot;#B3-L26&quot;&gt;26&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L27&quot;
     href=&quot;#B3-L27&quot;&gt;27&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L28&quot;
     href=&quot;#B3-L28&quot;&gt;28&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L29&quot;
     href=&quot;#B3-L29&quot;&gt;29&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L30&quot;
     href=&quot;#B3-L30&quot;&gt;30&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L31&quot;
     href=&quot;#B3-L31&quot;&gt;31&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L32&quot;
     href=&quot;#B3-L32&quot;&gt;32&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L33&quot;
     href=&quot;#B3-L33&quot;&gt;33&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L34&quot;
     href=&quot;#B3-L34&quot;&gt;34&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L35&quot;
     href=&quot;#B3-L35&quot;&gt;35&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;#!/bin/sh -eu

F=&quot;$1&quot;

rcpt=&quot;$(awk &apos;
  match($0, /^(To|Cc|Bcc): (.*)$/, m) {
    split(m[2], tos, &quot;,&quot;)
    for (i in tos) {
      print &quot;--mail-rcpt &quot; tos[i]
    }
  }
&apos;  &quot;$F&quot;)&quot;

if grep -qE &apos;^From: .*&amp;lt;addr@server1\.org&amp;gt;$&apos; &quot;$F&quot;; then
  curl                                                      \
    -s                                                      \
    --url smtp://smtp.server1.org:587                       \
    --ssl-reqd                                              \
    --mail-from addr@server1.org                            \
    $rcpt                                                   \
    --user &apos;addr@server1.org:my-long-and-secure-passphrase&apos; \
    --upload-file &quot;$F&quot;
elif grep -qE &apos;^From: .*&amp;lt;addr@server2\.org&amp;gt;$&apos; &quot;$F&quot;; then
  curl                                                      \
    -s                                                      \
    --url smtp://smtp.server2.org:587                       \
    --ssl-reqd                                              \
    --mail-from addr@server2.org                            \
    $rcpt                                                   \
    --user &apos;addr@server2.org:my-long-and-secure-passphrase&apos; \
    --upload-file &quot;$F&quot;
else
  echo &apos;Bad &quot;From: &quot; address&apos;
  exit 1
fi&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;curl-awk-emails.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Most of curl flags used are self-explanatory, except for &lt;code&gt;$rcpt&lt;/code&gt;.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;curl connects to the SMTP server, but doesn’t set the recipient address by looking at the message. My
          solution was to generate the curl flags, store them in &lt;code&gt;$rcpt&lt;/code&gt; and use it unquoted to leverage
          shell word splitting.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;To me, the most interesting part was building the &lt;code&gt;$rcpt&lt;/code&gt; flags. My first instinct was to try
          grep, but it couldn’t print only matches in a regex. As I started to turn towards sed, I envisioned needing
          something else to loop over the sed output, and I then moved to Awk.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;In the short Awk snippet, 3 things were new to me: the &lt;code&gt;match(…​)&lt;/code&gt;, &lt;code&gt;split(…​)&lt;/code&gt; and
          &lt;code&gt;for () {}&lt;/code&gt;. The only other function I have ever used was &lt;code&gt;gsub(…​)&lt;/code&gt;, but these new
          ones felt similar enough that I could almost guess their behaviour and arguments. &lt;code&gt;match(…​)&lt;/code&gt;
          stores the matches of a regex on the given array positionally, and &lt;code&gt;split(…​)&lt;/code&gt; stores the chunks
          in the given array.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I even did it incrementally:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L3&quot;
     href=&quot;#B4-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L4&quot;
     href=&quot;#B4-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L5&quot;
     href=&quot;#B4-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L6&quot;
     href=&quot;#B4-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L7&quot;
     href=&quot;#B4-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L8&quot;
     href=&quot;#B4-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L9&quot;
     href=&quot;#B4-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L10&quot;
     href=&quot;#B4-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L11&quot;
     href=&quot;#B4-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L12&quot;
     href=&quot;#B4-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L13&quot;
     href=&quot;#B4-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L14&quot;
     href=&quot;#B4-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L15&quot;
     href=&quot;#B4-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L16&quot;
     href=&quot;#B4-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L17&quot;
     href=&quot;#B4-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L18&quot;
     href=&quot;#B4-L18&quot;&gt;18&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;$ H=&apos;To: to@example.com, to2@example.com\nCc: cc@example.com, cc2@example.com\nBcc: bcc@example.com,bcc2@example.com\n&apos;
$ printf &quot;$H&quot; | awk &apos;/^To: .*$/ { print $0 }&apos;
To: to@example.com, to2@example.com
$ printf &quot;$H&quot; | awk &apos;match($0, /^To: (.*)$/, m) { print m }&apos;
awk: ligne de commande:1: (FILENAME=- FNR=1) fatal : tentative d&apos;utilisation du tableau « m » dans un contexte scalaire
$ printf &quot;$H&quot; | awk &apos;match($0, /^To: (.*)$/, m) { print m[0] }&apos;
To: to@example.com, to2@example.com
$ printf &quot;$H&quot; | awk &apos;match($0, /^To: (.*)$/, m) { print m[1] }&apos;
to@example.com, to2@example.com
$ printf &quot;$H&quot; | awk &apos;match($0, /^To: (.*)$/, m) { split(m[1], tos, &quot; &quot;); print tos }&apos;
awk: ligne de commande:1: (FILENAME=- FNR=1) fatal : tentative d&apos;utilisation du tableau « tos » dans un contexte scalaire
$ printf &quot;$H&quot; | awk &apos;match($0, /^To: (.*)$/, m) { split(m[1], tos, &quot; &quot;); print tos[0] }&apos;

$ printf &quot;$H&quot; | awk &apos;match($0, /^To: (.*)$/, m) { split(m[1], tos, &quot; &quot;); print tos[1] }&apos;
to@example.com,
$ printf &quot;$H&quot; | awk &apos;match($0, /^To: (.*)$/, m) { split(m[1], tos, &quot; &quot;); print tos[2] }&apos;
to2@example.com
$ printf &quot;$H&quot; | awk &apos;match($0, /^To: (.*)$/, m) { split(m[1], tos, &quot; &quot;); print tos[3] }&apos;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;curl-awk-emails.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;(This isn’t the verbatim interactive session, but a cleaned version to make it more readable.)&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;At this point, I realized I needed a for loop over the &lt;code&gt;tos&lt;/code&gt; array, and I moved the Awk snippet
          into the &lt;code&gt;~/bin/dispatch-email.sh&lt;/code&gt;. I liked the final thing:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L1&quot;
     href=&quot;#B5-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L2&quot;
     href=&quot;#B5-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L3&quot;
     href=&quot;#B5-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L4&quot;
     href=&quot;#B5-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L5&quot;
     href=&quot;#B5-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L6&quot;
     href=&quot;#B5-L6&quot;&gt;6&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;match($0, /^(To|Cc|Bcc): (.*)$/, m) {
  split(m[2], tos, &quot;,&quot;)
  for (i in tos) {
    print &quot;--mail-rcpt &quot; tos[i]
  }
}&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;curl-awk-emails.html.4.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As I learn more about Awk, I feel that it is too undervalued, as many people turn to Perl or other
          programming languages when Awk suffices. The advantage is pretty clear: writing programs that run on any
          POSIX system, without extra dependencies required.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Coding to the standards is underrated.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      SVG favicon
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/12/29/svg.html" title="SVG favicon" />
    <published>
      2020-12-29T00:00:00+00:00
    </published>
    <updated>
      2021-01-12T00:00:00+00:00
    </updated>
    <id>
      https://euandre.org/en/til/2020/12/29/svg.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I’ve wanted to change this website’s favicon from a plain &lt;code&gt;.ico&lt;/code&gt; file to a proper SVG. The
          problem I was trying to solve was to reuse the same image on other places, such as avatars.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/12/29/svg.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I’ve wanted to change this website’s favicon from a plain &lt;code&gt;.ico&lt;/code&gt; file to a proper SVG. The
          problem I was trying to solve was to reuse the same image on other places, such as avatars.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Generating a PNG from the existing 16x16 icon was possible but bad: the final image was blurry. Converting
          the &lt;code&gt;.ico&lt;/code&gt; to an SVG was possible, but sub-optimal: tools try to guess some vector paths, and the
          final SVG didn’t match the original.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Instead I used a tool to draw the &quot;vector pixels&quot; as black squares, and after getting the final result I
          manually cleaned-up the generated XML:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L10&quot;
     href=&quot;#B1-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L11&quot;
     href=&quot;#B1-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L12&quot;
     href=&quot;#B1-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L13&quot;
     href=&quot;#B1-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L14&quot;
     href=&quot;#B1-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L15&quot;
     href=&quot;#B1-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L16&quot;
     href=&quot;#B1-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L17&quot;
     href=&quot;#B1-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L18&quot;
     href=&quot;#B1-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L19&quot;
     href=&quot;#B1-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L20&quot;
     href=&quot;#B1-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L21&quot;
     href=&quot;#B1-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L22&quot;
     href=&quot;#B1-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L23&quot;
     href=&quot;#B1-L23&quot;&gt;23&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L24&quot;
     href=&quot;#B1-L24&quot;&gt;24&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L25&quot;
     href=&quot;#B1-L25&quot;&gt;25&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L26&quot;
     href=&quot;#B1-L26&quot;&gt;26&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L27&quot;
     href=&quot;#B1-L27&quot;&gt;27&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L28&quot;
     href=&quot;#B1-L28&quot;&gt;28&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L29&quot;
     href=&quot;#B1-L29&quot;&gt;29&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L30&quot;
     href=&quot;#B1-L30&quot;&gt;30&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L31&quot;
     href=&quot;#B1-L31&quot;&gt;31&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L32&quot;
     href=&quot;#B1-L32&quot;&gt;32&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L33&quot;
     href=&quot;#B1-L33&quot;&gt;33&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L34&quot;
     href=&quot;#B1-L34&quot;&gt;34&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L35&quot;
     href=&quot;#B1-L35&quot;&gt;35&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L36&quot;
     href=&quot;#B1-L36&quot;&gt;36&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L37&quot;
     href=&quot;#B1-L37&quot;&gt;37&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L38&quot;
     href=&quot;#B1-L38&quot;&gt;38&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L39&quot;
     href=&quot;#B1-L39&quot;&gt;39&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L40&quot;
     href=&quot;#B1-L40&quot;&gt;40&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L41&quot;
     href=&quot;#B1-L41&quot;&gt;41&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L42&quot;
     href=&quot;#B1-L42&quot;&gt;42&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L43&quot;
     href=&quot;#B1-L43&quot;&gt;43&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L44&quot;
     href=&quot;#B1-L44&quot;&gt;44&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L45&quot;
     href=&quot;#B1-L45&quot;&gt;45&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L46&quot;
     href=&quot;#B1-L46&quot;&gt;46&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L47&quot;
     href=&quot;#B1-L47&quot;&gt;47&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L48&quot;
     href=&quot;#B1-L48&quot;&gt;48&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L49&quot;
     href=&quot;#B1-L49&quot;&gt;49&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L50&quot;
     href=&quot;#B1-L50&quot;&gt;50&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L51&quot;
     href=&quot;#B1-L51&quot;&gt;51&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L52&quot;
     href=&quot;#B1-L52&quot;&gt;52&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L53&quot;
     href=&quot;#B1-L53&quot;&gt;53&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L54&quot;
     href=&quot;#B1-L54&quot;&gt;54&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L55&quot;
     href=&quot;#B1-L55&quot;&gt;55&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L56&quot;
     href=&quot;#B1-L56&quot;&gt;56&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L57&quot;
     href=&quot;#B1-L57&quot;&gt;57&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L58&quot;
     href=&quot;#B1-L58&quot;&gt;58&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L59&quot;
     href=&quot;#B1-L59&quot;&gt;59&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L60&quot;
     href=&quot;#B1-L60&quot;&gt;60&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L61&quot;
     href=&quot;#B1-L61&quot;&gt;61&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L62&quot;
     href=&quot;#B1-L62&quot;&gt;62&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&amp;gt;
&amp;lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot; height=&quot;16&quot;&amp;gt;
  &amp;lt;path d=&quot;M 0  8  L 1  8  L 1  9  L 0  9  L 0  8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 0  13 L 1  13 L 1  14 L 0  14 L 0  13 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 1  8  L 2  8  L 2  9  L 1  9  L 1  8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 1  13 L 2  13 L 2  14 L 1  14 L 1  13 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 2  8  L 3  8  L 3  9  L 2  9  L 2  8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 2  13 L 3  13 L 3  14 L 2  14 L 2  13 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 3  8  L 4  8  L 4  9  L 3  9  L 3  8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 3  13 L 4  13 L 4  14 L 3  14 L 3  13 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 4  7  L 5  7  L 5  8  L 4  8  L 4  7  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 4  8  L 5  8  L 5  9  L 4  9  L 4  8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 4  13 L 5  13 L 5  14 L 4  14 L 4  13 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 5  6  L 6  6  L 6  7  L 5  7  L 5  6  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 5  7  L 6  7  L 6  8  L 5  8  L 5  7  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 5  13 L 6  13 L 6  14 L 5  14 L 5  13 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 6  5  L 7  5  L 7  6  L 6  6  L 6  5  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 6  6  L 7  6  L 7  7  L 6  7  L 6  6  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 6  14 L 7  14 L 7  15 L 6  15 L 6  14 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 7  1  L 8  1  L 8  2  L 7  2  L 7  1  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 7  14 L 8  14 L 8  15 L 7  15 L 7  14 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 7  15 L 8  15 L 8  16 L 7  16 L 7  15 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 7  2  L 8  2  L 8  3  L 7  3  L 7  2  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 7  3  L 8  3  L 8  4  L 7  4  L 7  3  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 7  4  L 8  4  L 8  5  L 7  5  L 7  4  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 7  5  L 8  5  L 8  6  L 7  6  L 7  5  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 8  1  L 9  1  L 9  2  L 8  2  L 8  1  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 8  15 L 9  15 L 9  16 L 8  16 L 8  15 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 9  1  L 10 1  L 10 2  L 9  2  L 9  1  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 9  2  L 10 2  L 10 3  L 9  3  L 9  2  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 9  6  L 10 6  L 10 7  L 9  7  L 9  6  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 9  15 L 10 15 L 10 16 L 9  16 L 9  15 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 10 2  L 11 2  L 11 3  L 10 3  L 10 2  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 10 3  L 11 3  L 11 4  L 10 4  L 10 3  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 10 4  L 11 4  L 11 5  L 10 5  L 10 4  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 10 5  L 11 5  L 11 6  L 10 6  L 10 5  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 10 6  L 11 6  L 11 7  L 10 7  L 10 6  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 11 6  L 12 6  L 12 7  L 11 7  L 11 6  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 11 8  L 12 8  L 12 9  L 11 9  L 11 8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 10 15 L 11 15 L 11 16 L 10 16 L 10 15 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 11 10 L 12 10 L 12 11 L 11 11 L 11 10 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 11 12 L 12 12 L 12 13 L 11 13 L 11 12 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 11 14 L 12 14 L 12 15 L 11 15 L 11 14 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 11 15 L 12 15 L 12 16 L 11 16 L 11 15 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 12 6  L 13 6  L 13 7  L 12 7  L 12 6  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 12 8  L 13 8  L 13 9  L 12 9  L 12 8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 12 10 L 13 10 L 13 11 L 12 11 L 12 10 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 12 12 L 13 12 L 13 13 L 12 13 L 12 12 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 12 14 L 13 14 L 13 15 L 12 15 L 12 14 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 13 6  L 14 6  L 14 7  L 13 7  L 13 6  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 13 8  L 14 8  L 14 9  L 13 9  L 13 8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 13 10 L 14 10 L 14 11 L 13 11 L 13 10 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 13 12 L 14 12 L 14 13 L 13 13 L 13 12 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 13 13 L 14 13 L 14 14 L 13 14 L 13 13 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 13 14 L 14 14 L 14 15 L 13 15 L 13 14 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 14 7  L 15 7  L 15 8  L 14 8  L 14 7  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 14 8  L 15 8  L 15 9  L 14 9  L 14 8  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 14 9  L 15 9  L 15 10 L 14 10 L 14 9  Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 14 10 L 15 10 L 15 11 L 14 11 L 14 10 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 14 11 L 15 11 L 15 12 L 14 12 L 14 11 Z&quot; /&amp;gt;
  &amp;lt;path d=&quot;M 14 12 L 15 12 L 15 13 L 14 13 L 14 12 Z&quot; /&amp;gt;
&amp;lt;/svg&amp;gt;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;svg.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The good thing about this new favicon (at &lt;a href=
          &quot;../../../../../img/favicon.svg&quot;&gt;&lt;code&gt;/static/lord-favicon.svg&lt;/code&gt;&lt;/a&gt;) is that a) it is simple enough
          that I feel comfortable editing it manually and b) it is an SVG, which means I can generate any desired
          size.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;With the new favicon file, I now had to add to the templates’ &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; a
          &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; to this icon:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;&amp;lt;head&amp;gt;
  &amp;lt;meta charset=&quot;UTF-8&quot; /&amp;gt;
  &amp;lt;link rel=&quot;icon&quot; type=&quot;image/svg+xml&quot; href=&quot;/static/favicon.svg&quot;&amp;gt;
  ...&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;svg.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Still missing is a bitmap image for places that can’t handle vector images. I used Jekyll generator to
          create an PNG from the existing SVG:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L12&quot;
     href=&quot;#B3-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L13&quot;
     href=&quot;#B3-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L14&quot;
     href=&quot;#B3-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L15&quot;
     href=&quot;#B3-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L16&quot;
     href=&quot;#B3-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L17&quot;
     href=&quot;#B3-L17&quot;&gt;17&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;module Jekyll
  class FaviconGenerator &amp;lt; Generator
    safe true
    priority :high

    SIZE = 420

    def generate(site)
      svg = &apos;static/favicon.svg&apos;
      png = &apos;static/favicon.png&apos;
      unless File.exist? png then
        puts &quot;Missing &apos;#{png}&apos;, generating...&quot;
        puts `inkscape -o #{png} -w #{SIZE} -h #{SIZE} #{svg}`
      end
    end
  end
end&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;svg.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I had to increase the priority of the generator so that it would run before other places that would use a
          &lt;code&gt;{% link /static/lord-favicon.png %}&lt;/code&gt;, otherwise the file would be considered missing.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Awk snippet: ShellCheck all scripts in a repository
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/12/15/shellcheck-repo.html" title="Awk snippet: ShellCheck all scripts in a repository" />
    <published>
      2020-12-15T00:00:00+00:00
    </published>
    <updated>
      2020-12-16T00:00:00+00:00
    </updated>
    <id>
      https://euandre.org/en/til/2020/12/15/shellcheck-repo.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Inspired by Fred Herbert’s &quot;&lt;a href=&quot;https://ferd.ca/awk-in-20-minutes.html&quot;&gt;Awk in 20 Minutes&lt;/a&gt;&quot;,
              here’s a problem I just solved with a line of Awk: run ShellCheck in all scripts of a repository.&lt;/p&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/12/15/shellcheck-repo.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Inspired by Fred Herbert’s &quot;&lt;a href=&quot;https://ferd.ca/awk-in-20-minutes.html&quot;&gt;Awk in 20 Minutes&lt;/a&gt;&quot;,
              here’s a problem I just solved with a line of Awk: run ShellCheck in all scripts of a repository.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;In my repositories I usually have Bash and POSIX scripts, which I want to keep tidy with &lt;a href=
              &quot;https://www.shellcheck.net/&quot;&gt;ShellCheck&lt;/a&gt;. Here’s the first version of
              &lt;code&gt;assert-shellcheck.sh&lt;/code&gt;:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;#!/bin/sh -eux

find . -type f -name &apos;*.sh&apos; -print0 | xargs -0 shellcheck&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;shellcheck-repo.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;This is the type of script that I copy around to all repositories, and I want it to be capable of
              working on any repository, without requiring a list of files to run ShellCheck on.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;This first version worked fine, as all my scripts had the ‘.sh’ ending. But I recently added some
              scripts without any extension, so &lt;code&gt;assert-shellcheck.sh&lt;/code&gt; called for a second version. The
              first attempt was to try grepping the shebang line:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;$ grep &apos;^#!/&apos; assert-shellcheck.sh
#!/usr/sh&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;shellcheck-repo.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Good, we have a grep pattern on the first try. Let’s try to find all the matching files:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L12&quot;
     href=&quot;#B3-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L13&quot;
     href=&quot;#B3-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L14&quot;
     href=&quot;#B3-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L15&quot;
     href=&quot;#B3-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L16&quot;
     href=&quot;#B3-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L17&quot;
     href=&quot;#B3-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L18&quot;
     href=&quot;#B3-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L19&quot;
     href=&quot;#B3-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L20&quot;
     href=&quot;#B3-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L21&quot;
     href=&quot;#B3-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L22&quot;
     href=&quot;#B3-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L23&quot;
     href=&quot;#B3-L23&quot;&gt;23&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L24&quot;
     href=&quot;#B3-L24&quot;&gt;24&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L25&quot;
     href=&quot;#B3-L25&quot;&gt;25&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L26&quot;
     href=&quot;#B3-L26&quot;&gt;26&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L27&quot;
     href=&quot;#B3-L27&quot;&gt;27&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L28&quot;
     href=&quot;#B3-L28&quot;&gt;28&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L29&quot;
     href=&quot;#B3-L29&quot;&gt;29&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;$ find . -type f | xargs grep -l &apos;^#!/&apos;
./TODOs.org
./.git/hooks/pre-commit.sample
./.git/hooks/pre-push.sample
./.git/hooks/pre-merge-commit.sample
./.git/hooks/fsmonitor-watchman.sample
./.git/hooks/pre-applypatch.sample
./.git/hooks/pre-push
./.git/hooks/prepare-commit-msg.sample
./.git/hooks/commit-msg.sample
./.git/hooks/post-update.sample
./.git/hooks/pre-receive.sample
./.git/hooks/applypatch-msg.sample
./.git/hooks/pre-rebase.sample
./.git/hooks/update.sample
./build-aux/with-guile-env.in
./build-aux/test-driver
./build-aux/missing
./build-aux/install-sh
./build-aux/install-sh~
./bootstrap
./scripts/assert-todos.sh
./scripts/songbooks
./scripts/compile-readme.sh
./scripts/ci-build.sh
./scripts/generate-tasks-and-bugs.sh
./scripts/songbooks.in
./scripts/with-container.sh
./scripts/assert-shellcheck.sh&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;shellcheck-repo.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;This approach has a problem, though: it includes files ignored by Git, such as
              &lt;code&gt;builld-aux/install-sh~&lt;/code&gt;, and even goes into the &lt;code&gt;.git/&lt;/code&gt; directory and finds sample
              hooks in &lt;code&gt;.git/hooks/*&lt;/code&gt;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;To list the files that Git is tracking we’ll try &lt;code&gt;git ls-files&lt;/code&gt;:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L3&quot;
     href=&quot;#B4-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L4&quot;
     href=&quot;#B4-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L5&quot;
     href=&quot;#B4-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L6&quot;
     href=&quot;#B4-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L7&quot;
     href=&quot;#B4-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L8&quot;
     href=&quot;#B4-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L9&quot;
     href=&quot;#B4-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L10&quot;
     href=&quot;#B4-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L11&quot;
     href=&quot;#B4-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L12&quot;
     href=&quot;#B4-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L13&quot;
     href=&quot;#B4-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L14&quot;
     href=&quot;#B4-L14&quot;&gt;14&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;$ git ls-files | xargs grep -l &apos;^#!/&apos;
TODOs.org
bootstrap
build-aux/with-guile-env.in
old/scripts/assert-docs-spelling.sh
old/scripts/build-site.sh
old/scripts/builder.bats.sh
scripts/assert-shellcheck.sh
scripts/assert-todos.sh
scripts/ci-build.sh
scripts/compile-readme.sh
scripts/generate-tasks-and-bugs.sh
scripts/songbooks.in
scripts/with-container.sh&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;shellcheck-repo.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;It looks to be almost there, but the &lt;code&gt;TODOs.org&lt;/code&gt; entry shows a flaw in it: grep is looking
              for a &lt;code&gt;&apos;^#!/&apos;&lt;/code&gt; pattern on any part of the file. In my case, &lt;code&gt;TODOs.org&lt;/code&gt; had a
              snippet in the middle of the file where a line started with &lt;code&gt;#!/bin/sh&lt;/code&gt;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;So what we actually want is to match the &lt;strong&gt;first&lt;/strong&gt; line against the pattern. We could
              loop through each file, get the first line with &lt;code&gt;head -n 1&lt;/code&gt; and grep against that, but this is
              starting to look messy. I bet there is another way of doing it concisely…​&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Let’s try Awk. I need a way to select the line numbers to replace &lt;code&gt;head -n 1&lt;/code&gt;, and to stop
              processing the file if the pattern matches. A quick search points me to using &lt;code&gt;FNR&lt;/code&gt; for the
              former, and &lt;code&gt;{ nextline }&lt;/code&gt; for the latter. Let’s try it:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L1&quot;
     href=&quot;#B5-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L2&quot;
     href=&quot;#B5-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L3&quot;
     href=&quot;#B5-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L4&quot;
     href=&quot;#B5-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L5&quot;
     href=&quot;#B5-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L6&quot;
     href=&quot;#B5-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L7&quot;
     href=&quot;#B5-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L8&quot;
     href=&quot;#B5-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L9&quot;
     href=&quot;#B5-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L10&quot;
     href=&quot;#B5-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L11&quot;
     href=&quot;#B5-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L12&quot;
     href=&quot;#B5-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L13&quot;
     href=&quot;#B5-L13&quot;&gt;13&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;$ git ls-files | xargs awk &apos;FNR&amp;gt;1 { nextfile } /^#!\// { print FILENAME; nextfile }&apos;
bootstrap
build-aux/with-guile-env.in
old/scripts/assert-docs-spelling.sh
old/scripts/build-site.sh
old/scripts/builder.bats.sh
scripts/assert-shellcheck.sh
scripts/assert-todos.sh
scripts/ci-build.sh
scripts/compile-readme.sh
scripts/generate-tasks-and-bugs.sh
scripts/songbooks.in
scripts/with-container.sh&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;shellcheck-repo.html.4.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Great! Only &lt;code&gt;TODOs.org&lt;/code&gt; is missing, but the script is much better: instead of matching
              against any part of the file that may have a shebang-like line, we only look for the first. Let’s put it
              back into the &lt;code&gt;assert-shellcheck.sh&lt;/code&gt; file and use &lt;code&gt;NULL&lt;/code&gt; for separators to
              accommodate files with spaces in the name:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L1&quot;
     href=&quot;#B6-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L2&quot;
     href=&quot;#B6-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L3&quot;
     href=&quot;#B6-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L4&quot;
     href=&quot;#B6-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L5&quot;
     href=&quot;#B6-L5&quot;&gt;5&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;#!/usr/sh -eux

git ls-files -z | \
  xargs -0 awk &apos;FNR&amp;gt;1 { nextfile } /^#!\// { print FILENAME; nextfile }&apos; | \
  xargs shellcheck&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;shellcheck-repo.html.5.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;This is where I’ve stopped, but I imagine a likely improvement: match against only
              &lt;code&gt;#!/bin/sh&lt;/code&gt; and &lt;code&gt;#!/usr/bin/env bash&lt;/code&gt; shebangs (the ones I use most), to avoid
              running ShellCheck on Perl files, or other shebangs.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Also when reviewing the text of this article, I found that &lt;code&gt;{ nextfile }&lt;/code&gt; is a GNU Awk
              extension. It would be an improvement if &lt;code&gt;assert-shellcheck.sh&lt;/code&gt; relied on the POSIX subset of
              Awk for working correctly.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;update&quot;&gt;&lt;em&gt;Update&lt;/em&gt;&lt;a class=&quot;anchor&quot;
             href=&quot;#update&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;After publishing, I could remove &lt;code&gt;{ nextfile }&lt;/code&gt; and even make the script simpler:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L1&quot;
     href=&quot;#B7-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L2&quot;
     href=&quot;#B7-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L3&quot;
     href=&quot;#B7-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L4&quot;
     href=&quot;#B7-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L5&quot;
     href=&quot;#B7-L5&quot;&gt;5&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;#!/usr/sh -eux

git ls-files -z | \
  xargs -0 awk &apos;FNR==1 &amp;amp;&amp; /^#!\// { print FILENAME }&apos; | \
  xargs shellcheck&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;shellcheck-repo.html.6.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Now both the shell and Awk usage are POSIX compatible.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Storing CI data on Git notes
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/11/30/git-notes-ci.html" title="Storing CI data on Git notes" />
    <published>
      2020-11-30T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/11/30/git-notes-ci.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Extending the bare bones CI server I’ve &lt;a href=&quot;../12/diy-nix-bash-ci.html&quot;&gt;talked about before&lt;/a&gt;,
          divoplade on Freenode suggested storing CI artifacts on &lt;a href=&quot;https://git-scm.com/docs/git-notes&quot;&gt;Git
          notes&lt;/a&gt;, such as tarballs, binaries, logs, &lt;em&gt;etc&lt;/em&gt;.&lt;/p&gt;
        &lt;/div&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/11/30/git-notes-ci.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Extending the bare bones CI server I’ve &lt;a href=&quot;../12/diy-nix-bash-ci.html&quot;&gt;talked about before&lt;/a&gt;,
          divoplade on Freenode suggested storing CI artifacts on &lt;a href=&quot;https://git-scm.com/docs/git-notes&quot;&gt;Git
          notes&lt;/a&gt;, such as tarballs, binaries, logs, &lt;em&gt;etc&lt;/em&gt;.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I’ve written a small script that will put log files and CI job data on Git notes, and make it visible on
          the porcelain log. It is a simple extension of the previous article:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L10&quot;
     href=&quot;#B1-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L11&quot;
     href=&quot;#B1-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L12&quot;
     href=&quot;#B1-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L13&quot;
     href=&quot;#B1-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L14&quot;
     href=&quot;#B1-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L15&quot;
     href=&quot;#B1-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L16&quot;
     href=&quot;#B1-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L17&quot;
     href=&quot;#B1-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L18&quot;
     href=&quot;#B1-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L19&quot;
     href=&quot;#B1-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L20&quot;
     href=&quot;#B1-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L21&quot;
     href=&quot;#B1-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L22&quot;
     href=&quot;#B1-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L23&quot;
     href=&quot;#B1-L23&quot;&gt;23&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L24&quot;
     href=&quot;#B1-L24&quot;&gt;24&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L25&quot;
     href=&quot;#B1-L25&quot;&gt;25&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L26&quot;
     href=&quot;#B1-L26&quot;&gt;26&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L27&quot;
     href=&quot;#B1-L27&quot;&gt;27&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L28&quot;
     href=&quot;#B1-L28&quot;&gt;28&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L29&quot;
     href=&quot;#B1-L29&quot;&gt;29&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L30&quot;
     href=&quot;#B1-L30&quot;&gt;30&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L31&quot;
     href=&quot;#B1-L31&quot;&gt;31&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L32&quot;
     href=&quot;#B1-L32&quot;&gt;32&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L33&quot;
     href=&quot;#B1-L33&quot;&gt;33&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L34&quot;
     href=&quot;#B1-L34&quot;&gt;34&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L35&quot;
     href=&quot;#B1-L35&quot;&gt;35&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L36&quot;
     href=&quot;#B1-L36&quot;&gt;36&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L37&quot;
     href=&quot;#B1-L37&quot;&gt;37&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L38&quot;
     href=&quot;#B1-L38&quot;&gt;38&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L39&quot;
     href=&quot;#B1-L39&quot;&gt;39&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L40&quot;
     href=&quot;#B1-L40&quot;&gt;40&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;#!/usr/bin/env bash
set -Eeuo pipefail
set -x

PREFIX=&apos;/srv/ci/vps&apos;
mkdir -p &quot;$PREFIX&quot;
read -r _ SHA _ # oldrev newrev refname
FILENAME=&quot;$(date -Is)-$SHA.log&quot;
LOGFILE=&quot;$PREFIX/$FILENAME&quot;
exec &amp;amp;&amp;gt; &amp;gt;(tee -a &quot;$LOGFILE&quot;)

echo &quot;Starting CI job at: $(date -Is)&quot;

finish() {
  STATUS=&quot;$?&quot;
  printf &quot;\n\n&amp;gt;&amp;gt;&amp;gt; exit status was %s\n&quot; &quot;$STATUS&quot;
  echo &quot;Finishing CI job at: $(date -Is)&quot;
  popd
  NOTE=$(cat &amp;lt;&amp;lt;EOF
See CI logs with:
  git notes --ref=refs/notes/ci-logs show $SHA
  git notes --ref=refs/notes/ci-data show $SHA
EOF
)
  git notes --ref=refs/notes/ci-data add -f -m &quot;$STATUS $FILENAME&quot;
  git notes --ref=refs/notes/ci-logs add -f -F &quot;$LOGFILE&quot;
  git notes add -f -m &quot;$NOTE&quot;
  printf &quot;\n\n&amp;gt;&amp;gt;&amp;gt; CI logs added as Git note.&quot;
}
trap finish EXIT

unset GIT_DIR
CLONE=&quot;$(mktemp -d)&quot;
git clone . &quot;$CLONE&quot;
pushd &quot;$CLONE&quot;
git config --global user.email git@euandre.org
git config --global user.name &apos;EuAndreh CI&apos;

./container make check site
./container make publish&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;git-notes-ci.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The important part is in the &lt;code&gt;finish()&lt;/code&gt; function: - #25 stores the exit status and the
          generated filename separated by spaces; - #26 adds the log file in a note using the
          &lt;code&gt;refs/notes/ci-logs&lt;/code&gt; ref; - #27 it adds a note to the commit saying how to see the logs.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;A commit now has an attached note, and shows it whenever you look at it:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L5&quot;
     href=&quot;#B2-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L6&quot;
     href=&quot;#B2-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L7&quot;
     href=&quot;#B2-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L8&quot;
     href=&quot;#B2-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L9&quot;
     href=&quot;#B2-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L10&quot;
     href=&quot;#B2-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L11&quot;
     href=&quot;#B2-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L12&quot;
     href=&quot;#B2-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L13&quot;
     href=&quot;#B2-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L14&quot;
     href=&quot;#B2-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L15&quot;
     href=&quot;#B2-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L16&quot;
     href=&quot;#B2-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L17&quot;
     href=&quot;#B2-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L18&quot;
     href=&quot;#B2-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L19&quot;
     href=&quot;#B2-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L20&quot;
     href=&quot;#B2-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L21&quot;
     href=&quot;#B2-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L22&quot;
     href=&quot;#B2-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L23&quot;
     href=&quot;#B2-L23&quot;&gt;23&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L24&quot;
     href=&quot;#B2-L24&quot;&gt;24&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L25&quot;
     href=&quot;#B2-L25&quot;&gt;25&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L26&quot;
     href=&quot;#B2-L26&quot;&gt;26&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L27&quot;
     href=&quot;#B2-L27&quot;&gt;27&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;$ git show 87c57133abd8be5d7cc46afbf107f59b26066575
commit 87c57133abd8be5d7cc46afbf107f59b26066575
Author: EuAndreh &amp;lt;eu@euandre.org&amp;gt;
Date:   Wed Feb 24 21:58:28 2021 -0300

    vps/machines.scm: Change path to cronjob files

Notes:
    See CI logs with:
      git notes --ref=refs/notes/ci-logs show 87c57133abd8be5d7cc46afbf107f59b26066575
      git notes --ref=refs/notes/ci-data show 87c57133abd8be5d7cc46afbf107f59b26066575

diff --git a/servers/vps/machines.scm b/servers/vps/machines.scm
index d1830ca..a4ccde7 100644
--- a/servers/vps/machines.scm
+++ b/servers/vps/machines.scm
@@ -262,8 +262,8 @@ pki &quot; mail-domain &quot; key  \&quot;&quot; (tls-priv-for mail-domain) &quot;\&quot;&quot;))
             (service mcron-service-type
                      (mcron-configuration
                       (jobs
-                       (list #~(job &quot;30 1 * * 1&quot; &quot;guix gc -d&quot;)
-                             #~(job &quot;30 0 * * *&quot; &quot;/var/lib/euandreh/backup.sh&quot;)))))
+                       (list #~(job &quot;30 1 * * 1&quot; &quot;/opt/bin/gc.sh&quot;)
+                             #~(job &quot;30 0 * * *&quot; &quot;/opt/bin/backup.sh&quot;)))))
             (service dhcp-client-service-type)
             #;
             (service opensmtpd-service-type&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;git-notes-ci.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Other tools such as &lt;a href=&quot;https://git.zx2c4.com/cgit/&quot;&gt;cgit&lt;/a&gt; will also show notes on the web
          interface: &lt;a href=&quot;https://euandre.org/git/servers/commit?id=87c57133abd8be5d7cc46afbf107f59b26066575&quot;
             class=&quot;bare&quot;&gt;https://euandre.org/git/servers/commit?id=87c57133abd8be5d7cc46afbf107f59b26066575&lt;/a&gt;.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;You can go even further: since cgit can serve raw blob directly, you can even serve such artifacts (log
          files, release artifacts, binaries) from cgit itself:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;$ SHA=&quot;$(git notes --ref=refs/notes/ci-logs list 87c57133abd8be5d7cc46afbf107f59b26066575)&quot;
$ echo &quot;https://euandre.org/git/servers/blob?id=$SHA&quot;
https://euandre.org/git/servers/blob?id=1707a97bae24e3864fe7943f8dda6d01c294fb5c&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;git-notes-ci.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;And like that you’ll have cgit serving the artifacts for you: &lt;a href=
          &quot;https://euandre.org/git/servers/blob?id=1707a97bae24e3864fe7943f8dda6d01c294fb5c&quot;
             class=&quot;bare&quot;&gt;https://euandre.org/git/servers/blob?id=1707a97bae24e3864fe7943f8dda6d01c294fb5c&lt;/a&gt;.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      gPodder as a media subscription manager
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/11/14/gpodder-media.html" title="gPodder as a media subscription manager" />
    <published>
      2020-11-14T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/11/14/gpodder-media.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As we &lt;a href=&quot;https://www.charlieharrington.com/unexpected-useless-and-urgent&quot;&gt;re-discover&lt;/a&gt; the value
          of Atom/RSS feeds, most useful feed clients I know of don’t support media, specifically audio and video.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/11/14/gpodder-media.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;As we &lt;a href=&quot;https://www.charlieharrington.com/unexpected-useless-and-urgent&quot;&gt;re-discover&lt;/a&gt; the value
          of Atom/RSS feeds, most useful feed clients I know of don’t support media, specifically audio and video.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;https://gpodder.github.io/&quot;&gt;gPodder&lt;/a&gt; does.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;It is mostly know as a desktop podcatcher. But the thing about podcasts is that the feed is provided
          through an RSS/Atom feed. So you can just use gPodder as your media feed client, where you have control of
          what you look at.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I audio and video providers I know of offer an RSS/Atom view of their content, so you can, say, treat any
          YouTube channel like a feed on its own.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;gPodder will then managed your feeds, watched/unwatched, queue downloads, etc.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Being obvious now, it was a big finding for me. If it got you interested, I recommend you giving gPodder a
          try.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      DIY bare bones CI server with Bash and Nix
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/11/12/diy-nix-bash-ci.html" title="DIY bare bones CI server with Bash and Nix" />
    <published>
      2020-11-12T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/11/12/diy-nix-bash-ci.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;With a server with Nix installed (no need for NixOS), you can leverage its build isolation for running
              CI jobs by adding a &lt;a href=&quot;https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks&quot;&gt;post-receive&lt;/a&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/11/12/diy-nix-bash-ci.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;With a server with Nix installed (no need for NixOS), you can leverage its build isolation for running
              CI jobs by adding a &lt;a href=&quot;https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks&quot;&gt;post-receive&lt;/a&gt;
              Git hook to the server.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;In most of my project I like to keep a &lt;code&gt;test&lt;/code&gt; attribute which runs the test with
              &lt;code&gt;nix-build -A test&lt;/code&gt;. This way, a post-receive hook could look like:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L10&quot;
     href=&quot;#B1-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L11&quot;
     href=&quot;#B1-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L12&quot;
     href=&quot;#B1-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L13&quot;
     href=&quot;#B1-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L14&quot;
     href=&quot;#B1-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L15&quot;
     href=&quot;#B1-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L16&quot;
     href=&quot;#B1-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L17&quot;
     href=&quot;#B1-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L18&quot;
     href=&quot;#B1-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L19&quot;
     href=&quot;#B1-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L20&quot;
     href=&quot;#B1-L20&quot;&gt;20&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;#!/usr/bin/env bash
set -Eeuo pipefail
set -x

LOGS_DIR=&quot;/data/static/ci-logs/libedn&quot;
mkdir -p &quot;$LOGS_DIR&quot;
LOGFILE=&quot;${LOGS_DIR}/$(date -Is)-$(git rev-parse master).log&quot;
exec &amp;amp;&amp;gt; &amp;gt;(tee -a &quot;${LOGFILE}&quot;)

unset GIT_DIR
CLONE=&quot;$(mktemp -d)&quot;
git clone . &quot;$CLONE&quot;
pushd &quot;$CLONE&quot;

finish() {
  printf &quot;\n\n&amp;gt;&amp;gt;&amp;gt; exit status was %s\n&quot; &quot;$?&quot;
}
trap finish EXIT

nix-build -A test&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;diy-nix-bash-ci.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;We initially (lines #5 to #8) create a log file, named after &lt;em&gt;when&lt;/em&gt; the run is running and for
              &lt;em&gt;which&lt;/em&gt; commit it is running for. The &lt;code&gt;exec&lt;/code&gt; and &lt;code&gt;tee&lt;/code&gt; combo allows the
              output of the script to go both to &lt;code&gt;stdout&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; the log file. This makes the logs
              output show up when you do a &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Lines #10 to #13 create a fresh clone of the repository and line #20 runs the test command.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;After using a similar post-receive hook for a while, I now even generate a simple HTML file to make
              the logs available (&lt;a href=&quot;https://euandreh.xyz/remembering/ci.html&quot;&gt;example project&lt;/a&gt;) through the
              browser.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;upsides&quot;&gt;Upsides&lt;a class=&quot;anchor&quot;
             href=&quot;#upsides&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;No vendor lock-in, as all you need is a server with Nix installed.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;And if you pin the Nixpkgs version you’re using, this very simple setup yields extremely sandboxed
              runs on a very hermetic environment.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;downsides&quot;&gt;Downsides&lt;a class=&quot;anchor&quot;
             href=&quot;#downsides&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Besides the many missing shiny features of this very simplistic CI, &lt;code&gt;nix-build&lt;/code&gt; can be very
              resource intensive. Specifically, it consumes too much memory. So if it has to download too many things,
              or the build closure gets too big, the server might very well run out of memory.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Git bisect automation
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/11/12/git-bisect-automation.html" title="Git bisect automation" />
    <published>
      2020-11-12T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/11/12/git-bisect-automation.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;It is good to have an standardized way to run builds and tests on the repository of a project, so that you
          can find when a bug was introduced by using &lt;code&gt;git bisect run&lt;/code&gt;.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/11/12/git-bisect-automation.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;It is good to have an standardized way to run builds and tests on the repository of a project, so that you
          can find when a bug was introduced by using &lt;code&gt;git bisect run&lt;/code&gt;.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I’ve already been in the situation when a bug was introduced and I didn’t know how it even was occurring,
          and running Git bisect over hundreds of commits to pinpoint the failing commit was very empowering:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;$ GOOD_COMMIT_SHA=e1fd0a817d192c5a5df72dd7422e36558fa78e46
$ git bisect start HEAD $GOOD_COMMIT_SHA
$ git bisect run sn -c &apos;./build.sh &amp;amp;&amp; ./run-failing-case.sh&apos;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;git-bisect-automation.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Git will than do a binary search between the commits, and run the commands you provide it with to find the
          failing commit.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Instead of being afraid of doing a bisect, you should instead leverage it, and make Git help you dig
          through the history of the repository to find the bad code.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Useful Bash variables
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/11/12/useful-bashvars.html" title="Useful Bash variables" />
    <published>
      2020-11-12T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/11/12/useful-bashvars.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/&quot;&gt;GNU Bash&lt;/a&gt; has a few two letter variables that may be
              useful when typing on the terminal.&lt;/p&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/11/12/useful-bashvars.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/&quot;&gt;GNU Bash&lt;/a&gt; has a few two letter variables that may be
              useful when typing on the terminal.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;the-text-of-the-last-command&quot;&gt;&lt;code&gt;!!&lt;/code&gt;: the text of the last command&lt;a class=&quot;anchor&quot;
             href=&quot;#the-text-of-the-last-command&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The &lt;a href=&quot;https://www.gnu.org/software/bash/manual/bash.html#Event-Designators&quot;&gt;&lt;code&gt;!!&lt;/code&gt;
              variable&lt;/a&gt; refers to the previous command, and I find useful when following chains for symlinks:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;$ which git
/run/current-system/sw/bin/git
$ readlink $(!!)
readlink $(which git)
/nix/store/5bgr1xpm4m0r72h9049jbbhagxdyrnyb-git-2.28.0/bin/git&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;useful-bashvars.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;It is also useful when you forget to prefix &lt;code&gt;sudo&lt;/code&gt; to a command that requires it:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L5&quot;
     href=&quot;#B2-L5&quot;&gt;5&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;$ requires-sudo.sh
requires-sudo.sh: Permission denied
$ sudo !!
sudo ./requires-sudo.sh
# all good&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;useful-bashvars.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Bash prints the command expansion before executing it, so it is better for you to follow along what it
              is doing.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;_-most-recent-parameter&quot;&gt;&lt;code&gt;$_&lt;/code&gt;: most recent parameter&lt;a class=&quot;anchor&quot;
             href=&quot;#_-most-recent-parameter&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The &lt;a href=&quot;https://www.gnu.org/software/bash/manual/bash.html#Special-Parameters&quot;&gt;&lt;code&gt;$_&lt;/code&gt;
              variable&lt;/a&gt; will give you the most recent parameter you provided to a previous argument, which can save
              you typing sometimes:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;# instead of...
$ mkdir -p a/b/c/d/
$ cd a/b/c/d/

# ...you can:
$ mkdir -p a/b/c/d/
$ cd $_&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;useful-bashvars.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;anchor&quot;
             href=&quot;#conclusion&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;I wouldn’t use those in a script, as it would make the script terser to read, I find those useful
              shortcut that are handy when writing at the interactive terminal.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Find broken symlinks with &quot;find&quot;
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/11/08/find-broken-symlink.html" title="Find broken symlinks with &quot;find&quot;" />
    <published>
      2020-11-08T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/11/08/find-broken-symlink.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The &lt;code&gt;find&lt;/code&gt; command knows how to show broken symlinks:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/11/08/find-broken-symlink.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;The &lt;code&gt;find&lt;/code&gt; command knows how to show broken symlinks:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;find . -xtype l&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;find-broken-symlink.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;This was useful to me when combined with &lt;a href=&quot;https://git-annex.branchable.com/&quot;&gt;Git Annex&lt;/a&gt;. Its
          &lt;a href=&quot;https://git-annex.branchable.com/git-annex-wanted/&quot;&gt;&lt;code&gt;wanted&lt;/code&gt;&lt;/a&gt; option allows you to
          have a &quot;sparse&quot; checkout of the content, and save space by not having to copy every annexed file locally:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;git annex wanted . &apos;exclude=Music/* and exclude=Videos/*&apos;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;find-broken-symlink.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;You can &lt;code&gt;find&lt;/code&gt; any broken symlinks outside those directories by querying with Git Annex itself,
          but &lt;code&gt;find . -xtype l&lt;/code&gt; works on other places too, where broken symlinks might be a problem.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Search changes to a filename pattern in Git history
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/10/11/search-git-history.html" title="Search changes to a filename pattern in Git history" />
    <published>
      2020-10-11T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/10/11/search-git-history.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;This is &lt;a href=&quot;../../08/14/browse-git.html&quot;&gt;yet&lt;/a&gt; &lt;a href=&quot;../../08/16/git-search.html&quot;&gt;another&lt;/a&gt;
          &lt;a href=&quot;../../08/28/grep-online.html&quot;&gt;&quot;search in Git&quot;&lt;/a&gt; TIL entry. You could say that Git has a
          unintuitive CLI, or that is it very powerful.&lt;/p&gt;
        &lt;/div&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/10/11/search-git-history.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;This is &lt;a href=&quot;../../08/14/browse-git.html&quot;&gt;yet&lt;/a&gt; &lt;a href=&quot;../../08/16/git-search.html&quot;&gt;another&lt;/a&gt;
          &lt;a href=&quot;../../08/28/grep-online.html&quot;&gt;&quot;search in Git&quot;&lt;/a&gt; TIL entry. You could say that Git has a
          unintuitive CLI, or that is it very powerful.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I wanted to search for an old file that I new that was in the history of the repository, but was deleted
          some time ago. So I didn’t really remember the name, only bits of it.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I immediately went to the list of TILs I had written on searching in Git, but it wasn’t readily obvious
          how to do it, so here it goes:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;git log -- *pattern*&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;search-git-history.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;You could add globs before the pattern to match things on any directory, and add our &lt;code&gt;-p&lt;/code&gt;
          friend to promptly see the diffs:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;git log -p -- **/*pattern*&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;search-git-history.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Pull requests with Git, the old school way
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/09/05/oldschool-pr.html" title="Pull requests with Git, the old school way" />
    <published>
      2020-09-05T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/09/05/oldschool-pr.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;It might be news to you, as it was to me, that &quot;pull requests&quot; that you can create on a Git hosting
              provider’s web UIfootnote:pr-webui[ And maybe even using the Git hosting provider’s API from the command
    </summary>
    <content type="html" xml:base="en/til/2020/09/05/oldschool-pr.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;It might be news to you, as it was to me, that &quot;pull requests&quot; that you can create on a Git hosting
              provider’s web UIfootnote:pr-webui[ And maybe even using the Git hosting provider’s API from the command
              line! ] like GitLab/Bitbucket/GitHub actually comes from Git itself: &lt;code&gt;git request-pull&lt;/code&gt;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;At the very core, they accomplish the same thing: both the original and the web UI ones are ways for
              you to request the project maintainers to pull in your changes from your fork. It’s like saying: &quot;hi
              there, I did some changes on my clone of the repository, what do you think about bringing those in?&quot;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The only difference is that you’re working with only Git itself, so you’re not tied to any Git hosting
              provider: you can send pull requests across them transparently! You could even use your own &lt;a href=
              &quot;https://git.zx2c4.com/cgit/&quot;&gt;cgit&lt;/a&gt; installation. No need to be locked in by any of them, putting the
              &quot;D&quot; back in &quot;DVCS&quot;: it’s a &lt;strong&gt;distributed&lt;/strong&gt; version control system.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;git-request-pull-introduction&quot;&gt;&lt;code&gt;git request-pull&lt;/code&gt; introduction&lt;a class=&quot;anchor&quot;
             href=&quot;#git-request-pull-introduction&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Here’s the raw output of a &lt;code&gt;git request-pull&lt;/code&gt;:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L10&quot;
     href=&quot;#B1-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L11&quot;
     href=&quot;#B1-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L12&quot;
     href=&quot;#B1-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L13&quot;
     href=&quot;#B1-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L14&quot;
     href=&quot;#B1-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L15&quot;
     href=&quot;#B1-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L16&quot;
     href=&quot;#B1-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L17&quot;
     href=&quot;#B1-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L18&quot;
     href=&quot;#B1-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L19&quot;
     href=&quot;#B1-L19&quot;&gt;19&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;$ git request-pull HEAD public-origin
The following changes since commit 302c9f2f035c0360acd4e13142428c100a10d43f:

  db post: Add link to email exchange (2020-09-03 21:23:55 -0300)

are available in the Git repository at:

  https://euandre.org/git/euandre.org/

for you to fetch changes up to 524c646cdac4153e54f2163e280176adbc4873fa:

  db post: better pinpoint sqlite unsuitability (2020-09-03 22:08:56 -0300)

----------------------------------------------------------------
EuAndreh (1):
      db post: better pinpoint sqlite unsuitability

 _posts/2020-08-31-the-database-i-wish-i-had.md | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;oldschool-pr.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;That very first line is saying: &quot;create me a pull request with only a single commit, defined by
              &lt;code&gt;HEAD&lt;/code&gt;, and use the URL defined by &lt;code&gt;public-origin&lt;/code&gt;&quot;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Here’s a pitfall: you may try using your &lt;code&gt;origin&lt;/code&gt; remote at first where I put
              &lt;code&gt;public-origin&lt;/code&gt;, but that is many times pointing to something like
              &lt;code&gt;git@example.com&lt;/code&gt;, or &lt;code&gt;git.example.com:repo.git&lt;/code&gt; (check that with &lt;code&gt;git remote
              -v | grep origin&lt;/code&gt;). On both cases those are addresses available for interaction via SSH, and it
              would be better if your pull requests used an address ready for public consumption.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;A simple solution for that is for you to add the &lt;code&gt;public-origin&lt;/code&gt; alias as the HTTPS
              alternative to the SSH version:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;$ git remote add public-origin https://example.com/user/repo&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;oldschool-pr.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Every Git hosting provider exposes repositories via HTTPS.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Experiment it yourself, and get acquainted with the CLI.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;delivering-decentralized-pull-requests&quot;&gt;Delivering decentralized pull requests&lt;a class=&quot;anchor&quot;
             href=&quot;#delivering-decentralized-pull-requests&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Now that you can create the content of a pull request, you can just &lt;a href=
              &quot;../04/cli-email-fun-profit.html&quot;&gt;deliver it&lt;/a&gt; to the interested parties email:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;# send a PR with your last commit to the author&apos;s email
git request-pull HEAD public-origin | mail author@example.com -s &quot;PR: Add thing to repo&quot;

# send a PR with your last 5 commits to the project&apos;s mailing
# list, including the patch
git request-pull -p HEAD~5 public-origin | \
  mail list@example.com -s &quot;PR: Add another thing to repo&quot;

# send every commit that is new in &quot;other-branch&quot;
git request-pull master public-origin other-branch | \
  mail list@example.com -s &apos;PR: All commits from my &quot;other-brach&quot;&apos;&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;oldschool-pr.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;anchor&quot;
             href=&quot;#conclusion&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;In practice, I’ve never used or seen anyone use pull requests this way: everybody is just &lt;a href=
              &quot;https://drewdevault.com/2018/07/23/Git-is-already-distributed.html&quot;&gt;sending patches via email&lt;/a&gt;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;If you stop to think about this model, the problem of &quot;Git hosting providers becoming too centralized&quot;
              is a non-issue, and &quot;Git federation&quot; proposals are a less attractive as they may sound initially.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Using Git this way is not scary or so weird as the first impression may suggest. It is actually how
              Git was designed to be used.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Check &lt;code&gt;git help request-pull&lt;/code&gt; for more info.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Send emails using the command line for fun and profit!
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/09/04/cli-email-fun-profit.html" title="Send emails using the command line for fun and profit!" />
    <published>
      2020-09-04T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/09/04/cli-email-fun-profit.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Here are a few reasons why:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;olist arabic&quot;&gt;
          &lt;ol class=&quot;arabic&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/09/04/cli-email-fun-profit.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Here are a few reasons why:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;olist arabic&quot;&gt;
          &lt;ol class=&quot;arabic&quot;&gt;
            &lt;li&gt;
              &lt;p&gt;send yourself and other people notification of cronjobs, scripts runs, CI jobs, &lt;em&gt;etc.&lt;/em&gt;&lt;/p&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;leverage the POSIX pipe &lt;code&gt;|&lt;/code&gt;, and pipe emails away!&lt;/p&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;because you can.&lt;/p&gt;
            &lt;/li&gt;
          &lt;/ol&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Reason 3 is the fun part, reasons 1 and 2 are the profit part.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;First &lt;a href=&quot;https://wiki.archlinux.org/index.php/SSMTP&quot;&gt;install and configure SSMTP&lt;/a&gt; for using, say,
          Gmail as the email server:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;# file /etc/ssmtp/ssmtp.conf
FromLineOverride=YES
MailHub=smtp.gmail.com:587
UseSTARTTLS=YES
UseTLS=YES
rewriteDomain=gmail.com
root=username@gmail.com
AuthUser=username
AuthPass=password&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;cli-email-fun-profit.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Now install &lt;a href=&quot;https://mailutils.org/&quot;&gt;GNU Mailutils&lt;/a&gt; (&lt;code&gt;sudo apt-get install
          mailutils&lt;/code&gt; or the equivalent on your OS), and send yourself your first email:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;echo body | mail -aFrom:email@example.com email@example.com -s subject&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;cli-email-fun-profit.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;And that’s about it, you’ve got mail. Here are some more places where it might be applicable:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L12&quot;
     href=&quot;#B3-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L13&quot;
     href=&quot;#B3-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L14&quot;
     href=&quot;#B3-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L15&quot;
     href=&quot;#B3-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L16&quot;
     href=&quot;#B3-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L17&quot;
     href=&quot;#B3-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L18&quot;
     href=&quot;#B3-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L19&quot;
     href=&quot;#B3-L19&quot;&gt;19&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;# report a backup cronjob, attaching logs
set -e

finish() {
  status=$?
  if [[ $status = 0 ]]; then
    STATUS=&quot;SUCCESS (status $status)&quot;
  else
    STATUS=&quot;FAILURE (status $status)&quot;
  fi

  mail user@example.com                                 \
       -s &quot;Backup job report on $(hostname): ${STATUS}&quot; \
       --content-type &apos;text/plain; charset=utf-8&apos;       \
       -A&quot;$LOG_FILE&quot; &amp;lt;&amp;lt;&amp;lt; &apos;The log report is in the attachment.&apos;
}
trap finish EXIT

do-long-backup-cmd-here&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;cli-email-fun-profit.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;# share the output of a cmd with someone
some-program | mail someone@example.com -s &quot;The weird logs that I was talking about&quot;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;cli-email-fun-profit.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;…​and so on.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;You may consider adding a &lt;code&gt;alias mail=’mail -aFrom:email@example.com’&lt;/code&gt; so you don’t keep
          re-entering the “From:” part.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Send yourself some emails to see it working!&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Grep online repositories
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/08/28/grep-online.html" title="Grep online repositories" />
    <published>
      2020-08-28T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/08/28/grep-online.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I often find interesting source code repositories online that I want to grep for some pattern but I can’t,
          because either:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;ulist&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/08/28/grep-online.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I often find interesting source code repositories online that I want to grep for some pattern but I can’t,
          because either:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;ulist&quot;&gt;
          &lt;ul&gt;
            &lt;li&gt;
              &lt;p&gt;the repository is on &lt;a href=&quot;https://git.zx2c4.com/cgit/&quot;&gt;cgit&lt;/a&gt; or a similar code repository that
              doesn’t allow search in files, or;&lt;/p&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;the search function is really bad, and doesn’t allow me to use regular expressions for searching
              patterns in the code.&lt;/p&gt;
            &lt;/li&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Here’s a simple script that allows you to overcome that problem easily:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L10&quot;
     href=&quot;#B1-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L11&quot;
     href=&quot;#B1-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L12&quot;
     href=&quot;#B1-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L13&quot;
     href=&quot;#B1-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L14&quot;
     href=&quot;#B1-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L15&quot;
     href=&quot;#B1-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L16&quot;
     href=&quot;#B1-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L17&quot;
     href=&quot;#B1-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L18&quot;
     href=&quot;#B1-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L19&quot;
     href=&quot;#B1-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L20&quot;
     href=&quot;#B1-L20&quot;&gt;20&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L21&quot;
     href=&quot;#B1-L21&quot;&gt;21&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L22&quot;
     href=&quot;#B1-L22&quot;&gt;22&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L23&quot;
     href=&quot;#B1-L23&quot;&gt;23&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L24&quot;
     href=&quot;#B1-L24&quot;&gt;24&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L25&quot;
     href=&quot;#B1-L25&quot;&gt;25&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L26&quot;
     href=&quot;#B1-L26&quot;&gt;26&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L27&quot;
     href=&quot;#B1-L27&quot;&gt;27&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L28&quot;
     href=&quot;#B1-L28&quot;&gt;28&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L29&quot;
     href=&quot;#B1-L29&quot;&gt;29&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L30&quot;
     href=&quot;#B1-L30&quot;&gt;30&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L31&quot;
     href=&quot;#B1-L31&quot;&gt;31&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L32&quot;
     href=&quot;#B1-L32&quot;&gt;32&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L33&quot;
     href=&quot;#B1-L33&quot;&gt;33&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L34&quot;
     href=&quot;#B1-L34&quot;&gt;34&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L35&quot;
     href=&quot;#B1-L35&quot;&gt;35&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L36&quot;
     href=&quot;#B1-L36&quot;&gt;36&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L37&quot;
     href=&quot;#B1-L37&quot;&gt;37&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L38&quot;
     href=&quot;#B1-L38&quot;&gt;38&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L39&quot;
     href=&quot;#B1-L39&quot;&gt;39&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L40&quot;
     href=&quot;#B1-L40&quot;&gt;40&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;#!/usr/bin/env bash
set -eu

end=&quot;\033[0m&quot;
red=&quot;\033[0;31m&quot;
red() { echo -e &quot;${red}${1}${end}&quot;; }

usage() {
  red &quot;Missing argument $1.\n&quot;
  cat &amp;lt;&amp;lt;EOF
Usage:
    $0 &amp;lt;REGEX_PATTERN&amp;gt; &amp;lt;REPOSITORY_URL&amp;gt;

      Arguments:
        REGEX_PATTERN     Regular expression that &quot;git grep&quot; can search
        REPOSITORY_URL    URL address that &quot;git clone&quot; can download the repository from

Examples:
    Searching &quot;make get-git&quot; in cgit repository:
        git search &apos;make get-git&apos; https://git.zx2c4.com/cgit/
        git search &apos;make get-git&apos; https://git.zx2c4.com/cgit/ -- \$(git rev-list --all)
EOF
  exit 2
}


REGEX_PATTERN=&quot;${1:-}&quot;
REPOSITORY_URL=&quot;${2:-}&quot;
[[ -z &quot;${REGEX_PATTERN}&quot; ]] &amp;amp;&amp; usage &apos;REGEX_PATTERN&apos;
[[ -z &quot;${REPOSITORY_URL}&quot; ]] &amp;amp;&amp; usage &apos;REPOSITORY_URL&apos;

mkdir -p /tmp/git-search
DIRNAME=&quot;$(echo &quot;${REPOSITORY_URL%/}&quot; | rev | cut -d/ -f1 | rev)&quot;
if [[ ! -d &quot;/tmp/git-search/${DIRNAME}&quot; ]]; then
  git clone &quot;${REPOSITORY_URL}&quot; &quot;/tmp/git-search/${DIRNAME}&quot;
fi
pushd &quot;/tmp/git-search/${DIRNAME}&quot;

shift 3 || shift 2 # when &quot;--&quot; is missing
git grep &quot;${REGEX_PATTERN}&quot; &quot;${@}&quot;&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;grep-online.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;It is a wrapper around &lt;code&gt;git grep&lt;/code&gt; that downloads the repository when missing. Save in a file
          called &lt;code&gt;git-search&lt;/code&gt;, make the file executable and add it to your path.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Overview:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;ulist&quot;&gt;
          &lt;ul&gt;
            &lt;li&gt;
              &lt;p&gt;&lt;em&gt;lines 1~2&lt;/em&gt;:&lt;/p&gt;
              &lt;div class=&quot;paragraph&quot;&gt;
                &lt;p&gt;Bash shebang and the &lt;code&gt;set -eu&lt;/code&gt; options to exit on error or undefined variables.&lt;/p&gt;
              &lt;/div&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;&lt;em&gt;lines 4~30&lt;/em&gt;:&lt;/p&gt;
              &lt;div class=&quot;paragraph&quot;&gt;
                &lt;p&gt;Usage text to be printed when providing less arguments than expected.&lt;/p&gt;
              &lt;/div&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;&lt;em&gt;line 33&lt;/em&gt;:&lt;/p&gt;
              &lt;div class=&quot;paragraph&quot;&gt;
                &lt;p&gt;Extract the repository name from the URL, removing trailing slashes.&lt;/p&gt;
              &lt;/div&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;&lt;em&gt;lines 34~37&lt;/em&gt;:&lt;/p&gt;
              &lt;div class=&quot;paragraph&quot;&gt;
                &lt;p&gt;Download the repository when missing and go to the folder.&lt;/p&gt;
              &lt;/div&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;&lt;em&gt;line 39&lt;/em&gt;:&lt;/p&gt;
              &lt;div class=&quot;paragraph&quot;&gt;
                &lt;p&gt;Make the variable &lt;code&gt;$@&lt;/code&gt; contain the rest of the unused arguments.&lt;/p&gt;
              &lt;/div&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;p&gt;&lt;em&gt;line 40&lt;/em&gt;:&lt;/p&gt;
              &lt;div class=&quot;paragraph&quot;&gt;
                &lt;p&gt;Perform &lt;code&gt;git grep&lt;/code&gt;, forwarding the remaining arguments from &lt;code&gt;$@&lt;/code&gt;.&lt;/p&gt;
              &lt;/div&gt;
            &lt;/li&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Example output:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L5&quot;
     href=&quot;#B2-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L6&quot;
     href=&quot;#B2-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L7&quot;
     href=&quot;#B2-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L8&quot;
     href=&quot;#B2-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L9&quot;
     href=&quot;#B2-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L10&quot;
     href=&quot;#B2-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L11&quot;
     href=&quot;#B2-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L12&quot;
     href=&quot;#B2-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L13&quot;
     href=&quot;#B2-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L14&quot;
     href=&quot;#B2-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L15&quot;
     href=&quot;#B2-L15&quot;&gt;15&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;$ git search &apos;make get-git&apos; https://git.zx2c4.com/cgit/
Clonage dans &apos;/tmp/git-search/cgit&apos;...
remote: Enumerating objects: 542, done.
remote: Counting objects: 100% (542/542), done.
remote: Compressing objects: 100% (101/101), done.
warning: object 51dd1eff1edc663674df9ab85d2786a40f7ae3a5: gitmodulesParse: could not parse gitmodules blob
remote: Total 7063 (delta 496), reused 446 (delta 441), pack-reused 6521
Réception d&apos;objets: 100% (7063/7063), 8.69 Mio | 5.39 Mio/s, fait.
Résolution des deltas: 100% (5047/5047), fait.
/tmp/git-search/cgit ~/dev/libre/songbooks/docs
README:    $ make get-git

$ git search &apos;make get-git&apos; https://git.zx2c4.com/cgit/
/tmp/git-search/cgit ~/dev/libre/songbooks/docs
README:    $ make get-git&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;grep-online.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Subsequent greps on the same repository are faster because no download is needed.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;When no argument is provided, it prints the usage text:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L8&quot;
     href=&quot;#B3-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L9&quot;
     href=&quot;#B3-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L10&quot;
     href=&quot;#B3-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L11&quot;
     href=&quot;#B3-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L12&quot;
     href=&quot;#B3-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L13&quot;
     href=&quot;#B3-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L14&quot;
     href=&quot;#B3-L14&quot;&gt;14&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;$ git search
Missing argument REGEX_PATTERN.

Usage:
    /home/andreh/dev/libre/dotfiles/scripts/ad-hoc/git-search &amp;lt;REGEX_PATTERN&amp;gt; &amp;lt;REPOSITORY_URL&amp;gt;

      Arguments:
        REGEX_PATTERN     Regular expression that &quot;git grep&quot; can search
        REPOSITORY_URL    URL address that &quot;git clone&quot; can download the repository from

Examples:
    Searching &quot;make get-git&quot; in cgit repository:
        git search &apos;make get-git&apos; https://git.zx2c4.com/cgit/
        git search &apos;make get-git&apos; https://git.zx2c4.com/cgit/ -- $(git rev-list --all)&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;grep-online.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Search in git
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/08/16/git-search.html" title="Search in git" />
    <published>
      2020-08-16T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/08/16/git-search.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Here’s a useful trio to know about to help you search things in git:&lt;/p&gt;
            &lt;/div&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/08/16/git-search.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Here’s a useful trio to know about to help you search things in git:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;olist arabic&quot;&gt;
              &lt;ol class=&quot;arabic&quot;&gt;
                &lt;li&gt;
                  &lt;p&gt;&lt;code&gt;git show &amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/p&gt;
                &lt;/li&gt;
                &lt;li&gt;
                  &lt;p&gt;&lt;code&gt;git log --grep=&apos;&amp;lt;regexp&amp;gt;&apos;&lt;/code&gt;&lt;/p&gt;
                &lt;/li&gt;
                &lt;li&gt;
                  &lt;p&gt;&lt;code&gt;git grep &apos;&amp;lt;regexp&amp;gt;&apos; [commit]&lt;/code&gt;&lt;/p&gt;
                &lt;/li&gt;
              &lt;/ol&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;1-git-show-commit&quot;&gt;1. &lt;code&gt;git show &amp;lt;commit&amp;gt;&lt;/code&gt;&lt;a class=&quot;anchor&quot;
             href=&quot;#1-git-show-commit&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Show a specific commit and it’s diff:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;git show
# shows the latest commit
git show &amp;lt;commit&amp;gt;
# shows an specific &amp;lt;commit&amp;gt;
git show v1.2
# shows commit tagged with v1.2&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;git-search.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;2-git-log-grepregexp&quot;&gt;2. &lt;code&gt;git log --grep=&apos;&amp;lt;regexp&amp;gt;&apos;&lt;/code&gt;&lt;a class=&quot;anchor&quot;
             href=&quot;#2-git-log-grepregexp&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Search through the commit messages:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;git log --grep=&apos;refactor&apos;&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;git-search.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;3-git-grep-regexp-commit&quot;&gt;3. &lt;code&gt;git grep &apos;&amp;lt;regexp&amp;gt;&apos; [commit]&lt;/code&gt;&lt;a class=&quot;anchor&quot;
             href=&quot;#3-git-grep-regexp-commit&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Search content in git history:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;git grep &apos;TODO&apos;
# search the repository for the &quot;TODO&quot; string
git grep &apos;TODO&apos; $(git rev-list --all)
# search the whole history for &quot;TODO&quot; string&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;git-search.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;And if you find an occurrence of the regexp in a specific commit and you want to browse the repository
              in that point in time, you can link:../14/browse-git.html[use git checkout for that].&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Browse a git repository at a specific commit
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/08/14/browse-git.html" title="Browse a git repository at a specific commit" />
    <published>
      2020-08-14T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/08/14/browse-git.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;I commonly use tools like &lt;code&gt;git log&lt;/code&gt; together with &lt;code&gt;git show&lt;/code&gt; when inspecting
              past changes in a repository:&lt;/p&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/08/14/browse-git.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;I commonly use tools like &lt;code&gt;git log&lt;/code&gt; together with &lt;code&gt;git show&lt;/code&gt; when inspecting
              past changes in a repository:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;git log
# search for a the commit I&apos;m looking for
git show &amp;lt;my-commit&amp;gt;
# see the diff for the commit&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;browse-git.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;But I also wanted to not only be able to look at the diff of a specific commit, but to browse the
              whole repository at that specific commit.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;I used to accomplish it the &quot;brute force&quot; way: clone the whole repository in another folder and
              checkout the commit there:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;git clone &amp;lt;original-repo&amp;gt; /tmp/tmp-repo-clone
cd /tmp-repo-clone
git checkout &amp;lt;my-commit&amp;gt;&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;browse-git.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;But git itself allows we to specific the directory of the checkout by using the
              &lt;code&gt;--work-tree&lt;/code&gt; global git flag. This is what &lt;code&gt;man git&lt;/code&gt; says about it:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;--work-tree=&amp;lt;path&amp;gt;
    Set the path to the working tree. It can be an absolute path or a path relative to the current working
    directory. This can also be controlled by setting the GIT_WORK_TREE environment variable and the
    core.worktree configuration variable (see core.worktree in git-config(1) for a more detailed
    discussion).&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;browse-git.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;So it allows us to set the desired path of the working tree. So if we want to copy the contents of the
              current working tree into &lt;code&gt;copy/&lt;/code&gt;:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;mkdir copy
git --work-tree=copy/ checkout .&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;browse-git.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;After that &lt;code&gt;copy/&lt;/code&gt; will contain a replica of the code in HEAD. But to checkout a specific,
              we need some extra parameters:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L1&quot;
     href=&quot;#B5-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;git --work-tree=&amp;lt;dir&amp;gt; checkout &amp;lt;my-commit&amp;gt; -- .&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;browse-git.html.4.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;There’s an extra &lt;code&gt;– .&lt;/code&gt; at the end, which initially looks like we’re sending Morse signals
              to git, but we’re actually saying to &lt;code&gt;git-checkout&lt;/code&gt; which sub directory of
              &lt;code&gt;&amp;lt;my-commit&amp;gt;&lt;/code&gt; we want to look at. Which means we can do something like:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L1&quot;
     href=&quot;#B6-L1&quot;&gt;1&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;git --work-tree=&amp;lt;dir&amp;gt; checkout &amp;lt;my-commit&amp;gt; -- src/&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;browse-git.html.5.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;And with that &lt;code&gt;&amp;lt;dir&amp;gt;&lt;/code&gt; will only contain what was inside &lt;code&gt;src/&lt;/code&gt; at
              &lt;code&gt;&amp;lt;commit&amp;gt;&lt;/code&gt;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;After any of those checkouts, you have to &lt;code&gt;git reset .&lt;/code&gt; to reset your current staging area
              back to what it was before the checkout.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;references&quot;&gt;References&lt;a class=&quot;anchor&quot;
             href=&quot;#references&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;olist arabic&quot;&gt;
              &lt;ol class=&quot;arabic&quot;&gt;
                &lt;li&gt;
                  &lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/a/16493707&quot;&gt;GIT: Checkout to a specific folder&lt;/a&gt;
                  (StackOverflow)&lt;/p&gt;
                &lt;/li&gt;
              &lt;/ol&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Anchor headers and code lines in Jekyll
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/08/13/code-jekyll.html" title="Anchor headers and code lines in Jekyll" />
    <published>
      2020-08-13T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/08/13/code-jekyll.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The default Jekyll toolbox (&lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, &lt;a href=
              &quot;https://kramdown.gettalong.org/&quot;&gt;kramdown&lt;/a&gt; and &lt;a href=&quot;https://rouge.jneen.net/&quot;&gt;rouge&lt;/a&gt;) doesn’t
    </summary>
    <content type="html" xml:base="en/til/2020/08/13/code-jekyll.html">
        &lt;div id=&quot;preamble&quot;&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The default Jekyll toolbox (&lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, &lt;a href=
              &quot;https://kramdown.gettalong.org/&quot;&gt;kramdown&lt;/a&gt; and &lt;a href=&quot;https://rouge.jneen.net/&quot;&gt;rouge&lt;/a&gt;) doesn’t
              provide with a configuration option to add anchors to headers and code blocks.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The best way I found of doing this is by creating a simple Jekyll plugin, more specifically, a
              &lt;a href=&quot;https://jekyllrb.com/docs/plugins/hooks/&quot;&gt;Jekyll hook&lt;/a&gt;. These allow you to jump in to the
              Jekyll build and add a processing stage before of after Jekyll performs something.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;All you have to do is add the code to &lt;code&gt;_plugins/my-jekyll-plugin-code.rb&lt;/code&gt;, and Jekyll knows
              to pick it up and call your code on the appropriate time.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;anchor-on-headers&quot;&gt;Anchor on headers&lt;a class=&quot;anchor&quot;
             href=&quot;#anchor-on-headers&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Since I wanted to add anchors to headers in all documents, this Jekyll hook works on
              &lt;code&gt;:documents&lt;/code&gt; after they have been transformed into HTML, the &lt;code&gt;:post_render&lt;/code&gt;
              phase:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L3&quot;
     href=&quot;#B1-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L4&quot;
     href=&quot;#B1-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L5&quot;
     href=&quot;#B1-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L6&quot;
     href=&quot;#B1-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L7&quot;
     href=&quot;#B1-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L8&quot;
     href=&quot;#B1-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L9&quot;
     href=&quot;#B1-L9&quot;&gt;9&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;Jekyll::Hooks.register :documents, :post_render do |doc|
  if doc.output_ext == &quot;.html&quot;
    doc.output =
      doc.output.gsub(
        /&amp;lt;h([1-6])(.*?)id=&quot;([\w-]+)&quot;(.*?)&amp;gt;(.*?)&amp;lt;\/h[1-6]&amp;gt;/,
        &apos;&amp;lt;a href=&quot;#\3&quot;&amp;gt;&amp;lt;h\1\2id=&quot;\3&quot;\4&amp;gt;\5&amp;lt;/h\1&amp;gt;&amp;lt;/a&amp;gt;&apos;
      )
  end
end&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;code-jekyll.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;I’ve derived my implementations from two &quot;official&quot;footnote:official[ I don’t know how official they
              are, I just assumed it because they live in the same organization inside GitHub that Jekyll does. ]
              hooks, &lt;a href=&quot;https://github.com/jekyll/jemoji&quot;&gt;jemoji&lt;/a&gt; and &lt;a href=
              &quot;https://github.com/jekyll/jekyll-mentions&quot;&gt;jekyll-mentions&lt;/a&gt;.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;All I did was to wrap the header tag inside an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;, and set the &lt;code&gt;href&lt;/code&gt;
              of that &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; to the existing id of the header. Before the hook the HTML looks like:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L5&quot;
     href=&quot;#B2-L5&quot;&gt;5&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;...some unmodified text...
&amp;lt;h2 id=&quot;my-header&quot;&amp;gt;
  My header
&amp;lt;/h2&amp;gt;
...more unmodified text...&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;code-jekyll.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;And after the hook should turn that into:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L1&quot;
     href=&quot;#B3-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L2&quot;
     href=&quot;#B3-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L3&quot;
     href=&quot;#B3-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L4&quot;
     href=&quot;#B3-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L5&quot;
     href=&quot;#B3-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L6&quot;
     href=&quot;#B3-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B3-L7&quot;
     href=&quot;#B3-L7&quot;&gt;7&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;...some unmodified text...
&amp;lt;a href=&quot;#my-header&quot;&amp;gt;
  &amp;lt;h2 id=&quot;my-header&quot;&amp;gt;
    My header
  &amp;lt;/h2&amp;gt;
&amp;lt;/a&amp;gt;
...more unmodified text...&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;code-jekyll.html.2.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The used regexp tries to match only h1-h6 tags, and keep the rest of the HTML attributes untouched,
              since this isn’t a general HTML parser, but the generated HTML is somewhat under your control. Use at
              your own risk because &lt;a href=
              &quot;https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454&quot;&gt;
              you shouldn’t parse HTML with regexps&lt;/a&gt;. Also I used this strategy in my environment, where no other
              plugins are installed. I haven’t considered how this approach may conflict with other Jekyll plugins.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;In the new anchor tag you can add your custom CSS class to style it as you wish.&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;sect1&quot;&gt;
          &lt;h2 id=&quot;anchor-on-code-blocks&quot;&gt;Anchor on code blocks&lt;a class=&quot;anchor&quot;
             href=&quot;#anchor-on-code-blocks&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
          &lt;div class=&quot;sectionbody&quot;&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Adding anchors to code blocks needs a little bit of extra work, because line numbers themselves don’t
              have preexisting ids, so we need to generate them without duplications between multiple code blocks in
              the same page.&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Similarly, this Jekyll hook also works on &lt;code&gt;:documents&lt;/code&gt; in the &lt;code&gt;:post_render&lt;/code&gt;
              phase:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L1&quot;
     href=&quot;#B4-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L2&quot;
     href=&quot;#B4-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L3&quot;
     href=&quot;#B4-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L4&quot;
     href=&quot;#B4-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L5&quot;
     href=&quot;#B4-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L6&quot;
     href=&quot;#B4-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L7&quot;
     href=&quot;#B4-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L8&quot;
     href=&quot;#B4-L8&quot;&gt;8&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L9&quot;
     href=&quot;#B4-L9&quot;&gt;9&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L10&quot;
     href=&quot;#B4-L10&quot;&gt;10&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L11&quot;
     href=&quot;#B4-L11&quot;&gt;11&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L12&quot;
     href=&quot;#B4-L12&quot;&gt;12&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L13&quot;
     href=&quot;#B4-L13&quot;&gt;13&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L14&quot;
     href=&quot;#B4-L14&quot;&gt;14&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L15&quot;
     href=&quot;#B4-L15&quot;&gt;15&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L16&quot;
     href=&quot;#B4-L16&quot;&gt;16&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L17&quot;
     href=&quot;#B4-L17&quot;&gt;17&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L18&quot;
     href=&quot;#B4-L18&quot;&gt;18&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L19&quot;
     href=&quot;#B4-L19&quot;&gt;19&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B4-L20&quot;
     href=&quot;#B4-L20&quot;&gt;20&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;PREFIX = &apos;&amp;lt;pre class=&quot;lineno&quot;&amp;gt;&apos;
POSTFIX = &apos;&amp;lt;/pre&amp;gt;&apos;
Jekyll::Hooks.register :documents, :post_render do |doc|
  if doc.output_ext == &quot;.html&quot;
    code_block_counter = 1
    doc.output = doc.output.gsub(/&amp;lt;pre class=&quot;lineno&quot;&amp;gt;[\n0-9]+&amp;lt;\/pre&amp;gt;/) do |match|
      line_numbers = match
                      .gsub(/&amp;lt;pre class=&quot;lineno&quot;&amp;gt;([\n0-9]+)&amp;lt;\/pre&amp;gt;/, &apos;\1&apos;)
                      .split(&quot;\n&quot;)

      anchored_line_numbers_array = line_numbers.map do |n|
        id = &quot;B#{code_block_counter}-L#{n}&quot;
        &quot;&amp;lt;a id=\&quot;#{id}\&quot; href=\&quot;##{id}\&quot;&amp;gt;#{n}&amp;lt;/a&amp;gt;&quot;
      end
      code_block_counter += 1

      PREFIX + anchored_line_numbers_array.join(&quot;\n&quot;) + POSTFIX
    end
  end
end&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;code-jekyll.html.3.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;This solution assumes the default Jekyll toolbox with code line numbers turned on in
              &lt;code&gt;_config.yml&lt;/code&gt;:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L1&quot;
     href=&quot;#B5-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L2&quot;
     href=&quot;#B5-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L3&quot;
     href=&quot;#B5-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L4&quot;
     href=&quot;#B5-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L5&quot;
     href=&quot;#B5-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B5-L6&quot;
     href=&quot;#B5-L6&quot;&gt;6&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;kramdown:
  syntax_highlighter_opts:
    span:
      line_numbers: false
    block:
      line_numbers: true&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;code-jekyll.html.4.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;The anchors go from B1-L1 to BN-LN, using the &lt;code&gt;code_block_counter&lt;/code&gt; to track which code
              block we’re in and don’t duplicate anchor ids. Before the hook the HTML looks like:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L1&quot;
     href=&quot;#B6-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L2&quot;
     href=&quot;#B6-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L3&quot;
     href=&quot;#B6-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L4&quot;
     href=&quot;#B6-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L5&quot;
     href=&quot;#B6-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L6&quot;
     href=&quot;#B6-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L7&quot;
     href=&quot;#B6-L7&quot;&gt;7&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B6-L8&quot;
     href=&quot;#B6-L8&quot;&gt;8&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;...some unmodified text...
&amp;lt;pre class=&quot;lineno&quot;&amp;gt;1
2
3
4
5
&amp;lt;/pre&amp;gt;
...more unmodified text...&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;code-jekyll.html.5.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;And after the hook should turn that into:&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;listingblock&quot;&gt;
              &lt;div class=&quot;content&quot;&gt;
                &lt;table&gt;
                  &lt;tbody&gt;
                    &lt;tr&gt;
                      &lt;td&gt;
                        &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L1&quot;
     href=&quot;#B7-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L2&quot;
     href=&quot;#B7-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L3&quot;
     href=&quot;#B7-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L4&quot;
     href=&quot;#B7-L4&quot;&gt;4&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L5&quot;
     href=&quot;#B7-L5&quot;&gt;5&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L6&quot;
     href=&quot;#B7-L6&quot;&gt;6&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B7-L7&quot;
     href=&quot;#B7-L7&quot;&gt;7&lt;/a&gt;&lt;/pre&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                        &lt;pre&gt;...some unmodified text...
&amp;lt;pre class=&quot;lineno&quot;&amp;gt;&amp;lt;a id=&quot;B1-L1&quot; href=&quot;#B1-L1&quot;&amp;gt;1&amp;lt;/a&amp;gt;
&amp;lt;a id=&quot;B1-L2&quot; href=&quot;#B1-L2&quot;&amp;gt;2&amp;lt;/a&amp;gt;
&amp;lt;a id=&quot;B1-L3&quot; href=&quot;#B1-L3&quot;&amp;gt;3&amp;lt;/a&amp;gt;
&amp;lt;a id=&quot;B1-L4&quot; href=&quot;#B1-L4&quot;&amp;gt;4&amp;lt;/a&amp;gt;
&amp;lt;a id=&quot;B1-L5&quot; href=&quot;#B1-L5&quot;&amp;gt;5&amp;lt;/a&amp;gt;&amp;lt;/pre&amp;gt;
...more unmodified text...&lt;/pre&gt;
                      &lt;/td&gt;
                    &lt;/tr&gt;
                  &lt;/tbody&gt;
                &lt;/table&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph plaintext&quot;&gt;
              &lt;p&gt;&lt;a href=&quot;code-jekyll.html.6.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;
            &lt;div class=&quot;paragraph&quot;&gt;
              &lt;p&gt;Happy writing :)&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    </content>
  </entry>
  <entry xml:lang="en">
    <title type="html">
      Simple filename timestamp
    </title>
    <link type="text/html" rel="alternative" href="https://euandre.org/en/til/2020/08/12/filename-timestamp.html" title="Simple filename timestamp" />
    <published>
      2020-08-12T00:00:00+00:00
    </published>
    <id>
      https://euandre.org/en/til/2020/08/12/filename-timestamp.html
    </id>
    <author>
      <name>
        EuAndreh
      </name>
      <email>
        eu@euandre.org
      </email>
    </author>
    <summary type="html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;When writing Jekyll posts or creating log files with dates on them, I usually struggle with finding a
          direct way of accomplishing that. There’s a simple solution: &lt;code&gt;date -I&lt;/code&gt;.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
    </summary>
    <content type="html" xml:base="en/til/2020/08/12/filename-timestamp.html">
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;When writing Jekyll posts or creating log files with dates on them, I usually struggle with finding a
          direct way of accomplishing that. There’s a simple solution: &lt;code&gt;date -I&lt;/code&gt;.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L1&quot;
     href=&quot;#B1-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B1-L2&quot;
     href=&quot;#B1-L2&quot;&gt;2&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;./my-program.sh &amp;gt; my-program.$(date -I).log
cp post-template.md _posts/$(date -I)-post-slug.md&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;filename-timestamp.html.0.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Using this built-in GNU/Linux tool allows you to &lt;code&gt;touch $(date -I).md&lt;/code&gt; to readily create a
          &lt;code&gt;2020-08-12.md&lt;/code&gt; file.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;I always had to read &lt;code&gt;man date&lt;/code&gt; or search the web over and over, and after doing this
          repeatedly it became clear that both &lt;code&gt;date -I&lt;/code&gt; and &lt;code&gt;date -Is&lt;/code&gt; (&lt;code&gt;s&lt;/code&gt; here
          stands for seconds) are the thing that I’m looking for 95% of the time:&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;listingblock&quot;&gt;
          &lt;div class=&quot;content&quot;&gt;
            &lt;table&gt;
              &lt;tbody&gt;
                &lt;tr&gt;
                  &lt;td&gt;
                    &lt;pre class=&quot;lineno&quot;&gt;&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L1&quot;
     href=&quot;#B2-L1&quot;&gt;1&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L2&quot;
     href=&quot;#B2-L2&quot;&gt;2&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L3&quot;
     href=&quot;#B2-L3&quot;&gt;3&lt;/a&gt;
&lt;a class=&quot;code-line-anchor&quot;
     id=&quot;B2-L4&quot;
     href=&quot;#B2-L4&quot;&gt;4&lt;/a&gt;&lt;/pre&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                    &lt;pre&gt;# inside my-program.sh
echo &quot;Program started at $(date -Is)&quot;
# output is:
# Program started at 2020-08-12T09:04:58-03:00&lt;/pre&gt;
                  &lt;/td&gt;
                &lt;/tr&gt;
              &lt;/tbody&gt;
            &lt;/table&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph plaintext&quot;&gt;
          &lt;p&gt;&lt;a href=&quot;filename-timestamp.html.1.txt&quot;&gt;plaintext&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;paragraph&quot;&gt;
          &lt;p&gt;Both date formats are hierarchical, having the bigger time intervals to the left. This means that you can
          easily sort them (and even tab-complete them) with no extra effort or tool required.&lt;/p&gt;
        &lt;/div&gt;
    </content>
  </entry>
</feed>
