7 # version of this script
8 backports_dsc_version=0.1
14 bp_distribution=${BACKPORT_DISTRIBUTION:-lenny-backports}
15 bp_version_suffix=${BACKPORT_VERSION_SUFFIX:-bpo50}
16 bp_maintainer_name=${DEBFULLNAME:-unamed}
17 bp_maintainer_email=${DEBEMAIL:-unknown}
18 bp_update_maintainer=1
19 # whether or not to apply backport patches found in a package
21 # produce fancy colored output
23 # enables additional status message if set to true
25 # sed expressions to modify debian/control
30 if [ -f /etc/backport-dsc ]; then
34 # source user config files
35 if [ -f "$HOME/.backport-dsc" ]; then
43 backport-dsc $backports_dsc_version
45 Copyright (C) 2010 Michael Hanke <michael.hanke@gmail.com>
47 Licensed under GNU Public License version 2 or later.
48 This is free software; see the source for copying conditions. There is NO
49 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
51 Written by Michael Hanke for the NeuroDebian project.
57 print_short_description()
60 Helper to aid backporting a Debian source package to an arbitrary distribution
63 backport-dsc aids backporting by appropriately mangling the source package
64 version, adjusting the maintainer of a package and compiling an informative
65 changelog entry. Moreover, it supports distribution specific patches (plain, or
66 for format 3.0 (quilt) source packages) and allow modification of debian/control
67 via arbitrary 'sed' expressions.
69 Backport relevant patches can be embedded in source packages for use with
70 backport-dsc. The distribution name (see --target-dsitribution) serves as an
71 identifier to search for patches in the source package that shall be applied
72 for a particular distribution. For packages using format the 3.0 (quilt),
73 backport-dsc will look for debian/patches/series-<distname> and append it to
74 the main patch series. Moreover, backport-dsc will also look for patches
75 matching /debian/patches/<distname>-dsc-patch* and apply them to the source
76 package. The latter patches, unlike the former quilt series, can also be used
77 to modify the debian/ directory itself.
87 Usage: backport-dsc [OPTIONS] <dsc-file>
92 -d <distname>, --target-distribution <distname>
93 Arbitrary distribution name (e.g. lenny-backports). This will be the target
94 distribution used for the backport changelog entry. The distribution name
95 also serves as an identifier to search for backport patches in the source
99 Print short description, usage summary and option list.
101 --maint-email <email>
102 Specify the backport maintainer's email address. Alternatively, backport-dsc
103 will use the DEBEMAIL environment setting.
106 Specify the backport maintainer's real name. Alternatively, backport-dsc will
107 use the DEBFULLNAME environment setting.
109 --mod-control <expression>
110 sed expression to modify debian/control. The option can be given multiple
111 times and all expressions wil be passed to sed in the order of appearance.
112 This can be used to, e.g. change build or runtime dependencies.
114 --no-backport-patches
115 If set, potentially existing backport patches will not be applied/activated.
118 If set, backport-dsc won't colorize its status and error messages.
120 --no-maintainer-update
121 If set, the orginal maintainer is preserved in the backported source package.
122 This should only be done if original maintainer and backporter are identical.
123 Otherwise the porter should take responsibility for the source package
124 backport and identify herself as the maintainer.
126 -s <string>, --version-suffix <string>
127 Version suffix that will be appended to the orginal source package version,
128 ideally indicating the backport target distribution. The resulting package
129 version will follow this schema:
131 <originalversion>~<suffix>+<digit>
133 e.g.: 1.2.3-4~bpo50+1
136 Enable additional status messages.
139 Print all available help.
142 Print version information and exit.
148 print_additional_description()
154 backport-dsc examplepkg_1.2.3-4.dsc
155 Create backport suitable for backports.org
157 backport-dsc -d myown-backports -v mo2010 examplepkg_1.2.3-4.dsc
158 Create backport for some custom distribution with custom version suffix.
160 backport-dsc -d ubuntu-lucid -v myppa --mod-control "-e 's/iceweasel/firefox/g'" examplepkg_1.2.3-4.dsc
161 Create a backport for a fake ubuntu PPA repository, replacing all occurences
162 of iceweasel in debian/control with firefox.
167 backport-dsc reads configuration from two files: system-wide from
168 /etc/backports-dsc and per user settings from \$HOME/.backport-dsc
169 (in that order). Both files have to be valid bash scripts that will
170 be sourced by backport-dsc. The following variables (each shown with an
171 example setting) can be used to pre-configure backport-dsc:
173 bp_distribution="lenny-backports"
174 Backport target distribution (see --backport-distribution)
176 bp_version_suffix="bpo50"
177 Version suffix (see --version-suffix)
179 bp_maintainer_name="Unkown fellow"
180 Name of the backport maintainer (see --maint-name)
182 bp_maintainer_email="user@example.net"
183 Email address of backport maintainer (see --maint-email)
186 Whether or not to apply backport patches found in a source package.
187 (see --no-backport-patches)
190 Enable or disable colored status output (see --no-color)
193 Enable verbose status output (see --verbose)
195 bp_mod_control="--mod-control 's/^Depends:.*$/&, mypackage/'"
196 sed expressions to modify debian/control, for example to add dependencies
199 bp_update_maintainer=1
200 Whether or not to replace the original maintainer in the backported source
201 package (see --no-maintainer-update)
206 backport-dsc acknowledges the common environment variables DEBFULLNAME and
207 DEBEMAIL to specify the maintainer.
211 Report bugs to <michael.hanke@gmail.com>.
218 ################################
219 # Commandline options handling #
220 ################################
222 # Parse commandline options (taken from the getopt examples from the Debian util-linux package)
223 # Note that we use `"$@"' to let each command-line parameter expand to a
224 # separate word. The quotes around `$@' are essential!
225 # We need CLOPTS as the `eval set --' would nuke the return value of getopt.
226 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' -- "$@"`
228 if [ $? != 0 ] ; then
229 echo "Terminating..." >&2
233 # Note the quotes around `$CLOPTS': they are essential!
234 eval set -- "$CLOPTS"
238 -d|--target-distribution) shift; bp_distribution=$1; shift;;
239 -s|--version-suffix) shift; backport_version=$1; shift;;
240 --maint-name) shift; bp_maintainer_name=$1; shift;;
241 --maint-email) shift; bp_maintainer_email=$1; shift;;
242 --no-maintainer-update) bp_update_maintainer=0; shift;;
243 --no-backport-patches) apply_patches=0; shift;;
244 --no-color) bp_color_output=0; shift;;
245 --verbose) bp_verbose=1; shift;;
246 --mod-control) shift; bp_mod_control="$bp_mod_control -e '$1'"; shift;;
247 -h|--help) print_short_description; print_help; exit 0;;
248 --verbose-help) print_short_description; print_help; print_additional_description; exit 0;;
249 --version) print_version; exit 0;;
251 *) echo "Internal error! ($1)"; exit 1;;
255 # colorful output requested?
256 if [ "$bp_color_output" = 1 ]; then
257 black='\e[0;30m'; Black='\e[1;30m'
258 red='\e[0;31m'; Red='\e[1;31m'
259 green='\e[0;32m'; Green='\e[1;32m'
260 yellow='\e[0;33m'; Yellow='\e[1;33m'
261 blue='\e[0;34m'; Blue='\e[1;34m'
262 cyan='\e[0;36m'; Cyan='\e[1;36m'
263 white='\e[0;37m'; White='\e[1;37m'
277 if [ $# -ne 1 ]; then
278 printf "${Red}Error: This command needs exactly one positional argument.\n${NC}"
282 # to be processed source package
285 if [ ! -f "$dsc_file" ]; then
286 printf "${Red}Error: Cannot find DSC file at '$dsc_file'.\n${NC}"
290 # determine basic DSC properties
291 src_name=$(basename "${dsc_file%%_*}")
292 src_version=${dsc_file#*_}
293 src_version=${src_version%%.dsc}
295 wdir=$(mktemp -d -t backport-dsc.XXXXXX)
296 sdir=$wdir/${src_name}-${src_version}
298 bp_version="~${bp_version_suffix}+"
301 # setup environment for dpkg
302 DEBEMAIL="$bp_maintainer_email"
303 DEBFULLNAME="$bp_maintainer_name"
304 export DEBEMAIL DEBFULLNAME
306 if [ "$bp_verbose" = 1 ]; then
307 printf "${green}DSC name: '$src_name'\nDSC version: '$src_version'\n${NC}"
308 printf "${green}Backporting to '$bp_distribution', version suffix '$bp_version'\n${NC}"
309 printf "${green}Extracting source package to '$sdir'\n${NC}"
312 # common debchange call
313 bp_dch_cmd="dch --noconf --force-distribution --force-bad-version -c $sdir/debian/changelog"
315 # extract the original source package
316 dpkg-source -x $dsc_file $sdir
317 # note backport in changelog
318 $bp_dch_cmd -D ${bp_distribution} -l "${bp_version}" "Backported for ${bp_distribution}."
320 if [ "$bp_update_maintainer" = 1 ]; then
321 if [ "$bp_verbose" = 1 ]; then
322 printf "${green}Set backport maintainer to: '$bp_maintainer_name <$bp_maintainer_email>'\n${NC}"
324 bp_mod_control="$bp_mod_control -e 's/^Maintainer:.*$/Maintainer: $bp_maintainer_name <$bp_maintainer_email>\nX-Original-&/'"
327 # handle patches if desired
328 if [ "$bp_apply_patches" = 1 ]; then
329 dsc_format=$(dpkg-source --print-format $sdir)
330 # per each supported source package format
331 if [ "$dsc_format" = "3.0 (quilt)" -a -f "$sdir/debian/patches/series-$bp_distribution" ]; then
332 if [ "$bp_verbose" = 1 ]; then
333 printf "${green}Enabling additional quilt patch series for $bp_distribution.\n${NC}"
335 cat $sdir/debian/patches/series-$bp_distribution >> $sdir/debian/patches/series
336 $bp_dch_cmd "Added 'series-$bp_distribution' in quilt patch series."
338 # look for backport patches
339 for p in $(ls -1 $sdir/debian/patches/$bp_distribution-dsc-patch* 2> /dev/null || true); do
340 if [ "$bp_verbose" = 1 ]; then
341 printf "${green}Applying additional patch $(basename "$p").\n${NC}"
343 patch -p1 --directory=$sdir < "$p"
344 $bp_dch_cmd "Applied additional patch from debian/patches/$(basename "$p")."
348 # modify control file
349 if [ -n "$bp_mod_control" ]; then
350 if [ "$bp_verbose" = 1 ]; then
351 printf "${green}Modifying debian/control with given instructions.\n${NC}"
353 bash -c "sed -i $bp_mod_control $sdir/debian/control"
354 $bp_dch_cmd "Used following sed expression to modify debian/control:$bp_mod_control."
357 # extract final version
358 final_version=$(dpkg-parsechangelog -l$sdir/debian/changelog | egrep '^Version: ' | cut -d ' ' -f 2,2)
359 # build backported source package
360 bash -c "cd $wdir && dpkg-source -b $sdir"
361 # remove extracted source tree
363 # move generated source package into working dir
368 if [ "$bp_verbose" = 1 ]; then
369 printf "${green}Backported source package is at '${src_name}_$final_version.dsc'\n${NC}"