Created
January 28, 2021 01:32
-
-
Save PhrozenByte/0b10e0dbe4245b38f8ebcd4b17528133 to your computer and use it in GitHub Desktop.
Creates a coverage.svg badge from a clover.xml.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# coverage-badge.sh - Creates a coverage.svg badge from a clover.xml. | |
# | |
# Copyright (C) 2021 Daniel Rudolf (<https://www.daniel-rudolf.de>) | |
# License: The MIT License <http://opensource.org/licenses/MIT> | |
# | |
# SPDX-License-Identifier: MIT | |
function print_usage { | |
echo "Usage:" | |
echo " $(basename "$0") [CLOVER_XML] [BADGE_PATH]" | |
} | |
CLOVER_XML="" | |
BADGE_PATH="" | |
while [ $# -gt 0 ]; do | |
if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then | |
print_usage | |
echo | |
echo "Arguments:" | |
echo " CLOVER_XML path to coverage file to read from (defaults to 'clover.xml')" | |
echo " BADGE_PATH path to write coverage badge to (defaults to 'coverage.svg')" | |
echo | |
echo "Help options:" | |
echo " -h, --help display this help and exit" | |
echo " --version output version information and exit" | |
exit 0 | |
elif [ "$1" == "--version" ]; then | |
echo "coverage-badge.sh 1.0 (build 20210126)" | |
echo "Copyright (C) 2021 Daniel Rudolf" | |
echo "License: The MIT License <http://opensource.org/licenses/MIT>." | |
echo | |
echo "Written by Daniel Rudolf <https://www.daniel-rudolf.de/>" | |
echo "See also: <https://www.daniel-rudolf.de/oss/coverage-badge>" | |
exit 0 | |
elif [ -z "$CLOVER_XML" ]; then | |
CLOVER_XML="$1" | |
shift | |
elif [ -z "$BADGE_PATH" ]; then | |
BADGE_PATH="$1" | |
shift | |
elif [ "$1" != "--" ]; then | |
echo "Unknown option: $1" >&2 | |
exit 1 | |
fi | |
done | |
if [ -z "$(which xmllint)" ]; then | |
echo "Missing required dependency: xmllint" >&2 | |
exit 1 | |
fi | |
if [ -z "$CLOVER_XML" ] && [ ! -e "clover.xml" ]; then | |
print_usage >&2 | |
exit 1 | |
fi | |
CLOVER_XML="${CLOVER_XML:-clover.xml}" | |
if [ ! -e "$CLOVER_XML" ]; then | |
echo "Unable to read coverage from '$CLOVER_XML': No such file or directory" >&2 | |
exit 1 | |
elif [ ! -f "$CLOVER_XML" ]; then | |
echo "Unable to read coverage from '$CLOVER_XML': Not a file" >&2 | |
exit 1 | |
elif [ ! -r "$CLOVER_XML" ]; then | |
echo "Unable to read coverage from '$CLOVER_XML': Permission denied" >&2 | |
exit 1 | |
fi | |
BADGE_PATH="${BADGE_PATH:-coverage.svg}" | |
if [ -e "$BADGE_PATH" ]; then | |
if [ ! -f "$BADGE_PATH" ]; then | |
echo "Unable to write badge to '$BADGE_PATH': Already exists" >&2 | |
exit 1 | |
elif [ ! -w "$BADGE_PATH" ]; then | |
echo "Unable to write badge to '$BADGE_PATH': Permission denied" >&2 | |
exit 1 | |
fi | |
elif [ ! -d "$(dirname "$BADGE_PATH")" ]; then | |
echo "Unable to write badge to '$BADGE_PATH': Invalid path" >&2 | |
exit 1 | |
elif [ ! -w "$(dirname "$BADGE_PATH")" ] || [ ! -x "$(dirname "$BADGE_PATH")" ]; then | |
echo "Unable to write badge to '$BADGE_PATH': Permission denied" >&2 | |
exit 1 | |
fi | |
BADGE_TEMPLATE=' | |
<svg xmlns="http://www.w3.org/2000/svg" width="104" height="20" role="img" aria-label="coverage: {1}"> | |
<title>coverage: {1}</title> | |
<linearGradient id="s" x2="0" y2="100%"> | |
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/> | |
<stop offset="1" stop-opacity=".1"/> | |
</linearGradient> | |
<clipPath id="r"> | |
<rect width="104" height="20" rx="3" fill="#fff"/> | |
</clipPath> | |
<g clip-path="url(#r)"> | |
<rect width="61" height="20" fill="#555"/> | |
<rect x="61" width="43" height="20" fill="{1}"/> | |
<rect width="104" height="20" fill="url(#s)"/> | |
</g> | |
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"> | |
<text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text> | |
<text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text> | |
<text aria-hidden="true" x="815" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="{2}">{0}</text> | |
<text x="815" y="140" transform="scale(.1)" fill="#fff" textLength="{2}">{0}</text> | |
</g> | |
</svg> | |
' | |
COLORS=( "#4c1" "#97ca00" "#a4a61d" "#dfb317" "#fe7d37" "#e05d44" ) | |
ELEMENTS="$(xmllint --xpath 'string(/coverage/project/metrics/@elements)' "$CLOVER_XML")" | |
STATEMENTS="$(xmllint --xpath 'string(/coverage/project/metrics/@statements)' "$CLOVER_XML")" | |
METHODS="$(xmllint --xpath 'string(/coverage/project/metrics/@methods)' "$CLOVER_XML")" | |
COVERED_ELEMENTS="$(xmllint --xpath 'string(/coverage/project/metrics/@coveredelements)' "$CLOVER_XML")" | |
COVERED_STATEMENTS="$(xmllint --xpath 'string(/coverage/project/metrics/@coveredstatements)' "$CLOVER_XML")" | |
COVERED_METHODS="$(xmllint --xpath 'string(/coverage/project/metrics/@coveredmethods)' "$CLOVER_XML")" | |
COVERED_METRICS="$((COVERED_ELEMENTS + COVERED_STATEMENTS + COVERED_METHODS))" | |
TOTAL_METRICS="$((ELEMENTS + STATEMENTS + METHODS))" | |
COVERAGE="$((1000 * COVERED_METRICS / TOTAL_METRICS))" | |
COLOR_INDEX="$(((1000 - COVERAGE + 99) / 100))" | |
if [ "$((COVERAGE % 10))" != "0" ]; then | |
COVERAGE="$(printf '%.1f\n' "${COVERAGE}e-1")%" | |
else | |
COVERAGE="$((COVERAGE / 10))%" | |
fi | |
if [ "$COLOR_INDEX" -lt "${#COLORS}" ]; then | |
COLOR="${COLORS[$COLOR_INDEX]}" | |
else | |
COLOR="${COLORS[-1]}" | |
fi | |
if [ "${#COVERAGE}" -ge 4 ]; then | |
TEXT_LENGTH=330 | |
elif [ "${#COVERAGE}" -ge 3 ]; then | |
TEXT_LENGTH=250 | |
else | |
TEXT_LENGTH=170 | |
fi | |
BADGE="$BADGE_TEMPLATE" | |
BADGE="${BADGE//\{0\}/$COVERAGE}" | |
BADGE="${BADGE//\{1\}/$COLOR}" | |
BADGE="${BADGE//\{2\}/$TEXT_LENGTH}" | |
echo "$BADGE" > "$BADGE_PATH" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment