diff options
Diffstat (limited to 'tools/partest-ack')
-rwxr-xr-x | tools/partest-ack | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/tools/partest-ack b/tools/partest-ack new file mode 100755 index 0000000000..f7d5063292 --- /dev/null +++ b/tools/partest-ack @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +# +# wrapper around partest for fine-grained test selection via ack + +declare quiet failed update partest_debug file_regex partest_args ack_args cotouched + +[[ $# -gt 0 ]] || { + cat <<EOM +Usage: $0 <regex> [-dfquvp] [ack options] + + -d pass --debug to partest + -f pass --failed to partest + -q DON'T pass --show-log and --show-diff to partest + -u pass --update-check to partest + -v pass --verbose to partest + -p <path> select tests appearing in commits where <path> was also modified + +Given a regular expression (and optionally, any arguments accepted by ack) +runs all the tests for which any associated file matches the regex. Associated +files include .check and .flags files. Tests in directories will match if any +file matches. A file can match the regex by its contents or by its name. + +You must have ack installed: http://betterthangrep.com/ack-standalone + +Examples: + + > tools/partest-ack monad + % tests-with-matching-paths ... 2 + % tests-with-matching-code ... 2 + # 4 tests to run. + + > tools/partest-ack -p src/library/scala/Enumeration.scala + % tests-modified-in-same-commit ... 84 + # 84 tests to run. + + > tools/partest-ack -f + % tests-which-failed ... 42 + # 42 tests to run. +EOM + + exit 0 +} + +# The leading : in :achs suppresses some errors. Each letter is a valid +# option. If an option takes an argument, a colon follows it, e.g. +# it would be :ach:s if -h took an argument. +while getopts :fuvdp: opt; do + case $opt in + d) partest_debug=true && partest_args="$partest_args --debug" ;; + f) failed=true && partest_args="$partest_args --failed" ;; + p) cotouched="$cotouched $OPTARG" ;; + q) quiet=true ;; + u) partest_args="$partest_args --update-check" ;; + v) partest_args="$partest_args --verbose" ;; + :) echo "Option -$OPTARG requires an argument." >&2 ;; # this case is called for a missing option argument + *) echo "Unrecognized argument $OPTARG" ;; # this is the catch-all implying an unknown option + esac +done + +shift $((OPTIND-1)) +file_regex="$1" +ack_args="$*" + +tests () { + find test/files -mindepth 2 -maxdepth 2 -name '*.scala' -o -type d +} + +pathsToTests () { + for path in $(perl -pe 's#^(test/files/[^/]+/[^/.]+).*$#$1#'); do + if [[ -d "$path" ]]; then + echo "$path" + elif [[ -f "$path.scala" ]]; then + echo "$path.scala" + fi + done | sort -u +} + +tests-with-matching-paths() { + local re="$1" + for p in $(find test/files -type f); do + [[ $p =~ $re ]] && echo "$p" + done +} + +tests-which-failed () { + for f in $(find test/files -name '*.log'); do + echo ${f%-*} + done +} + +tests-modified-in-same-commit() { + [[ $# -gt 0 ]] && \ + for rev in $(git rev-list HEAD -- "$@"); do + git --no-pager show --pretty="format:" --name-only "$rev" -- test/files + done +} + +tests-with-matching-code() { + ack --noenv --text --files-with-matches "$@" -- test/files +} + +countStdout () { + local -i count=0 + while read line; do + printf "$line\n" + count+=1 + done + + printf >&2 " $count\n" +} + +testRun () { + printf >&2 "%% %-30s ... " "$1" + "$@" | pathsToTests | countStdout +} + +allMatches() { + [[ -n $file_regex ]] && testRun tests-with-matching-paths $file_regex + [[ -n $cotouched ]] && testRun tests-modified-in-same-commit $cotouched + [[ -n $ack_args ]] && testRun tests-with-matching-code $ack_args + [[ -n $failed ]] && testRun tests-which-failed +} + +paths=$(allMatches | sort -u) +[[ -n $quiet ]] || partest_args="--show-diff --show-log $partest_args" + +if [[ -z $paths ]] && [[ -z $failed ]]; then + echo >&2 "No matching tests." +else + count=$(echo $(echo "$paths" | wc -w)) + + # Output a command line which will re-run these same tests. + echo "# $count tests to run." + printf "%-52s %s\n" "test/partest $partest_args" "\\" + for path in $paths; do + printf " %-50s %s\n" "$path" "\\" + done + echo ' ""' + + test/partest $partest_args $paths +fi |