Nix with faketty

faketty nix --print-build-logs --log-format raw-with-logs [...] 2> >(cat -A >&2) on a Github Action Runner zsh / bash * gives:

^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[K^M^[[0m^[[Kunpacking sources^M$
  unpacking source archive /nix/store/bbjx2a6vkjq0rpk4ain1v0zpyhswqkhg-incl^M$

What’s going on here?!?

^M in there is a carriage return made visible by cat -A.

The problem hence is 253 new lines in this particular case, just to end up printing:

unpacking sources
  unpacking source archive /nix/store/bbjx2a6vkjq0rpk4ain1v0zpyhswqkhg-incl

:cry:

nix-2.16.1 - faketty 1.0.12

* zsh / bash on my local machine seem to handle the noise gracefully, while Github Action Runners just print newlines.

The workaround that I’ve found. It’s aweful:

faketty nix build \
  --print-build-logs \
  --log-format raw-with-logs \
  --eval-store auto \
  --max-jobs 2 \
  "$actionDrv^out" \
    1> /dev/null \
    2> >(sed $'s/\r\033\[0m\033\[K//g'| sed '
      # match lines starting with copying
      /^copying .*/ {
        # write them to ./copylogs
        w ./copylogs
        # delete them from the stream
        d
      }
    ' >&2)

Consider piping it through tee

I thought about tee as well, but couldn’t find a way to switch the stream based on stream matches. This sed implementation acts like a switch which redirects log lines on match to a file (but not to stdout).