From 33374cac3944ce21b21fba4bb14ebf15e24c0b94 Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN\"" Date: Tue, 10 Nov 2009 19:32:11 +0100 Subject: scripts: output renumbered patches in a new directory When renumbering patches, the original patches get removed and replaced with the new ones. This can be annoying to loose the original patches. Fix this by putting the new patchs in a directory of their own. --- scripts/patch-renumber.sh | 56 ++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 23 deletions(-) (limited to 'scripts') diff --git a/scripts/patch-renumber.sh b/scripts/patch-renumber.sh index 95bae8fb..08ec1beb 100755 --- a/scripts/patch-renumber.sh +++ b/scripts/patch-renumber.sh @@ -9,37 +9,47 @@ myname="$0" doUsage() { cat <<_EOF_ -Usage: ${myname} [sed_re] - Will renumber all patches found in 'dir', starting at 'base', and with - an increment of 'inc'. +Usage: ${myname} [sed_re] + Renumbers all patches found in 'src_dir', starting at 'base', with an + increment of 'inc', and puts the renumbered patches in 'dst_dir'. + Leading digits are replaced with the new indexes, and a subsequent '_' + is replaced with a '-'. If 'sed_re' is given, it is interpreted as a valid sed expression, and - it will be applied to the patch name. - If the environment variable FAKE is set to 'y', then the command will - only be printed, and not executed (so you can check beforehand). + is be applied to the patch name. + If the environment variable FAKE is set to 'y', then nothing gets done, + the command to run is only be printed, and not executed (so you can + check beforehand). + 'dst_dir' must not yet exist. Eg.: - patch-renumber.sh patches/gcc/4.3.1 100 10 - patch-renumber.sh patches/gcc/4.2.4 100 10 's/(all[_-])*(gcc[-_])*//;' + patch-renumber.sh patches/gcc/4.2.3 patches/gcc/4.2.4 100 10 + patch-renumber.sh /some/dir/my-patches patches/gcc/4.3.1 100 10 's/(all[_-])*(gcc[-_])*//;' _EOF_ } -[ $# -lt 3 -o $# -gt 4 ] && { doUsage; exit 1; } -[ -d "${1}" ] || { doUsage; exit 1; } +[ $# -lt 4 -o $# -gt 5 ] && { doUsage; exit 1; } -dir="${1}" -cpt="${2}" -inc="${3}" -sed_re="${4}" - -case "$(LC_ALL=C hg id "${dir}" 2>/dev/null)" in - "") CMD="";; - *) CMD="hg";; -esac +src="${1}" +dst="${2}" +cpt="${3}" +inc="${4}" +sed_re="${5}" +if [ ! -d "${src}" ]; then + printf "%s: '%s': not a directory\n" "${myname}" "${src}" + exit 1 +fi +if [ -d "${dst}" ]; then + printf "%s: '%s': directory already exists\n" "${myname}" "${dst}" + exit 1 +fi -if [ "${FAKE}" = "y" ]; then - CMD="echo ${CMD}" +Q= +if [ -n "${FAKE}" ]; then + printf "%s: won't do anything: FAKE='%s'\n" "${myname}" "${FAKE}" + Q="echo" fi -for p in "${dir}"/*.patch*; do +${Q} mkdir -pv "${dst}" +for p in "${src}/"*.patch*; do [ -e "${p}" ] || { echo "No such file '${p}'"; exit 1; } newname="$(printf "%03d-%s" \ "${cpt}" \ @@ -48,6 +58,6 @@ for p in "${dir}"/*.patch*; do -e "${sed_re}" \ )" \ )" - [ "${p}" = "${dir}/${newname}" ] || ${CMD} mv -v "${p}" "${dir}/${newname}" + ${Q} cp -v "${p}" "${dst}/${newname}" cpt=$((cpt+inc)) done -- cgit v1.2.3 From c863d223faa360a299181b071c03d7a447644175 Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN\"" Date: Thu, 12 Nov 2009 18:42:13 +0100 Subject: scripts: be POSIXly correct in helper scripts Fix helper scripts to be POSIXly correct: don't expect '.' (the dot builtin) to search CWD if it is not in $PATH. --- scripts/addToolVersion.sh | 7 ++++++- scripts/patch-renumber.sh | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/addToolVersion.sh b/scripts/addToolVersion.sh index b71ee9ae..876d4e24 100755 --- a/scripts/addToolVersion.sh +++ b/scripts/addToolVersion.sh @@ -5,7 +5,12 @@ set -e myname="$0" # Parse the tools' paths configuration -. "paths.mk" +# It is expected that this script is only to be run from the +# source directory of crosstool-NG, so it is trivial to find +# paths.mk (we can't use ". paths.mk", as POSIX states that +# $PATH should be searched for, and $PATH most probably doe +# not include "."), hence the "./". +. "./paths.mk" doHelp() { cat <<-EOF diff --git a/scripts/patch-renumber.sh b/scripts/patch-renumber.sh index 08ec1beb..3604df57 100755 --- a/scripts/patch-renumber.sh +++ b/scripts/patch-renumber.sh @@ -5,7 +5,12 @@ set -e myname="$0" # Parse the tools' paths configuration -. "paths.mk" +# It is expected that this script is only to be run from the +# source directory of crosstool-NG, so it is trivial to find +# paths.mk (we can't use ". paths.mk", as POSIX states that +# $PATH should be searched for, and $PATH most probably doe +# not include "."), hence the "./". +. "./paths.mk" doUsage() { cat <<_EOF_ -- cgit v1.2.3 From 590ca63f0dc6a548e2254d71b065efbf38ed85d8 Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN\"" Date: Fri, 13 Nov 2009 19:34:18 +0100 Subject: scripts: add a new helper script to easily rediff a patchset --- scripts/patch-rework.sh | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100755 scripts/patch-rework.sh (limited to 'scripts') diff --git a/scripts/patch-rework.sh b/scripts/patch-rework.sh new file mode 100755 index 00000000..795c3c3e --- /dev/null +++ b/scripts/patch-rework.sh @@ -0,0 +1,153 @@ +#!/bin/sh + +# Get our required options +base="$1" +src="$2" +dst="$3" +shift 3 + +# The remainder is for diff +diff="$@" + +# This function checks that the files listed in the file in "$1" +# do exist, at the given depth-stripping level (aka diff -p#) +do_check_files_at_depth() { + local flist="$1" + local depth="$2" + local ok=0 # 0: OK, !0: KO + + exec 6<&0 + exec 7<"${flist}" + + while read -u7 f; do + f="$( echo "${f}" |sed -r -e "s:^([^/]+/){${depth}}::;" )" + [ -f "${f}" ] || ok=1 + done + + exec 7<&- + exec <&6 + + return ${ok} +} + +mkdir -p "${dst}" +dst="$( cd "${dst}"; pwd )" + +# Iterate through patches +for p in "${src}/"*.patch; do + pname="$( basename "${p}" )" + + printf "Handling patch '${pname}'...\n" + + printf " creating reference..." + cp -a "${base}" "${base}.orig" + printf " done\n" + + printf " retrieving patch comment..." + comment="$( awk ' +BEGIN { mark=0; } +$0~/^diff --/ { nextfile; } +$1=="---" { mark=1; next; } +$1=="+++" && mark==1 { nextfile; } +{ mark=0; print; } +' "${p}" )" + printf " done\n" + + printf " creating patched file list..." + diffstat -f 4 -r 2 -u -p 0 "${p}" \ + |head -n -1 \ + |awk '{ for(i=NF;i>=NF-5;i--) { $(i) = ""; } print; }' \ + |sort \ + >"diffstat.orig" + printf " done\n" + + pushd "${base}" >/dev/null 2>&1 + + # Check all files exist, up to depth 3 + printf " checking depth:" + for((d=0;d<4;d++)); do + printf " ${d}" + if do_check_files_at_depth "../diffstat.orig" ${d}; then + printf " ok, using depth '${d}'\n" + break + fi + done + if [ ${d} -ge 4 ]; then + printf "\n" + printf " checking depth failed\n" + read -p " --> enter patch depth (or Ctrl-C to abort): " d + fi + + # Store the original list of fiels touched by the patch, + # removing the $d leading components + sed -r -e "s:^([^/]+/){${d}}::;" "../diffstat.orig" >"${dst}/${pname}.diffstat.orig" + + # Apply the patch proper, and check it applied cleanly. + # We can't check with --dry-run because of patches that + # contain multiple accumulated patches onto a single file. + printf " applying patch..." + if ! patch -g0 -F1 -f -p${d} <"${p}" >"../patch.out" 2>&1; then + printf " ERROR\n" + # Revert the patch + popd >/dev/null 2>&1 + printf " restoring '${base}'..." + rm -f "diffstat.tmp" + rm -rf "${base}" + mv "${base}.orig" "${base}" + printf " done\n\n" + printf "There was an error while applying:\n --> ${p} <--\n" + printf "'${base}' was restored to the state it was prior to applying this faulty patch.\n" + printf "Here's the 'patch' command, and its output:\n" + printf " ----8<----\n" + printf " patch -g0 -F1 -f -p${d} <'${p}'\n" + cat "patch.out" |(IFS=$(printf "\n"); while read line; do printf " ${line}\n"; done) + rm -f "patch.out" + printf " ----8<----\n" + exit 1 + fi + printf " done\n" + + printf " removing '.orig' files..." + find . -type f -name '*.orig' -exec rm -f {} + + printf " done\n" + + popd >/dev/null 2>&1 + + printf " re-diffing the patch..." + printf "%s\n\n" "${comment}" >"${dst}/${pname}" + diff -durN "${base}.orig" "${base}" >>"${dst}/${pname}" + printf " done\n" + + if [ -n "${diff}" ]; then + printf " applying diff filter..." + filterdiff -x "${diff}" "${dst}/${pname}" >"tmp-diff" + mv "tmp-diff" "${dst}/${pname}" + printf " done\n" + fi + + printf " creating new patched file list..." + diffstat -f 4 -r 2 -u -p 1 "${dst}/${pname}" \ + |head -n -1 \ + |awk '{ for(i=NF;i>=NF-5;i--) { $(i) = ""; } print; }' \ + |sort \ + >"${dst}/${pname}.diffstat.new" + printf " done\n" + + printf " removing temporary files/dirs..." + rm -f "patch.out" + rm -f "diffstat.tmp" + rm -rf "${base}.orig" + printf " done\n" +done + +# Scan all new patches to see if they touch +# more files than the original patches +printf "\nChecking resulting patchset:\n" +for p in "${dst}/"*.patch; do + pname="$( basename "${p}" )" + + if ! cmp "${p}.diffstat.orig" "${p}.diffstat.new" >/dev/null; then + printf " --> '${pname}' differ in touched files <--\n" + fi +done +printf " done.\n" -- cgit v1.2.3