#!/bin/bash # # Dump patches from git (current coring directory) to be usable in --spec file # The script does not modify your spec file! You have to copy & past the output manually. # # !!! # Script read bugs summary from bugzilla. Don't forget "bugzilla login" # before you execute the script. # !!! # # TEMP=$(getopt -o hs:o:x:p: --long help,spec:,output-directory:,head:,split-point:, -n 'git2spec' -- "$@") BASE= SPEC_FILE= HEAD= OFFSET=0 n_patches=0 declare -a PATCHES declare -a BUGNUMS declare -a SUMMARY bold=$(tput setaf 3) normal=$(tput sgr0) function die() { echo "$1" exit 0 } function add_to_array() { local -n a=$1 local idx=$2 a[$idx]=$3 } function get_filename() { local -n a=PATCHES echo "${a[$1]}" } function get_bznum() { local -n a=BUGNUMS echo "${a[$1]}" } function get_bzsummary() { local -n a=SUMMARY echo "${a[$1]}" } function patch_get_bz() { local filename=$(get_filename $1) awk '/^Addresses:/ { match($0, "id=([0-9]*)", x); bz=substr($0, x[1, "start"], x[1, "length"]); print bz }' "${filename}" } function bugzilla_get_summary() { local bz="$1" bugzilla query --bug_id=${bz} --outputformat="%{summary}" } function dump_patches() { local head="$1" local bz local num if [ $OFFSET -eq 0 ]; then num=1 else num=$OFFSET fi while read line; do add_to_array PATCHES $n_patches $line n_patches=$(($n_patches + 1)) done < <(git format-patch -o ${BASE} ${head} --start-number $num) [ $n_patches -eq 0 ] && return # read BZ numbers from patch files for i in $(seq 0 $(($n_patches - 1))); do bz=$(patch_get_bz $i) add_to_array BUGNUMS $i $bz done } function read_bugzilla() { local bz local summary echo -n "Reading bugzillas..." for i in $(seq 0 $(($n_patches - 1))); do bz=$(get_bznum $i) echo -n "$bz " summary="$(bugzilla_get_summary $bz)" add_to_array SUMMARY $i "$summary" done echo "done" echo } function section_s() { echo "${bold}### ${1}${normal}" } function section_e() { echo "${bold}### ${1}${normal}" echo } function usage() { echo "git2spec [options]" echo echo "Options:" echo " -s, --spec path to specfile" echo " -o, --output-directory optional, default is specfile directory" echo " -x, --head where to start generate patches in git history" echo " -p, --split-point optional, where in git history begins stuff maintaind by your spec file" echo exit 0 } # # main() # eval set -- "$TEMP" while true ; do case "$1" in -s|--spec) SPEC_FILE="$2" ; shift 2 ;; -o|--output*) BASE="$2" ; shift 2 ;; -x|--head) HEAD="$2" ; shift 2 ;; -p|--split*) START="$2" ; shift 2 ;; -h|--help) usage ; ;; --) shift ; break ;; *) echo "Internal error!" ; exit 1 ;; esac done #[ -z "$SPEC_FILE" ] && die "No spec file specified (use --spec )." [ -z "$HEAD" ] && die "No start-point specified (use --head )." if [ -z "$BASE" ]; then BASE="$(dirname $SPEC_FILE)" fi if [ -n "$START" ]; then OFFSET=$(git rev-list --count ${START}..${HEAD}) fi dump_patches $HEAD [ $n_patches -eq 0 ] && die "Not found patches." read_bugzilla USERNAME="$(git config --get user.name)" USEREMAIL="$(git config --get user.email)" TODAY="$(date '+%a %b %d %Y')" VERSION="$(awk '/^Version/ {print $2}' ${SPEC_FILE})" RELEASE="$(awk '/^Release/ {print $2}' ${SPEC_FILE} | sed -e 's/%{?dist}.*//')" NEW_RELEASE=$(( $RELEASE + 1 )) section_s "SPEC FILE PATCHES (generated from git)" for i in $(seq 0 $(($n_patches - 1))); do bz=$(get_bznum $i) filename="$(basename $(get_filename $i))" summary="$(get_bzsummary $i)" if [ $OFFSET -eq 0 ]; then num=$i else num=$(( $OFFSET + $i )) fi echo "# $bz - $summary" echo "Patch${num}: ${filename}" done section_e "END OF PATCHES" section_s "spec file changelog" echo "* ${TODAY} ${USERNAME} <${USEREMAIL}> ${VERSION}-${NEW_RELEASE}" for i in $(seq 0 $(($n_patches - 1))); do bz=$(get_bznum $i) summary="$(get_bzsummary $i)" echo "- fix #$bz - ${summary}" done section_e section_s "git" echo -n "git add " for i in $(seq 0 $(($n_patches - 1))); do echo -n "$(basename $(get_filename $i)) " done echo section_e section_s "dist-git commit" echo "${VERSION}-${NEW_RELEASE}" echo echo -n "Resolves: " for i in $(seq 0 $(($n_patches - 1))); do echo -n "#$(get_bznum $i) " done echo section_e