2021-11-22 17:54:21 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
2022-05-25 12:10:55 +01:00
|
|
|
set -euo pipefail
|
2021-11-22 17:54:21 +00:00
|
|
|
|
2021-11-23 21:37:59 +00:00
|
|
|
SCRIPT_NAME=$(basename "$0")
|
|
|
|
|
|
|
|
function usage()
|
|
|
|
{
|
|
|
|
cat <<EOF
|
|
|
|
${SCRIPT_NAME}: Generate coverage using grcov.
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
with_coverage [opts] <command> [args...] : Run <command> with [args].
|
|
|
|
with_coverage -i [opts] : Run bash interactively.
|
|
|
|
|
|
|
|
Options:
|
|
|
|
-h: Print this message.
|
|
|
|
-i: Run an interactive shell after the command (if any)
|
2021-11-23 21:48:45 +00:00
|
|
|
-c: Continue using data from previous runs. (By default, data is deleted.)
|
|
|
|
-s: Skip generating a final report.
|
2022-01-27 04:46:45 +00:00
|
|
|
-f <format>: format to use when generating coverage report. one of html (default), ade,
|
|
|
|
lcov, coveralls, coveralls+, files, covdir, or cobertura
|
|
|
|
-o <path>: set the output path for the coverage report (defaiult "coverage")
|
2021-11-23 21:37:59 +00:00
|
|
|
|
|
|
|
Notes:
|
2022-04-07 16:39:57 +01:00
|
|
|
You need to have grcov and llvm-tools-preview installed.
|
2021-11-23 21:37:59 +00:00
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
interactive=no
|
2021-11-23 21:48:45 +00:00
|
|
|
remove_data=yes
|
|
|
|
skip_report=no
|
2022-01-27 04:46:45 +00:00
|
|
|
format=html
|
|
|
|
output=coverage
|
2021-11-23 21:37:59 +00:00
|
|
|
|
2022-01-27 04:46:45 +00:00
|
|
|
while getopts "chisf:o:" opt ; do
|
2021-11-23 21:37:59 +00:00
|
|
|
case "$opt" in
|
2021-11-23 21:48:45 +00:00
|
|
|
c) remove_data=no
|
|
|
|
;;
|
2021-11-23 21:37:59 +00:00
|
|
|
h) usage
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
i) interactive=yes
|
|
|
|
;;
|
2021-11-23 21:48:45 +00:00
|
|
|
s) skip_report=yes
|
|
|
|
;;
|
2022-01-27 04:46:45 +00:00
|
|
|
f) format="$OPTARG"
|
|
|
|
;;
|
|
|
|
o) output="$OPTARG"
|
|
|
|
;;
|
2021-11-23 21:37:59 +00:00
|
|
|
*) echo "Unknown option."
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
# Remove the flags we parsed.
|
|
|
|
shift $((OPTIND-1))
|
|
|
|
|
|
|
|
# Make sure that we'll be doing _something_.
|
|
|
|
if [ $# -eq 0 ] && [ $interactive = "no" ]; then
|
|
|
|
echo "No command specified: Use the -i flag if you want a shell."
|
|
|
|
echo
|
|
|
|
echo "Run ${SCRIPT_NAME} -h for help."
|
|
|
|
exit 1
|
|
|
|
fi
|
2022-04-08 15:19:28 +01:00
|
|
|
default_toolchain=$(rustup show active-toolchain | cut -d' ' -f1)
|
|
|
|
echo "Using toolchain +${RUST_COVERAGE_TOOLCHAIN:=${default_toolchain}}. (Override with \$RUST_COVERAGE_TOOLCHAIN)"
|
2022-04-08 14:46:46 +01:00
|
|
|
|
|
|
|
# Validate that "+${RUST_COVERAGE_TOOLCHAIN}" is installed. This will log a message to stderr
|
|
|
|
# if it isn't.
|
|
|
|
cargo "+${RUST_COVERAGE_TOOLCHAIN}" -h >/dev/null
|
2021-11-23 21:37:59 +00:00
|
|
|
|
|
|
|
# Validate that grcov is installed.
|
2022-01-28 23:12:36 +00:00
|
|
|
if [ "$(command -v grcov 2>/dev/null)" = "" ]; then
|
2021-11-23 21:37:59 +00:00
|
|
|
echo "grcov appears not to be installed. Try 'cargo install grcov'." >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-11-24 17:33:31 +00:00
|
|
|
# Validate that llvm-tools-preview is installed.
|
2022-04-08 14:46:46 +01:00
|
|
|
if [ "$(rustup "+${RUST_COVERAGE_TOOLCHAIN}" component list --installed | grep llvm-tools-preview)" = "" ]; then
|
|
|
|
echo "llvm-tools-preview appears not to be installed. Try 'rustup +${RUST_COVERAGE_TOOLCHAIN} component add llvm-tools-preview'." >&2
|
2021-11-24 17:33:31 +00:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-11-22 17:54:21 +00:00
|
|
|
COVERAGE_BASEDIR=$(git rev-parse --show-toplevel)
|
2022-04-07 16:39:57 +01:00
|
|
|
export RUSTFLAGS="-C instrument-coverage"
|
2021-11-22 17:54:21 +00:00
|
|
|
export LLVM_PROFILE_FILE=$COVERAGE_BASEDIR/coverage_meta/%p-%m.profraw
|
2022-04-08 14:46:46 +01:00
|
|
|
export RUSTUP_TOOLCHAIN="${RUST_COVERAGE_TOOLCHAIN}"
|
2021-11-22 17:54:21 +00:00
|
|
|
|
2022-01-27 17:19:35 +00:00
|
|
|
# Using :? here to ensure that the script exits the path would
|
|
|
|
# otherwise be /
|
|
|
|
if [ -d "${COVERAGE_BASEDIR:?}/${output:?}" ]; then
|
|
|
|
rm -r "${COVERAGE_BASEDIR:?}/${output:?}" || true
|
2021-11-23 21:41:22 +00:00
|
|
|
fi
|
2021-11-23 21:48:45 +00:00
|
|
|
if [ -d "$COVERAGE_BASEDIR/coverage_meta" ] && [ "$remove_data" = "yes" ]; then
|
|
|
|
echo "Removing data from previous runs. (Use -c to suppress this behavior.)"
|
2021-11-23 21:41:22 +00:00
|
|
|
rm -r "$COVERAGE_BASEDIR/coverage_meta" || true
|
|
|
|
fi
|
2021-11-23 21:03:02 +00:00
|
|
|
|
2021-11-23 22:05:53 +00:00
|
|
|
mkdir -p "$COVERAGE_BASEDIR/coverage_meta"
|
2021-11-22 17:54:21 +00:00
|
|
|
|
2021-12-01 17:02:53 +00:00
|
|
|
if [ ! -e "$COVERAGE_BASEDIR/coverage_meta/commands" ] ; then
|
|
|
|
echo "REVISION: $(git rev-parse HEAD) $(git diff --quiet || echo "[dirty]")" > "$COVERAGE_BASEDIR/coverage_meta/commands"
|
|
|
|
fi
|
|
|
|
|
2021-11-23 21:37:59 +00:00
|
|
|
if [ $# -ne 0 ]; then
|
2021-11-23 22:05:53 +00:00
|
|
|
echo "$@" >> "$COVERAGE_BASEDIR/coverage_meta/commands"
|
2021-11-23 21:37:59 +00:00
|
|
|
"$@"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $interactive = "yes" ] ; then
|
|
|
|
echo "Launching a bash shell."
|
|
|
|
echo "Exit this shell when you are ready to genate a coverage report."
|
2021-11-23 22:05:53 +00:00
|
|
|
echo "# BASH SHELL" >> "$COVERAGE_BASEDIR/coverage_meta/commands"
|
2021-11-23 21:37:59 +00:00
|
|
|
# when run interactivelly, don't die on error
|
|
|
|
bash || true
|
2021-11-22 17:54:21 +00:00
|
|
|
fi
|
|
|
|
|
2021-11-23 21:48:45 +00:00
|
|
|
if [ "$skip_report" = "yes" ]; then
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2021-11-23 21:03:02 +00:00
|
|
|
echo "Generating report..."
|
|
|
|
|
2022-01-27 17:09:20 +00:00
|
|
|
grcov "$COVERAGE_BASEDIR/coverage_meta" \
|
|
|
|
--binary-path "$COVERAGE_BASEDIR/target/debug/" \
|
|
|
|
-s "$COVERAGE_BASEDIR/" \
|
|
|
|
-o "$COVERAGE_BASEDIR/$output" \
|
|
|
|
-t "$format" \
|
|
|
|
--branch \
|
|
|
|
--ignore-not-existing \
|
2022-03-24 18:53:53 +00:00
|
|
|
--excl-start '^(pub(\((crate|super)\))? )?mod test' \
|
2022-01-27 17:09:20 +00:00
|
|
|
--excl-stop '^}' \
|
|
|
|
--ignore="*/tests/*" \
|
|
|
|
--ignore="*/examples/*" \
|
2022-02-22 19:41:54 +00:00
|
|
|
--ignore="*/fuzz/*" \
|
2022-01-27 17:14:32 +00:00
|
|
|
--ignore="crates/arti-bench/*" \
|
2022-03-04 20:24:38 +00:00
|
|
|
--ignore="crates/arti-testing/*" \
|
2022-01-27 17:09:20 +00:00
|
|
|
--ignore="*/github.com-1ecc6299db9ec823/*"
|
2022-01-27 04:46:45 +00:00
|
|
|
|
2022-01-28 17:22:48 +00:00
|
|
|
if [ "$format" == cobertura ]; then
|
2022-02-17 18:02:58 +00:00
|
|
|
python3 "$COVERAGE_BASEDIR/maint/postprocess_coverage_cobertura" "$COVERAGE_BASEDIR/$output"
|
2022-01-28 17:22:48 +00:00
|
|
|
echo "Full report: $COVERAGE_BASEDIR/$output"
|
|
|
|
exit
|
|
|
|
elif [ "$format" != html ]; then
|
2022-02-02 18:18:22 +00:00
|
|
|
# no html post processing when outputting non html result
|
2022-01-27 04:46:45 +00:00
|
|
|
echo "Full report: $COVERAGE_BASEDIR/$output"
|
|
|
|
exit
|
|
|
|
fi
|
2021-11-22 17:54:21 +00:00
|
|
|
|
2022-01-27 04:46:45 +00:00
|
|
|
cp "$COVERAGE_BASEDIR/$output/index.html" "$COVERAGE_BASEDIR/$output/index_orig.html"
|
2021-12-01 17:02:53 +00:00
|
|
|
|
2022-01-28 23:12:36 +00:00
|
|
|
if [ "$(command -v python3 2>/dev/null)" = "" ]; then
|
2021-12-01 17:02:53 +00:00
|
|
|
echo "python3 not installed; not post-processing the index file."
|
|
|
|
else
|
|
|
|
echo "Postprocessing..."
|
2022-02-17 18:02:58 +00:00
|
|
|
python3 "$COVERAGE_BASEDIR/maint/postprocess_coverage_html" "$COVERAGE_BASEDIR/coverage_meta/commands" "$COVERAGE_BASEDIR/$output/index.html" "$COVERAGE_BASEDIR/$output/index.html"
|
2021-12-01 17:02:53 +00:00
|
|
|
fi
|
2021-11-23 22:05:53 +00:00
|
|
|
|
2022-01-27 04:46:45 +00:00
|
|
|
echo "Full report: $COVERAGE_BASEDIR/$output/index.html"
|