Ctrl K
ComunidadGuías…

scripts/check-mutation-total.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
set -euo pipefail

reports=$1
rows=40

work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT
survivors=$work/survivors
uncovered=$work/uncovered
: >"$survivors"
: >"$uncovered"

killed=0
lived=0
common=0
default_root=
desktop_root=
found=0

while IFS= read -r -d '' report; do
    name=$(basename "$report" .json)
    if ! counts=$(jq -r '[(.mutants_killed // "?"), (.mutants_lived // "?"), (.mutants_not_covered // "?")] | @tsv' "$report" 2>/dev/null); then
        echo "mutation: $name is not a readable report" >&2
        exit 11
    fi
    IFS=$'\t' read -r report_killed report_lived report_not_covered <<<"$counts"
    for count in "$report_killed" "$report_lived" "$report_not_covered"; do
        if [[ ! "$count" =~ ^[0-9]+$ ]]; then
            echo "mutation: $name is missing its mutant counts" >&2
            exit 11
        fi
    done
    found=$((found + 1))
    killed=$((killed + report_killed))
    lived=$((lived + report_lived))
    case "$name" in
        root-default-root)
            default_root=$report_not_covered
            ;;
        root-desktop-root)
            desktop_root=$report_not_covered
            ;;
        *)
            common=$((common + report_not_covered))
            ;;
    esac
    jq -r --arg report "$name" '
        (.files // [])[]
        | .file_name as $file
        | (.mutations // [])[]
        | select(.status == "LIVED")
        | [$report, $file, (.line | tostring), .type]
        | @tsv' "$report" >>"$survivors"
    jq -r --arg report "$name" '
        (.files // [])[]
        | {file: .file_name, count: ([(.mutations // [])[] | select(.status == "NOT COVERED")] | length)}
        | select(.count > 0)
        | [(.count | tostring), $report, .file]
        | @tsv' "$report" >>"$uncovered"
done < <(find "$reports" -type f -name '*.json' -print0)

if [ "$found" -eq 0 ]; then
    echo "mutation: no package reports found" >&2
    exit 11
fi
if [[ ! "$default_root" =~ ^[0-9]+$ ]]; then
    echo "mutation: default root report is missing" >&2
    exit 11
fi
if [[ ! "$desktop_root" =~ ^[0-9]+$ ]]; then
    echo "mutation: desktop root report is missing" >&2
    exit 11
fi

default_total=$((common + default_root))
desktop_total=$((common + desktop_root))
printf 'mutation: %d killed, %d survived; uncovered %d default, %d desktop\n' \
    "$killed" "$lived" "$default_total" "$desktop_total"

while IFS=$'\t' read -r report file line mutator; do
    printf '::warning title=Mutant survived::%s changed %s:%s and no test noticed\n' \
        "$mutator" "$file" "$line"
    printf 'mutation: %s survived %s in %s:%s\n' "$report" "$mutator" "$file" "$line" >&2
done <"$survivors"

{
    printf '## Mutation testing\n\n'
    printf '%d mutants killed, %d survived.\n\n' "$killed" "$lived"
    printf 'Mutants no test reaches: %d in the default build, %d in the desktop build.\n\n' \
        "$default_total" "$desktop_total"
    if [ -s "$survivors" ]; then
        printf '### Survived\n\n'
        printf 'A test ran this line, the change altered behaviour, and nothing failed.\n\n'
        printf '| package | file | line | mutator |\n| --- | --- | --- | --- |\n'
        while IFS=$'\t' read -r report file line mutator; do
            printf '| %s | %s | %s | %s |\n' "$report" "$file" "$line" "$mutator"
        done <"$survivors"
        printf '\n'
    fi
    if [ -s "$uncovered" ]; then
        printf '### Not reached\n\n'
        printf 'No test executes these lines, so the mutants there were never run.\n'
        printf 'Go does not instrument const and var declarations or the case expressions of a\n'
        printf 'conditionless switch, so mutants on those lines can never be reached at all.\n\n'
        printf '| mutants | package | file |\n| --- | --- | --- |\n'
        sort -t "$(printf '\t')" -k1,1nr -k2,2 -k3,3 "$uncovered" >"$work/sorted"
        head -n "$rows" "$work/sorted" >"$work/shown"
        while IFS=$'\t' read -r count report file; do
            printf '| %s | %s | %s |\n' "$count" "$report" "$file"
        done <"$work/shown"
        listed=$(wc -l <"$work/sorted")
        if [ "$listed" -gt "$rows" ]; then
            printf '\n%d more files are not listed.\n' "$((listed - rows))"
        fi
    fi
} >>"${GITHUB_STEP_SUMMARY:-/dev/stdout}"