#!/bin/bash set -e SCRIPT_NAME=$(basename "$0") function usage() { cat < [args...] : Run with [args]. with_coverage -i [opts] : Run bash interactively. Options: -h: Print this message. -i: Run an interactive shell after the command (if any) -c: Continue using data from previous runs. (By default, data is deleted.) -s: Skip generating a final report. Notes: You need to have grcov, rust-nightly, and llvm-tools-preview installed. EOF } interactive=no remove_data=yes skip_report=no while getopts "chis" opt ; do case "$opt" in c) remove_data=no ;; h) usage exit 0 ;; i) interactive=yes ;; s) skip_report=yes ;; *) 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 # Validate that +nightly is installed. This will log a message to stderr # if it isn't. cargo +nightly -h >/dev/null # Validate that grcov is installed. if [ "$(which grcov 2>/dev/null)" = "" ]; then echo "grcov appears not to be installed. Try 'cargo install grcov'." >&2 exit 1 fi # Validate that llvm-tools-preview is installed. if [ "$(rustup +nightly component list --installed | grep llvm-tools-preview)" = "" ]; then echo "llvm-tools-preview appears not to be installed. Try 'rustup +nightly component add llvm-tools-preview'." >&2 exit 1 fi COVERAGE_BASEDIR=$(git rev-parse --show-toplevel) export RUSTFLAGS="-Z instrument-coverage" export LLVM_PROFILE_FILE=$COVERAGE_BASEDIR/coverage_meta/%p-%m.profraw export RUSTUP_TOOLCHAIN=nightly if [ -d "$COVERAGE_BASEDIR/coverage" ]; then rm -r "$COVERAGE_BASEDIR/coverage" || true fi if [ -d "$COVERAGE_BASEDIR/coverage_meta" ] && [ "$remove_data" = "yes" ]; then echo "Removing data from previous runs. (Use -c to suppress this behavior.)" rm -r "$COVERAGE_BASEDIR/coverage_meta" || true fi mkdir -p "$COVERAGE_BASEDIR/coverage" mkdir -p "$COVERAGE_BASEDIR/coverage_meta" if [ $# -ne 0 ]; then echo "$@" >> "$COVERAGE_BASEDIR/coverage_meta/commands" "$@" fi if [ $interactive = "yes" ] ; then echo "Launching a bash shell." echo "Exit this shell when you are ready to genate a coverage report." echo "# BASH SHELL" >> "$COVERAGE_BASEDIR/coverage_meta/commands" # when run interactivelly, don't die on error bash || true fi if [ "$skip_report" = "yes" ]; then exit 0 fi echo "Generating report..." grcov "$COVERAGE_BASEDIR/coverage_meta" --binary-path "$COVERAGE_BASEDIR/target/debug/" \ -s "$COVERAGE_BASEDIR/crates/" -o "$COVERAGE_BASEDIR/coverage" -t html --branch \ --ignore-not-existing --excl-start '^mod test' --excl-stop '^}' \ --ignore="*/tests/*" --ignore="*/examples/*" # Extract coverage information and print it to the command line. awk '{if (match($0, /

([^<]*)<\/p>/)) { last_match=substr($0, RSTART+19, RLENGTH-23) } else if (last_match != "" && match($0, /[0-9]*(\.[0-9]*)? %/)) { pct = substr($0, RSTART, RLENGTH) print last_match " " pct last_match="" }}' "$COVERAGE_BASEDIR/coverage/index.html" # Insert the command log and git revision in index.html ed "$COVERAGE_BASEDIR/coverage/index.html" </dev/null /class=.level/ - a

REVISION: $(git rev-parse HEAD) $(git diff --quiet || echo "[dirty]")
$(cat "$COVERAGE_BASEDIR/coverage_meta/commands")
. wq EOF echo "Full report: $COVERAGE_BASEDIR/coverage/index.html"