Load another .envrc with direnv

June 16, 2023 - Tags: direnv, shell

A small snippet to source an additional env file with direnv:

source_env_if_exists .envrc.private
env_vars_required FOO BAR

where .envrc.private contains the environment variables:

export FOO=foo
export BAR=bar

The additional env_vars_required log an error for every variable that is not present.

lnav

October 21, 2021 - Tags: linux, shell

lnav is a useful tool to analyze multiple logfiles simultaneously. You can just use:

lnav log1 log2

to open the logs. Some important shortcuts are:

Key Description
? help menu
h, j, k, l vim-like movement
space/backspace page forward/backward
TAB file/filter menu
: Command prompt
; SQL queries

Traffic control with tc

October 12, 2021 - Tags: linux

tc (traffic control) is a great tool to “show / manipulate traffic settings” in the Linux kernel. With the qdisc command it’s e.g. possible to introduce delays:

tc qdisc add dev eth0 root netem delay 200ms # exact delay
tc qdisc change dev eth0 root netem delay 200ms 20ms # 20ms uniform variation
tc qdisc change dev eth0 root netem delay 200ms 20ms 20% # 20ms uniform variation with correlation

errors:

tc qdisc change dev eth0 root netem corrupt 1%

loss:

tc qdisc add dev eth0 root netem loss 1%

and duplicates:

tc qdisc change dev eth0 root netem duplicate 1%

To view the current settings use:

tc qdisc show # all devices
tc qdisc show dev eth0 # a specific device

To delete rules use:

tc qdisc del dev eth0 root

Match quoted strings with regular expressions

October 11, 2021 - Tags: python, re

The following regular expression is handy to match quoted strings that may contain escaped quotes:

import re

r = re.compile(r'"(?:(?!(?<!\\)\").)*"')

Here (?<!\\)\" matches a quote which is not preceded by a backslash (i.e. an unescaped quote). So (?!(?<!\\)\") is a lookahead which ensures that the next character is not an unescaped quote.

Unions of TypedDicts

October 10, 2021 - Tags: python, mypy

At runtime TypedDicts are only plain dictionaries. I.e. it is not possible to distinguish a Union of TypedDicts with isinstance. If you want to distinguish Unions of TypedDicts, it is recommended to use the tagged union pattern:

from typing import Literal, TypedDict, Union

class A(TypedDict):
    tag: Literal["A"]
    a: int
    
class B(TypedDict):
    tag: Literal["B"]
    b: str
    
TDs = Union[A, B]

def match(t: TDs) -> None:
    if t["tag"] == "A":
        print(t["a"])
    else:
        print(t["b"])

In existing code bases which use a lot of dicts a Union of TypedDicts may appear when types are introduced. The question is then if it is possible to introduce an additional field or if you have to silence the error temporarily until the code is cleaned up.

Hakyll snapshots for a complete post listing

October 9, 2021 - Tags: haskell, hakyll

On my Hakyll page I wanted to have the complete first 10 posts on the index page. Because I did not know what I was looking for, it took me a while to find it in the tutorial for RSS feeds. The trick is to save a snapshot before Hakyll introduces the default template:

  match "posts/*" $ do
    route $ setExtension "html"
    compile $
      pandocCompiler
        >>= loadAndApplyTemplate "templates/post.html" postCtx
        >>= saveSnapshot "content"
        >>= loadAndApplyTemplate "templates/default.html" postCtx
        >>= relativizeUrls

After that it’s easy to load the snapshots on the target for the index page:

match "index.html" $ do
  route idRoute
  compile $ do
    posts <- fmap (take 10) $ recentFirst =<< loadAllSnapshots "posts/*" "content"
    let ctx =
          listField "posts" postCtx (return posts)
            <> constField "title" "Home"
            <> defaultContext
    getResourceBody
      >>= applyAsTemplate ctx
      >>= loadAndApplyTemplate "templates/default.html" ctx
      >>= relativizeUrls

If you don’t use snapshots, not only the content of the post, but the complete page is pasted again, which was the case in my first, naive attempt.