Skip to content

Instantly share code, notes, and snippets.

@vhoyer
Last active June 30, 2021 17:23
Show Gist options
  • Save vhoyer/1a6a7ccc1e901cb0cba269017311ec39 to your computer and use it in GitHub Desktop.
Save vhoyer/1a6a7ccc1e901cb0cba269017311ec39 to your computer and use it in GitHub Desktop.
Overly complex script to run coverage only on changed files from one branch to another (defaults to the master).

Run branch coverage

Overly complex script to run coverage only on changed files from one branch to another (defaults to the master). This makes you only run tests that are different on the current branch compared to another branch, and this only runs coverage for the files that changed also. Bear in mind that this is also overly specific to the project I was working on and it's subfolders and file structure. That said, even if it does not work for you first try (which will probably not), it should serve as a good kick start.

#!/bin/sh
PRGNAME="$(basename $0)"
# BEGIN PARAMETERS
_open_browser="--open-browser"
o="-o"
_watch="--watch"
w="-w"
_branch="--branch"
b="-b"
_verbose="--verbose"
# END PARAMETERS
SHORTHELP="usage: $PRGNAME [options]
for a detailed list of options, use: \`$PRGNAME --help\`
"
HELPMSG="if you run $PRGNAME with no options it will display run the default
action.
-h short help message
--help display this message
$o,$_open_browser
run $PRGNAME opening the coverage report on browser afterwards
$w,$_watch re-run $PRGNAME whenever files change
$b,$_branch [one parameter is required] change the branch to compare to, default: master
$_verbose output more log for debug purposes
"
throwError() {
COLOR_RED="\033[0;31m"
echo "${COLOR_RED}$1"
exit 1
}
defaultAction() {
# Process and validate arguments
while [ -n "$1" ]; do
case "$1" in
# Open browser after done with the coverage
$o|$_open_browser) DO_OPEN_BROWSER=1 ;;
# Watch for file change and run coverage again
$w|$_watch) DO_WATCH=1 ;;
# Be verbose with the log
$_verbose) DO_VERBOSE=1 ;;
# Choose another branch other than master
$b|$_branch)
# If there is a next parameter move to next argument
[ -n "$2" ] && shift || throwError "Parameter \"$1\" needs one argument"
case "$1" in
# if it begins with a dash throw
-*) throwError "Invalid value \"$1\", expected a branch, got another parameter" ;;
*) BRANCH=$1 ;;
esac ;;
*) throwError "Invalid Option \"$1\", run \`$PRGNAME --help\` to see a full list of valid parameters" ;;
esac
shift
done
[ $DO_WATCH ] &&
clear
# Make sure the script is executed from project's root always
cd $(dirname $(realpath "$0"))/..
#
# Actual logic
#
git diff ${BRANCH:-master} --name-only -- | # Get only the file names from diff
sed -e '/^[^/]*$/d' | # Ignore root level file changes
sed -e '/^ci\//d' | # Ignore ci/ folder
sed -e '/^helm\//d' | # Ignore helm/ folder
sed -e '/^scripts\//d' | # Ignore scripts/ folder
sed -e '/^.*\.json$/d' | # Ignore *.json files
sed -e 's/^test\///' | # remove test prefix to test the real file
uniq >/tmp/difffilenames
if ! grep -qe "." /tmp/difffilenames; then
throwError "Error, no diff detected between ${BRANCH:-master} and current one"
fi
COLLECT_COVERAGE_FROM="{`cat /tmp/difffilenames |
tr '\n' ',' | sed -e 's/,$//' `}" # join every line with a comma (',')
TEST_PATH_PATTERN="(`cat /tmp/difffilenames |
sed -e 's/\(\/[^./]*\)\..*/\1/' | # remove every extension
sed -e 's/\(systems\/[^/]*\|src\)\///g' | # remove system and src prefix to run test for all systems
sed -e 's/\/__snapshots__//g' | # when snapshot is altered, run the test for it
sed -e 's/\/index//g' | # when index is altered, run tests for the hole folder
sed -e 's/config\/router\/[^/]*$/config\/router/g' | # Any file on config/router/ must run the config/router.test.js
tr '\n' '\|' | sed -e 's/|$//' `)" # join every line with a pipe ('|') to RegEx "OR"
echo "Running tests..."
[ $DO_VERBOSE ] && echo "\n\n\$TEST_PATH_PATTERN:\n\n`
echo $TEST_PATH_PATTERN |
tr '|' '\n' |
sed -e 's/^(\|)$//'
`\n\n\n\$COLLECT_COVERAGE_FROM:\n\n`
echo $COLLECT_COVERAGE_FROM |
tr ',' '\n' |
sed -e 's/^{\|}$//'`"
npm run test --silent -- \
--coverage \
--collectCoverageFrom=$COLLECT_COVERAGE_FROM \
--testPathPattern=$TEST_PATH_PATTERN
[ $DO_OPEN_BROWSER ] &&
xdg-open ./test/_coverage/index.html &&
unset DO_OPEN_BROWSER # Prevent opening of browser when watch repeats this command
[ $DO_WATCH ] &&
unset DO_WATCH && # Prevent endless recursion
watchFilesystemChange
}
watchFilesystemChange() {
# Make sure the script is executed from project's root always
cd $(dirname $(realpath "$0"))/..
local msg="\n\nWaiting for file changes to run command again, to cancel this behavior press CTRL-C\n\n"
echo $msg
chksum1=`chksumGenerate`;
while [ true ]; do
chksum2=`chksumGenerate`;
if [ "$chksum1" != "$chksum2" ]; then
clear
defaultAction
echo $msg
chksum1=`chksumGenerate`;
fi
sleep 0.2
done
}
chksumGenerate() {
echo `find . \
-not -path "./.git/*" \
-not -path "./.nuxt/*" \
-not -path "./node_modules/*" \
-type f -printf "%T@ %p\n" |
md5sum |
cut -d " " -f 1`
}
case "$1" in
# you can insert your own options here to do stuff
"--help")
printf "%s" "$HELPMSG"
;;
"-h")
printf "%s" "$SHORTHELP"
;;
*)
defaultAction $@
;;
esac
# vim:ts=8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment