See More

#!/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 "Parameters:" echo " branches.conf: file with the list of branches to be checked" echo " one per line; must be the very first argument" echo " term: hash of the commit|CVE|bsc to be found" echo " -g : pattern for grep to filter out branches you are interested in" echo " -h: show this message" echo " -c: show colored results always" echo " -C: show colored results only if stdout is connected to the terminal" echo " --: end of command line options" echo echo "Environment:" echo " LINUX_GIT: This environment variable should specify the location" echo " of a clone of the upstream Linux git repository" } 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" } setup_colors() { RED_FONT="$(tput setaf 1)$(tput bold)" GREEN_FONT="$(tput setaf 2)$(tput bold)" YELLOW_FONT="$(tput setaf 3)$(tput bold)" MAGENTA_FONT="$(tput setaf 5)$(tput bold)" NORMAL_FONT="$(tput sgr0)" } if [ $# -lt 1 ] ; then usage exit 1 fi [[ -z $LINUX_GIT ]] && echo "LINUX_GIT is unset, therefore I cannot check the base kernel and false negatives are possible!" >&2 # Ideally, this would be under -f option, but for now I'm leaving it here for backwards compatibility. !!! TODO !!! 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=() while [[ $# -gt 0 ]] do case "$1" in -h | --h | --he | --hel | --help) usage exit 0 ;; -g | --g | --gr | --gre | --grep) GREP_PATTERN="$2" if [[ -z $GREP_PATTERN ]] || [[ $GREP_PATTERN = -- ]]; then echo "Pattern must be non-empty!" >&2 exit 1 fi shift 2 ;; -c | --c | --co | --col | --colo | --color | --colou | --colour) setup_colors shift 1 ;; -C | --C | --Co | --Col | --Colo | --Color | --Colou | --Colour) [[ -t 1 ]] && setup_colors shift 1 ;; --) shift KBC_CHECK_TERMS+=($*) shift $# ;; -*) echo "Skipping unrecognized option: $1" >&2 shift 1 ;; *) KBC_CHECK_TERMS+=("$1") shift 1 ;; esac done 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_with_upstream_tag() { local ret=1 local line="$(git grep -e SRCVERSION "remotes/origin/$1" -- rpm/config.sh)" local tag_suffix="${line##*=}" if [[ -n $tag_suffix ]] ; then git --git-dir="$LINUX_GIT/.git" merge-base --is-ancestor "$2" "v$tag_suffix" ret=$? fi return $ret } declare -A TBL_GREP_PATCHES check_branch() { local verbose=0 if [ "$1" = "-v" ] ; then verbose=1 shift fi local branch="$1" git show-ref --verify --quiet "refs/remotes/origin/${branch}" || return 42 local found="" local blacklisted="" local missing="" local term for term in "${KBC_CHECK_TERMS[@]}" ; do term_to_search_for="$(term2regex $term)" if [[ $term_to_search_for == ^Git-commit* ]] && [[ -n $LINUX_GIT ]] && check_with_upstream_tag "$branch" "$term" ; then found="$found $term" continue fi local tbl_patches_ret local key="${term_to_search_for};${branch}" if [[ -z ${TBL_GREP_PATCHES["$key"]} ]]; then git grep -qi "$term_to_search_for" "remotes/origin/$branch" -- 'patches.*' 2>/dev/null tbl_patches_ret=$? TBL_GREP_PATCHES["$key"]=$tbl_patches_ret else tbl_patches_ret=${TBL_GREP_PATCHES["$key"]} fi if [ $tbl_patches_ret -eq 0 ] ; then found="$found $term" else git grep -qi "$term" "remotes/origin/$branch" -- 'blacklist.conf' 2>/dev/null if [ $? -eq 0 ] ; then blacklisted="$blacklisted $term" else missing="$missing $term" fi fi done # found if [ -z "$missing" ] && [ -z "$blacklisted" ] ; then return 0 fi # blacklisted if [ -z "$found" ] && [ -z "$missing" ] ; then return 1 fi # missing if [ -z "$found" ] && [ -z "$blacklisted" ] ; then return 3 fi # partly if [ $verbose -ne 0 ] ; then if [ -n "$missing" ] ; then echo " missing hash:" local hash for hash in $missing ; do echo " $hash" done fi if [ -n "$blacklisted" ] ; then echo " blacklisted hash:" local hash for hash in $blacklisted ; do echo " $hash" done fi echo fi return 2 } check_parents() { local last_branch="" local branch for branch in "$@" ; do check_branch $branch case $? in 0) echo " (found in $branch)" return ;; 2) 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 if [[ -n $GREP_PATTERN ]] && echo "$branch" | grep -q -E -v -- "$GREP_PATTERN"; 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 42) echo "branch does not exist" ;; 0) echo "${GREEN_FONT}${NORMAL_FONT}" ;; 1) echo "${MAGENTA_FONT}${NORMAL_FONT}" ;; 2) echo -n "${YELLOW_FONT}${NORMAL_FONT} " check_parents $parents # print missing commits check_branch -v "$branch" ;; *) echo -n "${RED_FONT}${NORMAL_FONT}" check_parents "${branch}_EMBARGO" $parents esac done