From 926c117955d2ed0c02ca56c58bd4506c20b12038 Mon Sep 17 00:00:00 2001 From: Ilya Grigoriev Date: Mon, 28 Aug 2023 20:57:26 -0700 Subject: [PATCH] demos: run scripts in a fixed environment and record with term-transcript Currently, there is no way provided to merely run scripts in a fixed environment (without recording). Short-term TODOs (done in descendant commits): - Fix the terminal width - Document the script --- demos/run_scripts.sh | 59 ++++++++++++++++++++++++++++++++++ demos/setup_standard_config.sh | 27 ++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100755 demos/run_scripts.sh create mode 100644 demos/setup_standard_config.sh diff --git a/demos/run_scripts.sh b/demos/run_scripts.sh new file mode 100755 index 000000000..7c7538b61 --- /dev/null +++ b/demos/run_scripts.sh @@ -0,0 +1,59 @@ +#!/bin/bash +set -euo pipefail +. "$(dirname "$0")"/setup_standard_config.sh + +# NOTE ON TOOLS: the only two nice tools I'm aware of that support our use-case +# (non-animated svgs) are https://github.com/slowli/term-transcript and +# https://github.com/FHPythonUtils/AnsiToImg. They have slightly different +# limitations and advantages. If one of them stops being developed, we could +# look at the other one. +# +# AnsiToImg can also generate PNGs, but that is currently harder to setup than +# `convert`. `convert` supports different backends. I do not completely +# understand them. On Debian, it did not work well without `sudo apt install +# inkscape`. It's unclear to me whether `convert` used Inkscape or one of its +# dependencies. Inkscape can be also used manually for SVG -> PNG conversion. +which term-transcript > /dev/null \ + || (echo '`term-transcipt` must be installed with e.g.'\ + '`cargo binstall term-transcript-cli`.' \ + 'See also https://github.com/slowli/term-transcript' >&2; + false) +which convert > /dev/null \ + || echo '`convert` from ImageMagick needs to be installed to create pngs.' \ + 'Only svgs will be created.' >&2 + +echo "jj --version: (set PATH to change)" +jj --version + +run_script_through_term_transcript_and_pipe_result_to_stderr() { + script="$1" + script_base="${script%.sh}" + script_base="${script_base#demo_}" + outfile=$(mktemp --tmpdir "$script_base"-output-XXXX.ansi) + # We use `term-transcript capture` instead of `term-transcript exec` so that + # we can show the output of the script via `tee`. + (bash "$script" || (echo "SCRIPT FAILED WITH EXIT CODE $?"; false)) 2>&1 | \ + tee "$outfile" + term-transcript capture \ + --no-inputs --pure-svg --palette powershell \ + --out "$script_base".svg "$script_base" \ + < "$outfile" + rm "$outfile" +} + +for script in "$@"; do + run_script_through_term_transcript_and_pipe_result_to_stderr "$script" 2>&1 + # By default, 1 SVG unit becomes 1 pixel. The term-transcript output + # defaults to 720 SVG units width. + # + # `-background black` is important because the SVGs use transparency to make + # rounded corners, and the transparent portion becomes white by default. + # TODO(ilyagr): Figure out if `convert` can make PNGs have transparency. + # + # `-resize 100%` is a no-op. `-resize 700x10000`` would make the width 700 px + # and preserve aspect ratio. + which convert > /dev/null \ + && convert -colors 63 -background black -resize 100% \ + "$script_base".svg "$script_base".png \ + || true +done diff --git a/demos/setup_standard_config.sh b/demos/setup_standard_config.sh new file mode 100644 index 000000000..59ae2f13b --- /dev/null +++ b/demos/setup_standard_config.sh @@ -0,0 +1,27 @@ +# This script is meant to be run with `source` from a fresh bash +# shell. Thus no shebang. +# shellcheck shell=bash +set -euo pipefail + +JJ_CONFIG=$(mktemp --tmpdir jjconfig-XXXX.toml) +export JJ_CONFIG +cat <<'EOF' > "$JJ_CONFIG" +[user] +name = "JJ Fan" +email = "jjfan@example.com" + +[operation] +hostname = "jujube" +username = "jjfan" + +[ui] +color="always" +paginate="never" +EOF + +GIT_CONFIG_GLOBAL=$(mktemp --tmpdir gitconfig-XXXX) +export GIT_CONFIG_GLOBAL +cat <<'EOF' > "$GIT_CONFIG_GLOBAL" +[color] +ui=always +EOF