Skip to content

Instantly share code, notes, and snippets.

@kujenga
Last active July 3, 2017 14:52
Show Gist options
  • Save kujenga/e63def21f7a727933991 to your computer and use it in GitHub Desktop.
Save kujenga/e63def21f7a727933991 to your computer and use it in GitHub Desktop.
Coverage profile generation for Go on Circle CI utilizing classic app engine
#!/usr/bin/env bash
#
# Generate test coverage statistics for Go packages.
#
# Works around the fact that `go test -coverprofile` currently does not work
# with multiple packages, see https://code.google.com/p/go/issues/detail?id=6909
#
# largely based on the below links with a few small changes
# to support classic google appengine
#
# http://mlafeldt.github.io/blog/test-coverage-in-go/
# https://github.com/mlafeldt/chef-runner/blob/v0.7.0/script/coverage
#
# Usage: script/coverage [--html|--coveralls] [test args..]
#
# --html Additionally create HTML report and open it in browser
# --coveralls Push coverage statistics to coveralls.io
#
set -e
workdir=.cover
profile="$workdir/cover.out"
mode=count
# current branch of the repository, used if the environment variable is not set
git_branch=$(git symbolic-ref --short HEAD)
generate_cover_data() {
rm -rf "$workdir"
mkdir "$workdir"
pkgs=''
if hash goapp 2>/dev/null; then
pkgs=$(goapp list $(glide nv))
else
pkgs=$(go list $(glide nv))
fi
for pkg in $pkgs; do
# skip if there are no *_test.go files
stat "$GOPATH/src/$pkg/"*_test.go > /dev/null 2>&1 || { echo "SKIP $pkg [no test files]"; continue; }
echo "TEST $pkg"
f="$workdir/$(echo "$pkg" | tr / -).cover"
if hash goapp 2>/dev/null; then
# use goapp if it is present
time goapp test -v -covermode="$mode" -coverprofile="$f" "$@" "$pkg"
else
time go test -v -covermode="$mode" -coverprofile="$f" "$@" "$pkg"
fi
done
echo "mode: $mode" >"$profile"
grep -h -v "^mode:" "$workdir"/*.cover >>"$profile"
}
show_cover_report() {
go tool cover -"${1}"="$profile"
}
push_to_coveralls() {
echo "Pushing coverage statistics to coveralls.io"
# specify git branch based on the environment in case
# allow for either COVERALLS_TOKEN and COVERALLS_REPO_TOKEN to be used
coveralls_token=${COVERALLS_TOKEN:-$COVERALLS_REPO_TOKEN}
GIT_BRANCH=${CIRCLE_BRANCH:-$git_branch} goveralls \
-coverprofile="$profile" \
-service=circleci \
-repotoken "$coveralls_token"
}
# increase file handle limit for appengine
ulimit -n 2048
flag=$1
shift
generate_cover_data "$@"
show_cover_report func
case "$flag" in
"")
;;
--html)
show_cover_report html ;;
--coveralls)
push_to_coveralls || echo "push to coveralls failed" ;;
*)
echo >&2 "error: invalid option: $1"; exit 1 ;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment