Skip to content

Instantly share code, notes, and snippets.

@jcbrinfo
Created May 13, 2017 20:33
Show Gist options
  • Select an option

  • Save jcbrinfo/b34848fb511354e31528d79b8d05dd8d to your computer and use it in GitHub Desktop.

Select an option

Save jcbrinfo/b34848fb511354e31528d79b8d05dd8d to your computer and use it in GitHub Desktop.
A thin wrapper over the Nit’s `./tests.sh` script that displays the changes since the last run.
#! /bin/bash
# A thin wrapper over the Nit’s `./tests.sh` script that displays the changes
# since the last run.
#
# Also, recompiles (except when `--no-make` is specified) the invoked engine
# before running the tests.
#
# Synopsis
# --------
# ./what-changed [-h] [-v] [-o <engine option>…] [--autosav] [--node]
# [--no-make] [--noskip] [--compdir <compdir>]
# [--engine <engine>] [--outdir <outdir>] [--] <tests…>
#
# Author
# ------
# * jcbrinfo <[email protected]>
#
# Licensing
# ---------
# Copyright (c) 2017, jcbrinfo <[email protected]>.
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
set -e
out_dir=out
engine_bin=
engine_srcdir=
make_engine=1
tests_options=()
compare_res() {
if [ -f "${out_dir}.bak/$1.res" ] || [ -f "${out_dir}/$1.res" ]; then
if ! cmp -s -- "${out_dir}.bak/$1.res" "${out_dir}/$1.res" > /dev/null 2>&1; then
print_change "$1"
fi
fi
}
print_change() {
printf '\n'
set -- "${out_dir}.bak/$1.res" "${out_dir}/$1.res"
[ -f "$1" ] || set -- /dev/null "$2"
[ -f "$2" ] || set -- "$1" /dev/null
diff -su -- "$@" | colorize_diff \
|| printf '--- %s\n+++ %s\n!!! `diff` failed.\n' "$@" | colorize_diff
}
colorize_diff() {
sed 's/^-/\x1b[31m-/;s/^+/\x1b[32m+/;s/^@/\x1b[34m@/;s/$/\x1b[0m/'
}
run_tests() {
# Save a lot of space wasted by compiled tests.
# Usually exceed the POSIX command length limit. This is why it is executed
# first: If it fails, files can be removed manually before re-launching the
# script.
rm -f "${out_dir}"/*.bin
# Recompile the engine.
if [ "${make_engine}" != 0 ]; then
(cd "${engine_srcdir}" && make -f Makefile.next "${engine_bin}")
fi
# Rotate directories once we know that compilation succeeds.
rm -rf "${out_dir}".bak
mkdir -p "${out_dir}"
mv -T "${out_dir}" "${out_dir}".bak
./tests.sh "${tests_options[@]}" "$@" || true
}
main() {
local engine=nitc
while :; do
case $1 in
-h|-v|--noskip|--node|--autosav)
tests_options=("${tests_options[@]}" "$1")
shift
;;
-o|--compdir)
tests_options=("${tests_options[@]}" "$1" "$2")
shift 2
;;
--engine)
engine="$2"
tests_options=("${tests_options[@]}" "$1" "$2")
shift 2
;;
--outdir)
out_dir="$2"
tests_options=("${tests_options[@]}" "$1" "$2")
shift 2
;;
--no-make)
make_engine=0
shift
;;
--)
shift
break
;;
-*)
printf 'unrecognized option %s\n' "$1" >&2
exit 2
;;
*)
break
;;
esac
done
case $engine in
nitc|nitg|nitcs|nitg-s|nitce|nitg-e|nitcsg|nitg-sg|nitcg|nitg-g|emscripten)
engine_bin=nitc
engine_srcdir=../src
;;
nit|niti|nitvm)
engine_bin=nit
engine_srcdir=../src
;;
nitin)
engine_bin=bin/nitin
engine_srcdir=../contrib/nitin
;;
nitj)
engine_bin=nitj
engine_srcdir=../src
;;
*)
printf 'unknown engine %s\n' "${engine}" >&2
exit 1
;;
esac
run_tests "$@"
echo '---------------------------------------------------------------------------------'
echo 'Here are the changes:'
for test_name in "$@"; do
test_name="${test_name%.nit}"
compare_res "${test_name}"
for alt in "${out_dir}/${test_name}_alt"*.res; do
alt="${alt#*/}"
alt="${alt%.res}"
compare_res "${alt}"
done
for alt_bak_res in "${out_dir}.bak/${test_name}_alt"*.res; do
alt="${alt_bak_res#*/}"
alt="${alt%.res}"
if [ -f "${alt_bak_res}" ] && [ \! -f "${out_dir}/${alt}.res" ]; then
print_change "${alt}"
fi
done
done
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment