From b43a8286cecd0495015b5828c40e5de3594609ad Mon Sep 17 00:00:00 2001 From: Michael Hanke Date: Sun, 5 Sep 2010 17:42:18 -0400 Subject: [PATCH] Draft of a new backporting helper. --- tools/backport-dsc | 370 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100755 tools/backport-dsc diff --git a/tools/backport-dsc b/tools/backport-dsc new file mode 100755 index 0000000..f6251c6 --- /dev/null +++ b/tools/backport-dsc @@ -0,0 +1,370 @@ +#!/bin/bash + +# play save +set -e +set -u + +# version of this script +backports_dsc_version=0.1 + +############ +# Defaults # +############ + +bp_distribution=${BACKPORT_DISTRIBUTION:-lenny-backports} +bp_version_suffix=${BACKPORT_VERSION_SUFFIX:-bpo50} +bp_maintainer_name=${DEBFULLNAME:-unamed} +bp_maintainer_email=${DEBEMAIL:-unknown} +bp_update_maintainer=1 +# whether or not to apply backport patches found in a package +bp_apply_patches=1 +# produce fancy colored output +bp_color_output=1 +# enables additional status message if set to true +bp_verbose=0 +# sed expressions to modify debian/control +bp_mod_control="" + + +# source config files +if [ -f /etc/backport-dsc ]; then + . /etc/backport-dsc +fi + +# source user config files +if [ -f "$HOME/.backport-dsc" ]; then + . $HOME/.backport-dsc +fi + + +print_version() +{ +cat << EOT +backport-dsc $backports_dsc_version + +Copyright (C) 2010 Michael Hanke + +Licensed under GNU Public License version 2 or later. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Written by Michael Hanke for the NeuroDebian project. + +EOT +} + + +print_short_description() +{ +cat << EOT +Helper to aid backporting a Debian source package to an arbitrary distribution +release. + +backport-dsc aids backporting by appropriately mangling the source package +version, adjusting the maintainer of a package and compiling an informative +changelog entry. Moreover, it supports distribution specific patches (plain, or +for format 3.0 (quilt) source packages) and allow modification of debian/control +via arbitrary 'sed' expressions. + +Backport relevant patches can be embedded in source packages for use with +backport-dsc. The distribution name (see --target-dsitribution) serves as an +identifier to search for patches in the source package that shall be applied +for a particular distribution. For packages using format the 3.0 (quilt), +backport-dsc will look for debian/patches/series- and append it to +the main patch series. Moreover, backport-dsc will also look for patches +matching /debian/patches/-dsc-patch* and apply them to the source +package. The latter patches, unlike the former quilt series, can also be used +to modify the debian/ directory itself. + +EOT +} + + +print_help() +{ +cat << EOT + +Usage: backport-dsc [OPTIONS] + + +Options: + +-d , --target-distribution + Arbitrary distribution name (e.g. lenny-backports). This will be the target + distribution used for the backport changelog entry. The distribution name + also serves as an identifier to search for backport patches in the source + package. + +-h, --help + Print short description, usage summary and option list. + +--maint-email + Specify the backport maintainer's email address. Alternatively, backport-dsc + will use the DEBEMAIL environment setting. + +--maint-name + Specify the backport maintainer's real name. Alternatively, backport-dsc will + use the DEBFULLNAME environment setting. + +--mod-control + sed expression to modify debian/control. The option can be given multiple + times and all expressions wil be passed to sed in the order of appearance. + This can be used to, e.g. change build or runtime dependencies. + +--no-backport-patches + If set, potentially existing backport patches will not be applied/activated. + +--no-colored + If set, backport-dsc won't colorize its status and error messages. + +--no-maintainer-update + If set, the orginal maintainer is preserved in the backported source package. + This should only be done if original maintainer and backporter are identical. + Otherwise the porter should take responsibility for the source package + backport and identify herself as the maintainer. + +-s , --version-suffix + Version suffix that will be appended to the orginal source package version, + ideally indicating the backport target distribution. The resulting package + version will follow this schema: + + ~+ + + e.g.: 1.2.3-4~bpo50+1 + +--verbose + Enable additional status messages. + +--verbose-help + Print all available help. + +--version + Print version information and exit. + +EOT +} + + +print_additional_description() +{ +cat << EOT + +Examples: + +backport-dsc examplepkg_1.2.3-4.dsc + Create backport suitable for backports.org + +backport-dsc -d myown-backports -v mo2010 examplepkg_1.2.3-4.dsc + Create backport for some custom distribution with custom version suffix. + +backport-dsc -d ubuntu-lucid -v myppa --mod-control "-e 's/iceweasel/firefox/g'" examplepkg_1.2.3-4.dsc + Create a backport for a fake ubuntu PPA repository, replacing all occurences + of iceweasel in debian/control with firefox. + + +Files: + +backport-dsc reads configuration from two files: system-wide from +/etc/backports-dsc and per user settings from \$HOME/.backport-dsc +(in that order). Both files have to be valid bash scripts that will +be sourced by backport-dsc. The following variables (each shown with an +example setting) can be used to pre-configure backport-dsc: + +bp_distribution="lenny-backports" + Backport target distribution (see --backport-distribution) + +bp_version_suffix="bpo50" + Version suffix (see --version-suffix) + +bp_maintainer_name="Unkown fellow" + Name of the backport maintainer (see --maint-name) + +bp_maintainer_email="user@example.net" + Email address of backport maintainer (see --maint-email) + +bp_apply_patches=1 + Whether or not to apply backport patches found in a source package. + (see --no-backport-patches) + +bp_color_output=1 + Enable or disable colored status output (see --no-color) + +bp_verbose=0 + Enable verbose status output (see --verbose) + +bp_mod_control="--mod-control 's/^Depends:.*$/&, mypackage/'" + sed expressions to modify debian/control, for example to add dependencies + (see --mod-control) + +bp_update_maintainer=1 + Whether or not to replace the original maintainer in the backported source + package (see --no-maintainer-update) + + +Environment: + +backport-dsc acknowledges the common environment variables DEBFULLNAME and +DEBEMAIL to specify the maintainer. + + + +Report bugs to . + +EOT +} + + + +################################ +# Commandline options handling # +################################ + +# Parse commandline options (taken from the getopt examples from the Debian util-linux package) +# Note that we use `"$@"' to let each command-line parameter expand to a +# separate word. The quotes around `$@' are essential! +# We need CLOPTS as the `eval set --' would nuke the return value of getopt. +CLOPTS=`getopt -o h,d:,s: --long help,verbose-help,version,target-distribution:,version-suffix:,maint-name:,maint-email:,no-color,no-backport-patches,verbose,mod-control:,no-maintainer-update, -n 'backport-dsc' -- "$@"` + +if [ $? != 0 ] ; then + echo "Terminating..." >&2 + exit 1 +fi + +# Note the quotes around `$CLOPTS': they are essential! +eval set -- "$CLOPTS" + +while true ; do + case "$1" in + -d|--target-distribution) shift; bp_distribution=$1; shift;; + -s|--version-suffix) shift; backport_version=$1; shift;; + --maint-name) shift; bp_maintainer_name=$1; shift;; + --maint-email) shift; bp_maintainer_email=$1; shift;; + --no-maintainer-update) bp_update_maintainer=0; shift;; + --no-backport-patches) apply_patches=0; shift;; + --no-color) bp_color_output=0; shift;; + --verbose) bp_verbose=1; shift;; + --mod-control) shift; bp_mod_control="$bp_mod_control -e '$1'"; shift;; + -h|--help) print_short_description; print_help; exit 0;; + --verbose-help) print_short_description; print_help; print_additional_description; exit 0;; + --version) print_version; exit 0;; + --) shift ; break ;; + *) echo "Internal error! ($1)"; exit 1;; + esac +done + +# colorful output requested? +if [ "$bp_color_output" = 1 ]; then + black='\e[0;30m'; Black='\e[1;30m' + red='\e[0;31m'; Red='\e[1;31m' + green='\e[0;32m'; Green='\e[1;32m' + yellow='\e[0;33m'; Yellow='\e[1;33m' + blue='\e[0;34m'; Blue='\e[1;34m' + cyan='\e[0;36m'; Cyan='\e[1;36m' + white='\e[0;37m'; White='\e[1;37m' + NC='\e[0m' #no color +else + black=''; Black='' + red=''; Red='' + green=''; Green='' + yellow=''; Yellow='' + blue=''; Blue='' + cyan=''; Cyan='' + white=''; White='' + NC='' #no color +fi + + +if [ $# -ne 1 ]; then + printf "${Red}Error: This command needs exactly one positional argument.\n${NC}" + exit 1 +fi + +# to be processed source package +dsc_file=$1 + +if [ ! -f "$dsc_file" ]; then + printf "${Red}Error: Cannot find DSC file at '$dsc_file'.\n${NC}" + exit 1 +fi + +# determine basic DSC properties +src_name=$(basename "${dsc_file%%_*}") +src_version=${dsc_file#*_} +src_version=${src_version%%.dsc} + +wdir=$(mktemp -d -t backport-dsc.XXXXXX) +sdir=$wdir/${src_name}-${src_version} + +bp_version="~${bp_version_suffix}+" + + +# setup environment for dpkg +DEBEMAIL="$bp_maintainer_email" +DEBFULLNAME="$bp_maintainer_name" +export DEBEMAIL DEBFULLNAME + +if [ "$bp_verbose" = 1 ]; then + printf "${green}DSC name: '$src_name'\nDSC version: '$src_version'\n${NC}" + printf "${green}Backporting to '$bp_distribution', version suffix '$bp_version'\n${NC}" + printf "${green}Extracting source package to '$sdir'\n${NC}" +fi + +# common debchange call +bp_dch_cmd="dch --noconf --force-distribution --force-bad-version -c $sdir/debian/changelog" + +# extract the original source package +dpkg-source -x $dsc_file $sdir +# note backport in changelog +$bp_dch_cmd -D ${bp_distribution} -l "${bp_version}" "Backported for ${bp_distribution}." + +if [ "$bp_update_maintainer" = 1 ]; then + if [ "$bp_verbose" = 1 ]; then + printf "${green}Set backport maintainer to: '$bp_maintainer_name <$bp_maintainer_email>'\n${NC}" + fi + bp_mod_control="$bp_mod_control -e 's/^Maintainer:.*$/Maintainer: $bp_maintainer_name <$bp_maintainer_email>\nX-Original-&/'" +fi + +# handle patches if desired +if [ "$bp_apply_patches" = 1 ]; then + dsc_format=$(dpkg-source --print-format $sdir) + # per each supported source package format + if [ "$dsc_format" = "3.0 (quilt)" -a -f "$sdir/debian/patches/series-$bp_distribution" ]; then + if [ "$bp_verbose" = 1 ]; then + printf "${green}Enabling additional quilt patch series for $bp_distribution.\n${NC}" + fi + cat $sdir/debian/patches/series-$bp_distribution >> $sdir/debian/patches/series + $bp_dch_cmd "Added 'series-$bp_distribution' in quilt patch series." + fi + # look for backport patches + for p in $(ls -1 $sdir/debian/patches/$bp_distribution-dsc-patch* 2> /dev/null || true); do + if [ "$bp_verbose" = 1 ]; then + printf "${green}Applying additional patch $(basename "$p").\n${NC}" + fi + patch -p1 --directory=$sdir < "$p" + $bp_dch_cmd "Applied additional patch from debian/patches/$(basename "$p")." + done +fi + +# modify control file +if [ -n "$bp_mod_control" ]; then + if [ "$bp_verbose" = 1 ]; then + printf "${green}Modifying debian/control with given instructions.\n${NC}" + fi + bash -c "sed -i $bp_mod_control $sdir/debian/control" + $bp_dch_cmd "Used following sed expression to modify debian/control:$bp_mod_control." +fi + +# extract final version +final_version=$(dpkg-parsechangelog -l$sdir/debian/changelog | egrep '^Version: ' | cut -d ' ' -f 2,2) +# build backported source package +bash -c "cd $wdir && dpkg-source -b $sdir" +# remove extracted source tree +rm -rf $sdir +# move generated source package into working dir +mv $wdir/* . +# cleanup +rm -rf $wdir + +if [ "$bp_verbose" = 1 ]; then + printf "${green}Backported source package is at '${src_name}_$final_version.dsc'\n${NC}" +fi -- 2.39.5