File indexing completed on 2024-05-12 04:22:07

0001 #!/bin/bash
0002 # SPDX-FileCopyrightText: 2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 # SPDX-License-Identifier: BSD-2-Clause
0004 ##
0005 # A script that does some rudimentary checks on the Changelog.
0006 # The script only works for the latest version, really, but it's a start...
0007 # Usage: check-changelog.sh VERSION
0008 # E.g. check-changelog.sh VERSION
0009 ##
0010 
0011 guess_version()
0012 # guess_version CHANGELOG_FILE
0013 {
0014     local changelog_file="$1"
0015     if ! sed -n  '/^KPhotoAlbum [.0-9]* / { s/KPhotoAlbum \([.0-9]*\) .*/\1/p ; q }' "$changelog_file"
0016     then
0017         echo "! Failed to extract latest release version from $changelog_file!" >&2
0018         exit 1
0019     fi
0020 }
0021 
0022 parse_git_issues()
0023 # parse_git_issues GITREF
0024 # Output:
0025 # ISSUE_NUMBER COMMIT_HASH
0026 # ...
0027 {
0028     local gitref="$1"
0029     # transform log into lines with commit hashes and lines with issue numbers
0030     # e.g.:
0031     # H:deadbeef
0032     # I:123456
0033     git log --pretty='#:%h%n%b%n' "$gitref" -- | sed -n '/^\#:/ s/\#/H/p ; /^\(BUG\)\|\(FEATURE\):/ s/[^0-9]*\([0-9]*\).*/I:\1/p' | {
0034         # append previous hash to issue number
0035         hash=
0036         while read -r line
0037         do
0038             case "${line}" in
0039                 H:*) hash="${line:2}"
0040                     ;;
0041                 I:*) echo "${line:2}" "$hash"
0042                     ;;
0043                 *)
0044                     echo "! Unexpected line format! This is a bug!" >&2
0045                     exit 1
0046             esac
0047         done
0048     }
0049 }
0050 
0051 check_issues()
0052 # check_issues CHANGELOG_FILE issues-commits.txt
0053 {
0054     local changelog_file="$1"
0055     local icfile="$2"
0056     local num_issues
0057     num_issues=$(wc -l < "$icfile")
0058     echo "# Checking mentions for resolved issues..." >&2
0059     {
0060         local num_ok=0
0061         local num_check=0
0062         while read -r issue hash
0063         do
0064             if grep -q "#${issue}\W" "${changelog_file}"
0065             then
0066                 echo "[OK] $issue"
0067                 (( num_ok++ ))
0068             else
0069                 echo "[CHECK] $issue - Check commit $hash and bug report https://bugs.kde.org/$issue for details."
0070                 (( num_check++ ))
0071             fi
0072         done
0073         echo "# $num_issues issues, $num_ok ok, $num_check suspicious." >&2
0074         if [[ "$num_check" -gt 0 ]]
0075         then
0076             echo "**" >&2
0077             echo "* Please check the mentioned issues for false positives. Here are some examples for false positives that should not be part of the changelog:" >&2
0078             echo "*  - any bugs that have not yet been part of a release" >&2
0079             echo "*  - any bugs that were reopened and thus are not actually fixed" >&2
0080             echo "**" >&2
0081         fi
0082     } < "$icfile"
0083 }
0084 
0085 parse_changelog_issues()
0086 # parse_changelog_issues CHANGELOG VERSION
0087 {
0088     local changelog_file="$1"
0089     local version="$2"
0090     # check lines up to the $version announcement,
0091     # ... place strings looking like a issue number (e.g. #12345) on their own line,
0092     # ... remove '#' characters that are not part of an issue number,
0093     # and then only print the issue numbers from the output, striping the '#' character
0094     sed -n "1,/^KPhotoAlbum ${version} / { s/[^#]*\#\([0-9]\+\)[^#]*/\n#\1/g ; s/#[^0-9]//g; p }" "${changelog_file}" | sed -n  '/^#/ s/\#//p'
0095 }
0096 
0097 check_issue_plausibility()
0098 # check_issue_plausibility ISSUES-COMMITS-FILE issues.txt
0099 {
0100     local icfile="$1"
0101     local issuefile="$2"
0102     local num_issues
0103     num_issues=$(wc -l < "$issuefile")
0104     echo "# Checking issue numbers found in Changelog file:" >&2
0105     {
0106         local num_ok=0
0107         local num_check=0
0108         while read -r issue
0109         do
0110             local hash
0111             if hash="$(sed -n "/^$issue / s/[^ ]* //p" "$icfile" | head -n1)"
0112             then
0113                 echo "[OK] $issue - commit $hash"
0114                 (( num_ok++ ))
0115             else
0116                 echo "[CHECK] $issue - Check bug report https://bugs.kde.org/$issue"
0117                 (( num_check++ ))
0118             fi
0119         done
0120         echo "# $num_issues issues, $num_ok ok, $num_check uncertain." >&2
0121         if [[ "$num_check" -gt 0 ]]
0122         then
0123             echo "**" >&2
0124             echo "* Please check manually, if the mentioned issue reports exist." >&2
0125             echo "**" >&2
0126         fi
0127     } < "$issuefile"
0128 }
0129 
0130 
0131 BASEDIR="$(git rev-parse --show-toplevel)"
0132 
0133 CHANGELOG="$BASEDIR/CHANGELOG.md"
0134 VERSION="$(guess_version "$CHANGELOG")"
0135 
0136 TEMPDIR=$(mktemp -d)
0137 cleanup()
0138 {
0139     rm -r "$TEMPDIR"
0140     unset TEMPDIR
0141 }
0142 trap cleanup EXIT
0143 
0144 echo "# Checking all changes since version $VERSION..." >&2
0145 
0146 parse_git_issues "v${VERSION}.." > "$TEMPDIR/git-issues-commits.txt"
0147 check_issues "$CHANGELOG" "$TEMPDIR/git-issues-commits.txt"
0148 
0149 parse_changelog_issues "$CHANGELOG" "$VERSION" >"$TEMPDIR/changelog-issues.txt"
0150 check_issue_plausibility "$TEMPDIR/git-issues-commits.txt" "$TEMPDIR/changelog-issues.txt"