This repository has been archived on 2024-05-26. You can view files and clone it, but cannot push or open issues or pull requests.
trixy/scripts/tests.sh

247 lines
6.5 KiB
Bash
Executable File

#! /usr/bin/env sh
# Copyright (C) 2023 - 2024:
# The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# This file is part of the Trixy crate for Trinitrix.
#
# Trixy is free software: you can redistribute it and/or modify
# it under the terms of the Lesser GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# and the Lesser GNU General Public License along with this program.
# If not, see <https://www.gnu.org/licenses/>.
# Parts of a shell library {{{
die() {
error "$1"
if [ -n "$2" ]; then
exit "$2"
else
exit 1
fi
}
print() {
# The direct usage is intended as `print` is rather lowlevel
# shellcheck disable=2059
printf "$*"
}
println() {
# The direct usage is intended as `println` is rather lowlevel
# shellcheck disable=2059
printf "$*\n"
}
eprint() {
>&2 print "$@"
}
eprintln() {
>&2 println "$@"
}
if [ -n "$NO_COLOR" ]; then
error() {
eprintln "==> ERROR:" "$*"
}
warning() {
eprintln "==> WARNING:" "$*"
}
debug() {
[ -n "$SHELL_LIBRARY_DEBUG" ] && eprintln "==> [Debug:]" "$*"
}
debug2() {
[ -n "$SHELL_LIBRARY_DEBUG" ] && eprintln " -> [Debug:]" "$*"
}
msg() {
eprintln "==>" "$*"
}
msg2() {
eprintln " ->" "$*"
}
prompt() {
eprint "..>" "$*"
}
else
# See https://stackoverflow.com/a/33206814 for ansi codes
error() {
eprintln "\033[1;91m==> ERROR:\033[0m" "\033[1;93m$*\033[0m"
}
warning() {
eprintln "\033[1;91m==> WARNING:\033[0m" "\033[1;93m$*\033[0m"
}
debug() {
[ -n "$SHELL_LIBRARY_DEBUG" ] && eprintln "\033[1;94m==> [Debug:]\033[0m" "\033[1;93m$*\033[0m"
}
debug2() {
[ -n "$SHELL_LIBRARY_DEBUG" ] && eprintln "\033[1;94m -> [Debug:]\033[0m" "\033[1;93m$*\033[0m"
}
msg() {
eprintln "\033[1;96m==>\033[0m" "\033[1;93m$*\033[0m"
}
msg2() {
eprintln "\033[1;96m ->\033[0m" "\033[1;93m$*\033[0m"
}
prompt() {
eprint "\033[1;96m..>\033[0m" "\033[1;93m$*\033[0m"
}
fi
mktmp() {
ensure_tmp_dir
mktemp -p "$SHELL_LIBRARY_TEMP_PREFIX_DIR"
}
ensure_tmp_dir() {
if ! [ -d "$SHELL_LIBRARY_TEMP_PREFIX_DIR" ]; then
SHELL_LIBRARY_TEMP_PREFIX_DIR="$(mktemp -d)"
fi
}
# A new version of tmp, which allows you to specify the commandline args as normal
# arguments
tmp() {
if echo "$1" | grep -E ' ' -q; then
warn "Detected an old version of tmp, as there are spaces in the input string!"
fi
TEMP_DIR_WITH_DEL="$(mktmp)"
"$@" 1>"$TEMP_DIR_WITH_DEL"
echo "$TEMP_DIR_WITH_DEL"
}
# Takes a path to search as argument.
# Also takes further arguments as names to search for.
# Prints the path to a file, if a file matching the given name is found.
search_dir_for_file() {
[ -d "$1" ] || die "Arg $1 is not a directory"
directory="$1" && shift 1
while read -r dir_entry; do
dir_entry_count=$((dir_entry_count + 1))
dir_entry_basename="$(basename "$dir_entry")"
for name in "$@"; do
if [ "$name" = "$dir_entry_basename" ]; then
println "$dir_entry"
fi
done
done <"$(tmp fd . "$directory" --type file --max-depth 1)"
print ""
}
# Returns the path to the directory which contains all the specified files:
# `search_upward_files file1 file2 file3` returns a path containing file1 ...
search_upward_files() {
directory="$(pwd)"
final_directory=""
output="$(mktmp)"
while [ "$(wc -l <"$output")" = 0 ]; do
search_dir_for_file "$directory" "$@" >"$output"
directory="$(dirname "$directory")"
if [ "$directory" = "/" ]; then
warning "We bailed out, as there seems to be no directory containing $*"
final_directory=""
return
fi
done
final_directory="$(dirname "$(head -n1 "$output")")"
print "$final_directory"
}
# }}}
help() {
cat <<EOF
A test manager (for trixy integration tests)
USAGE:
./scripts/tests [OPTIONS] COMMAND
OPTIONS:
--help | -h
Display this help and exit.
COMMANDS:
update [TESTNAME]
Updates the 'expected.md' file of a test with TESTNAME, if
TESTNAME is blank, all tests are updated.
new TESTNAME
Generates a new test from the '.template' directory and drops
you into an editor for the 'input.tri' file.
It will also generate the 'expected.md' file, after you close
the editor.
ARGUMENTS:
TESTNAME | *([a-zA-Z0-9]) := [[ false ]]
The name of a test.
(The notation above is only really useful, when
the shell library is employed to generate
a completion script.)
EOF
}
ROOT_DIR="$(search_upward_files "Cargo.toml")"
new() {
test_name="$1"
test_dir="$ROOT_DIR/tests/$test_name"
[ -d "$test_dir" ] && die "$test_dir already exists, refusing to override"
cp --recursive "$ROOT_DIR/tests/.template" "$test_dir"
sed --in-place "s|template|$test_name|g" "$test_dir/main.rs"
editor="${EDITOR:-$VI}"
"$editor" "$test_dir/input.tri"
update "$test_name"
}
update() {
test_name="$1"
test_dir="$ROOT_DIR/tests/$test_name"
if [ -n "$test_name" ]; then
cargo run --features build-binary -- \
"$test_dir/input.tri" generate all --no-vendored \
>"$test_dir/expected.md"
else
fd . "$ROOT_DIR/tests" --type directory --max-depth=1 --exec basename | while read -r dir; do
msg2 "Updating $dir.."
update "$dir"
done
fi
}
for arg in "$@"; do
case "$arg" in
"--help" | "-h")
help
exit 0
;;
esac
done
case "$1" in
"update")
shift 1
[ -n "$1" ] && test_name="$1"
update "$test_name"
;;
"new")
shift 1
test_name="$1"
[ -z "$test_name" ] && die "You must specify a TESTNAME"
new "$test_name"
;;
esac
# vim: ft=sh