zeek/auxil/btest/sphinx/btest-rst-cmd
Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

147 lines
3.5 KiB
Bash
Executable File

#! /usr/bin/env bash
#
# Executes a command and formats the command and its stdout in reST.
#
trap cleanup INT TERM EXIT
function usage() {
echo
echo "$(basename "$0") [options] <command line>"
echo
echo " -d Do not actually execute command; just format the command line."
echo " -h Show this help."
echo " -r <file> Insert <file> into output, rather than stdout."
echo " -o Do not include command into output."
echo " -c <cmd> Show <cmd> in output instead of the one actually executed."
echo " -f <filter> Run <filter> command on command output (or file) before including."
echo " -n <n> Include only n lines of output, adding a [...] marker if there's more."
echo
exit 1
}
function apply_filter() {
eval "$filter_env" | eval "$filter_opt"
}
# Strip leading white-space and then indent to 6 space.
function indent() {
python3 -c "
from __future__ import print_function
import sys
input = sys.stdin.readlines()
n = 1e10
for i in input:
n = min(n, len(i) - len(i.lstrip()))
for i in input:
print(' ' + i[n:], end='')
"
}
function cleanup() {
# shellcheck disable=SC2086
rm -f $tmps
exit
}
stdout=$(mktemp -t "$(basename "$0")".XXXXXX)
cmd_out=$(mktemp -t "$(basename "$0")".XXXXXX)
filter_out=$(mktemp -t "$(basename "$0")".XXXXXX)
tmps="$stdout $cmd_out $filter_out"
include=$cmd_out
show_command=1
cmd_display=""
dry=0
lines=0
filter_env=${BTEST_RST_FILTER}
while getopts "odhr:f:c:n:" opt; do
case $opt in
h) usage ;;
o) show_command=0 ;;
r) include=$OPTARG ;;
d)
dry=1
include=""
;;
c) cmd_display=$OPTARG ;;
f) filter_opt=$OPTARG ;;
n) lines=$OPTARG ;;
*) exit 1 ;;
esac
done
shift $((OPTIND - 1))
cmd=$*
test "$cmd_display" == "" && cmd_display=$cmd
test "$filter_opt" == "" && filter_opt="cat"
test "$filter_env" == "" && filter_env="cat"
test "$cmd" == "" && usage
if [ "$dry" != "1" ]; then
if ! eval "$cmd" >"$cmd_out"; then
exit 1
fi
fi
# Generate reST output.
if [ "$show_command" == "1" ]; then
{
echo ".. rst-class:: btest-cmd"
echo
echo " .. code-block:: none"
echo " :linenos:"
echo " :emphasize-lines: 1,1"
echo
echo " # $cmd_display" | apply_filter
} >>"$stdout"
else
{
echo ".. rst-class:: btest-include"
echo
echo " .. code-block:: guess"
echo " :linenos:"
echo
} >>"$stdout"
fi
for i in $include; do
echo " $(basename "$i")" >>"$filter_out"
echo "" >>"$filter_out"
cat "$i" | apply_filter | indent >"$filter_out"
if [ "$lines" = 0 ]; then
cat "$filter_out" >>"$stdout"
else
cat "$filter_out" | head -n "$lines" >>"$stdout"
if [ "$(wc -l <"$filter_out")" -gt "$lines" ]; then
echo ' [...]' >>"$stdout"
fi
fi
rm -f "$filter_out"
done
echo >>"$stdout"
# Branch depending on where this script was started from.
if [ "$BTEST_RST_OUTPUT" != "" ]; then
# Running from inside Sphinx, just output to where it tells us.
cat "$stdout" >>"${BTEST_RST_OUTPUT}#${TEST_PART}"
elif [ "$TEST_NAME" ]; then
# Running from inside BTest, output into file that btest-diff-rst will pickup.
cat "$stdout" >>"btest-${TEST_NAME}#${TEST_PART}"
else
# Running from command line, just print out.
cat "$stdout"
fi