diff --git a/scripts/git-commit-msg b/scripts/git-commit-msg new file mode 100755 index 0000000..5adcd80 --- /dev/null +++ b/scripts/git-commit-msg @@ -0,0 +1,43 @@ +#!/bin/bash +############################################################################# +# Copyright (c) 2024 SUSE +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, contact Novell, Inc. +# +# To contact SUSE about this file by physical or electronic mail, +# you may find current contact information at www.suse.com +############################################################################# + +commit_file="$1" + +err=0 +git diff-index --name-status --diff-filter=AM --cached HEAD | ( +while read stat file garbage; do + case "$file" in + patches.*/*) + new_refs=$(git diff-index -p --cached HEAD "$file" | \ + awk '/^+References:/ {for (i=2; i <= NF; i++) refs[$i]++} + /^-References:/ {for (i=2; i <= NF; i++) refs[$i]--} + END { for (r in refs) if (refs[r] > 0) print(r)}') + for ref in $new_refs ; do + grep -q $ref $commit_file || { echo "New reference '$ref' missing in the commit message." ; err=1 ; } + done + ;; + esac +done + +if test "$err" != 0; then + echo "Aborting." + exit "$err" +fi ) || exit diff --git a/scripts/install-git-hooks b/scripts/install-git-hooks index ed1641a..5ecb9ec 100755 --- a/scripts/install-git-hooks +++ b/scripts/install-git-hooks @@ -24,6 +24,7 @@ cdup=$(git rev-parse --show-cdup) || exit cd "${cdup:-./}" || exit GIT_DIR=$(git rev-parse --git-dir) || exit +SCRIPTS_DIR=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") check_snippet() { @@ -119,27 +120,20 @@ check_scripts() is_eq "$GIT_DIR"/hooks/kernel-source-pre-commit scripts/git-pre-commit } -# try to create a relative symlink if possible -relative_scripts_dir() -{ - local toplevel=$PWD - if test "$toplevel/.git" -ef "$GIT_DIR"; then - echo "../../scripts" - else - echo "$toplevel/scripts" - fi -} - install_scripts() { chmod +x "$GIT_DIR"/hooks/pre-commit - dir=$(relative_scripts_dir) - ln -sf "$dir"/git-pre-commit "$GIT_DIR"/hooks/kernel-source-pre-commit - if test -r "$GIT_DIR"/hooks/pre-merge-commit ; then - echo "Cannot install pre-merge-commit hook, upstream your hook to kernel-source/scripts" - else - ln -rfs "$GIT_DIR"/hooks/pre-commit "$GIT_DIR"/hooks/pre-merge-commit - fi + ln -rfs "$SCRIPTS_DIR"/git-pre-commit "$GIT_DIR"/hooks/kernel-source-pre-commit + declare -A hooks + hooks[pre-merge-commit]="$GIT_DIR"/hooks/pre-commit + hooks[commit-msg]="$SCRIPTS_DIR"/git-commit-msg + for h in ${!hooks[@]} ; do + if test -f "$GIT_DIR"/hooks/$h -a ! -L "$GIT_DIR"/hooks/$h ; then + echo "Cannot install $h hook, upstream your hook to kernel-source/scripts" + else + ln -rfs "${hooks[$h]}" "$GIT_DIR"/hooks/$h + fi + done } case "$1" in diff --git a/scripts/prepare-maint-update b/scripts/prepare-maint-update index a80944d..6e358a6 100755 --- a/scripts/prepare-maint-update +++ b/scripts/prepare-maint-update @@ -8,34 +8,85 @@ blu=$(tput setaf 4) nrm=$(tput sgr0) sn="${0##*/}" -if [ $# -lt 1 ]; then - printf "${Red}usage:${nrm} %s [branch] [kgraft_prj]\n" "$sn" >&2 +usage() { + printf "${Red}usage:${nrm} %s [-h] [-g | -G] [-t tbranch] branch\n" "$sn" + #rintf "usage: " + printf " Arg Example\n" + printf " -g kgraft_prj SLE15-SP5_Update_9\n" + printf " -G no livepatch submission (e.g. when resubmitting)\n" + printf " -t tbranch SLE15-SP5 (specify target when branch is a user branch)\n" + printf " branch SLE15-SP5\n" +} + +OPTS=$(getopt -o g:Gt:h -n "$sn" -- "$@") +eval set -- "$OPTS" +unset OPTS + +nolp= +while true ; do + case "$1" in + '-g') + lp_proj="$2" + shift 2 + ;; + '-G') + nolp=1 + shift 1 + ;; + '-t') + tbranch="$2" + shift 2 + ;; + '-h') + usage >&2 + exit 0 + ;; + '--') + shift + break + ;; + *) + printf "${Red}Args parsing error${nrm}\n" >&2 + exit 1 + ;; + esac + continue +done +if [ $# -ne 1 ]; then + usage >&2 + exit 1 +elif [ -n "$lp_proj" -a -n "$nolp" ] ; then + printf "${Red}-g and -G cannot be combined.${nrm}\n" >&2 + exit 1 +fi + +branch="$1" +tbranch="${tbranch:-${branch}}" +if [[ "${tbranch}" =~ / ]] ; then + printf "${Red}Specify target branch explicitly without user prefix${nrm}\n" >&2 exit 1 fi -tbranch="$1" -prod="${1%-LTSS}" -branch="${2:-$tbranch}" -lp_proj="${3}" OSC_DIR="${OSC_DIR:-/tmp}" OSC="osc -A https://api.suse.de/" -target="SUSE:SLE-${prod#SLE}:Update" +prod="${tbranch%-LTSS}" +target="SUSE:SLE-${prod#SLE}:Update" # this may be a parameter in future prj="Devel:Kernel:${tbranch}:Submit" kgraft_dir="Devel:kGraft:patches" if [ ! -d "$KSOURCE_GIT" ]; then - printf "${Red}Error: directory '%s' does not exist${nrm}\n" "$KSOURCE_GIT" - echo "Please set KSOURCE_GIT to the location of local kernel-source repository." + printf "${Red}Error: directory '%s' does not exist${nrm}\n" "$KSOURCE_GIT" >&2 + echo "Please set KSOURCE_GIT to the location of local kernel-source repository." >&2 exit 1 fi if [ ! -d "$OSC_DIR" ]; then - printf "${Red}Error: directory '%s' does not exist${nrm}\n" "$OSC_DIR" - echo "Please set OSC_DIR to a directory to use for OBS/IBS checkouts." + printf "${Red}Error: directory '%s' does not exist${nrm}\n" "$OSC_DIR" >&2 + echo "Please set OSC_DIR to a directory to use for OBS/IBS checkouts." >&2 exit 1 fi if ! $OSC api /about >/dev/null ; then - echo "${Red}Error: Cannot login to OBS${nrm}" - printf "Check your SSH key setup in .oscrc for '%s'\n" "$OSC" + echo "${Red}Error: Cannot login to OBS${nrm}" >&2 + printf "Check your SSH key setup in .oscrc for '%s'\n" "$OSC" >&2 exit 1 fi @@ -57,8 +108,10 @@ printf "Target branch: ${blu}%s${nrm}\n" "$tbranch" printf "Submission branch: ${blu}%s${nrm}\n" "$branch" printf "Commit: ${grn}%s${nrm}\n" \ $(git --no-pager show -s --pretty='%h' "$branch") -printf "Version: ${blu}%s${nrm}\n" "$version" -printf "Update: ${blu}%u${nrm}\n" "$upd" +printf "Version: ${blu}%s${nrm}\n" "$version" +if [ -z "$nolp" ] ; then + printf "Kgraft prj: ${blu}%s${nrm}\n" "$lp_proj" +fi echo if ! git merge-base --is-ancestor "$branch" "$tbranch"; then @@ -84,38 +137,42 @@ while read a; do archs="${archs}${archs:+ }${a#${smlp}}" done < <($OSC ls "$chanprj" | egrep "^$smlp") -kgraft_prj="${kgraft_dir}:${lp_proj}" -printf "${grn}* Copy kernel-livepatch-%s_Update_%u package...${nrm}\n" \ - "$prod" "$upd" -$OSC copypac "$kgraft_prj" \ - "kernel-livepatch-${prod}_Update_${upd}" "$prj" - -inc_upd="s/${prod}_Update_[[:digit:]]+/${prod}_Update_${upd}/g" -fixme="s/(${version//./_})-[[:digit:]_]+-/\1-FIXME-/" -printf "${grn}* Branch %s* and update _channel...${nrm}\n" "$smlp" -for a in $archs; do - printf "${grn} * architecture %s...${nrm}\n" "$a" - $OSC bco "$chanprj" "${smlp}${a}" "$prj" - pushd "${prj}/${smlp}${a}" >/dev/null - # Copy last bunch packages of given product, update their versions and - # paste them in one block after last package - last_pkg=$(grep -E "${prod}_Update_[[:digit:]]+" _channel | tail -1) - last_upd=$(echo "$last_pkg" | grep -oE "${prod}_Update_[[:digit:]]+" | tail -1) - prev_pkgs=$(grep -E "${last_upd}" _channel) - new_pkgs=$(echo -n "$prev_pkgs" | sed -re "${inc_upd} ; ${fixme} ; s/\$/\\\/") - # Assume no '|' in XML rows, escaping magic not to insert a trailing newline - sed -re "\|${last_pkg}| a \\ -${new_pkgs%\\} -" -i _channel - $OSC commit -m "update channel file" - popd >/dev/null -done +if [ -z "$nolp" ] ; then + kgraft_prj="${kgraft_dir}:${lp_proj}" + printf "${grn}* Copy kernel-livepatch-%s_Update_%u package...${nrm}\n" \ + "$prod" "$upd" + $OSC copypac "$kgraft_prj" \ + "kernel-livepatch-${prod}_Update_${upd}" "$prj" + + inc_upd="s/${prod}_Update_[[:digit:]]+/${prod}_Update_${upd}/g" + fixme="s/(${version//./_})-[[:digit:]_]+-/\1-FIXME-/" + printf "${grn}* Branch %s* and update _channel...${nrm}\n" "$smlp" + for a in $archs; do + printf "${grn} * architecture %s...${nrm}\n" "$a" + $OSC bco "$chanprj" "${smlp}${a}" "$prj" + pushd "${prj}/${smlp}${a}" >/dev/null + # Copy last bunch packages of given product, update their versions and + # paste them in one block after last package + last_pkg=$(grep -E "${prod}_Update_[[:digit:]]+" _channel | tail -1) + last_upd=$(echo "$last_pkg" | grep -oE "${prod}_Update_[[:digit:]]+" | tail -1) + prev_pkgs=$(grep -E "${last_upd}" _channel) + new_pkgs=$(echo -n "$prev_pkgs" | sed -re "${inc_upd} ; ${fixme} ; s/\$/\\\/") + # Assume no '|' in XML rows, escaping magic not to insert a trailing newline + sed -re "\|${last_pkg}| a \\ + ${new_pkgs%\\} + " -i _channel + $OSC commit -m "update channel file" + popd >/dev/null + done +fi echo -e "\n\nTo submit the update, run\n" printf "${red} %s mr %s \\\\\n" "$OSC" "$prj" printf " kernel-source \\\\\n" -printf " kernel-livepatch-%s_Update_%u \\\\\n" "$prod" "$upd" -while read p; do - printf " %s \\\\\n" "$p" -done < <($OSC ls "$prj" | egrep "^$smlp") +if [ -z "$nolp" ] ; then + printf " kernel-livepatch-%s_Update_%u \\\\\n" "$prod" "$upd" + while read p; do + printf " %s \\\\\n" "$p" + done < <($OSC ls "$prj" | egrep "^$smlp") +fi printf " %s${nrm}\n\n" "$target"