Blob Blame History Raw
#!/bin/bash

usage()
{
    echo "Check whether a given list of commit is available in"
    echo "a given list of branches."
    echo
    echo "Usage: ${0##*/} [branches.conf] term..."
    echo
    echo "Parametes:"
    echo "	branches.conf: file with the list of branches to be checked"
    echo "	term: hash of the commit|CVE|bsc to be found"
}

fetch_branches()
{
    local CACHED_BRANCHES="/tmp/$USER-branches.conf"
    local URL="https://kerncvs.suse.de/branches.conf"
    local EXPIRE=7
    branches=$CACHED_BRANCHES
    if [[ $(find "$CACHED_BRANCHES" -mtime -$EXPIRE -print 2>/dev/null) \
            && -s "$CACHED_BRANCHES" ]]; then
        echo "Using cached $CACHED_BRANCHES" >&2
        return
    fi
    curl "$URL" -o "$CACHED_BRANCHES"
}

if [ $# -lt 1 ] ; then
    usage
    exit 1
fi

branches=$1
if [ ! -f "$branches" ] ; then
    echo "Branches file not specified, trying to fetch it..." >&2
    if ! fetch_branches ; then
        "Error: Can't find the file with the list of branches: $branches nor fetch it"
        exit 1
    fi
else
    shift;
fi

KBC_CHECK_TERMS="$*"

term2regex()
{
    shopt -q nocasematch
    local t=$1
    case $t in
        # CVEs first
        2[0-9][0-9][0-9]-*)
            t=cve-$t
            ;&
        cve-*)
            echo "^References:.*$t"
            ;;
        # looks like a hash, look for commits
        [a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]*)
            echo "^Git-commit:.*$t"
            ;;
        # treat rest as a generic reference
        *)
            echo "^References:.*$t"
            ;;
    esac
}

check_branch()
{
    verbose=0
    if [ "$1" = "-v" ] ; then
        verbose=1
        shift
    fi

    branch="$1"
    found=""
    missing=""

    for term in $KBC_CHECK_TERMS ; do
        git grep -qi "$(term2regex $term)" "remotes/origin/$branch" -- 'patches.*' 2>/dev/null
        if [ $? -eq 0 ] ; then
            found="$found $term"
        else
            missing="$missing $term"
        fi
    done

    # found
    if [ -z "$missing" ] ; then
        return 0
    fi

    # missing
    if [ -z "$found" ] ; then
        return 2
    fi

    # partly
    if [ $verbose -ne 0 ] ; then
        echo "        missing hash:"
        for hash in $missing ; do
            echo "                $term"
        done
        echo
    fi
    return 1
}

check_parents()
{
    last_branch=""
    for branch in "$@" ; do
        check_branch $branch
        case $? in
            0)
                echo "    (found in $branch)"
                return
                ;;
            1)
                echo "    (partly in $branch)"
                return
                ;;
            *)
                ;;
        esac
        last_branch="$branch"
    done

    # not found anywhere
    echo "    (not even in $last_branch)"
}

grep -w build "$branches" | grep -v -E "^(master|vanilla|linux-next|cve)" | \
while read line ; do
    line=${line%%\#*}
    branch=${line%%:*}

    # empty line or comment
    if [ -z "$branch" ] ; then
       continue
    fi

    # always check also the _EMBARGO branch as a possible parent
    parents="${branch}_EMBARGO"
    set dummy ${line#$branch:}
    while [ $# -gt 0 ] ; do
        shift
        [[ "$1" =~ "merge:" ]] || continue
        tmp="${1//*merge:-/}"
        parents="$parents ${tmp//*merge:/}"
    done

    printf "%-23s" "$branch"
    check_branch "$branch"

    case $? in
        0)
            echo "<ok>"
            ;;
        1)
            echo -n "<partly> "
            check_parents $parents
            # print missing commits
            check_branch -v "$branch"
            ;;
        *)
            echo -n "<missing>"
            check_parents "${branch}_EMBARGO" $parents 
    esac
done