7 # version of this script
8 backports_dsc_version=0.2
14 bp_distribution=${BACKPORT_DISTRIBUTION:-squeeze-backports}
15 bp_version_prefix=${BACKPORT_VERSION_PREFIX:-\~}
16 bp_version_suffix=${BACKPORT_VERSION_SUFFIX:-bpo60}
17 bp_maintainer_name=${DEBFULLNAME:-unamed}
18 bp_maintainer_email=${DEBEMAIL:-unknown}
19 bp_update_maintainer=1
20 # whether or not to apply backport patches found in a package
22 # produce fancy colored output
24 # enables additional status message if set to true
26 # sed expressions to modify debian/control
31 if [ -f /etc/backport-dsc ]; then
35 # source user config files
36 if [ -f "$HOME/.backport-dsc" ]; then
44 backport-dsc $backports_dsc_version
46 Copyright (C) 2010-2012 Michael Hanke <michael.hanke@gmail.com>
48 Licensed under GNU Public License version 2 or later.
49 This is free software; see the source for copying conditions. There is NO
50 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
52 Written by Michael Hanke for the NeuroDebian project.
58 print_short_description()
61 Helper to aid backporting a Debian source package to an arbitrary distribution
64 backport-dsc aids backporting by appropriately mangling the source package
65 version, adjusting the maintainer of a package and compiling an informative
66 changelog entry. Moreover, it supports distribution specific patches (plain, or
67 for format 3.0 (quilt) source packages) and allow modification of debian/control
68 via arbitrary 'sed' expressions.
70 Backport relevant patches can be embedded in source packages for use with
71 backport-dsc. The distribution name (see --target-distribution) serves as an
72 identifier to search for patches in the source package that shall be applied
73 for a particular distribution. For packages using format the 3.0 (quilt),
74 backport-dsc will look for debian/patches/series-<distname> and append it to
75 the main patch series. Moreover, backport-dsc will also look for patches
76 matching /debian/patches/<distname>-dsc-patch* and apply them to the source
77 package. The latter patches, unlike the former quilt series, can also be used
78 to modify the debian/ directory itself.
88 Usage: backport-dsc [OPTIONS] <dsc-file>
93 -d <distname>, --target-distribution <distname>
94 Arbitrary distribution name (e.g. squeeze-backports). This will be the target
95 distribution used for the backport changelog entry. The distribution name
96 also serves as an identifier to search for backport patches in the source
100 Print short description, usage summary and option list.
102 --maint-email <email>
103 Specify the backport maintainer's email address. Alternatively, backport-dsc
104 will use the DEBEMAIL environment setting.
107 Specify the backport maintainer's real name. Alternatively, backport-dsc will
108 use the DEBFULLNAME environment setting.
110 --mod-control <expression>
111 sed expression to modify debian/control. The option can be given multiple
112 times and all expressions will be passed to sed in the order of appearance.
113 This can be used to, e.g. change build or runtime dependencies.
115 --no-backport-patches
116 If set, potentially existing backport patches will not be applied/activated.
119 If set, backport-dsc won't colorize its status and error messages.
121 --no-maintainer-update
122 If set, the orginal maintainer is preserved in the backported source package.
123 This should only be done if original maintainer and backporter are identical.
124 Otherwise the porter should take responsibility for the source package
125 backport and identify herself as the maintainer.
127 -s <string>, --version-suffix <string>
128 Version suffix that will be appended to the original source package version,
129 ideally indicating the backport target distribution. The resulting package
130 version will follow this schema:
132 <originalversion><prefix><suffix>+<digit>
134 e.g.: 1.2.3-4~bpo60+1 with default <prefix>=~
136 -p <string>, --version-prefix <string>
137 Version prefix that will be prepended to the backport version. By default it
138 is ~ but want to be changed (e.g. to +) for forward-porting to next releases.
141 Enable additional status messages.
144 Print all available help.
147 Print version information and exit.
153 print_additional_description()
159 backport-dsc examplepkg_1.2.3-4.dsc
160 Create backport suitable for backports.org
162 backport-dsc -d myown-backports -v mo2010 examplepkg_1.2.3-4.dsc
163 Create backport for some custom distribution with custom version suffix.
165 backport-dsc -d ubuntu-lucid -v myppa --mod-control "-e 's/iceweasel/firefox/g'" examplepkg_1.2.3-4.dsc
166 Create a backport for a fake Ubuntu PPA repository, replacing all occurrences
167 of iceweasel in debian/control with firefox.
172 backport-dsc reads configuration from two files: system-wide from
173 /etc/backports-dsc and per user settings from \$HOME/.backport-dsc
174 (in that order). Both files have to be valid bash scripts that will
175 be sourced by backport-dsc. The following variables (each shown with an
176 example setting) can be used to pre-configure backport-dsc:
178 bp_distribution="squeeze-backports"
179 Backport target distribution (see --backport-distribution)
181 bp_version_prefix="~"
182 Version prefix (see --version-prefix)
184 bp_version_suffix="bpo60"
185 Version suffix (see --version-suffix)
187 bp_maintainer_name="Unknown fellow"
188 Name of the backport maintainer (see --maint-name)
190 bp_maintainer_email="user@example.net"
191 Email address of backport maintainer (see --maint-email)
194 Whether or not to apply backport patches found in a source package.
195 (see --no-backport-patches)
198 Enable or disable colored status output (see --no-color)
201 Enable verbose status output (see --verbose)
203 bp_mod_control="--mod-control 's/^Depends:.*$/&, mypackage/'"
204 sed expressions to modify debian/control, for example to add dependencies
207 bp_update_maintainer=1
208 Whether or not to replace the original maintainer in the backported source
209 package (see --no-maintainer-update)
214 backport-dsc acknowledges the common environment variables DEBFULLNAME and
215 DEBEMAIL to specify the maintainer.
219 Report bugs to <michael.hanke@gmail.com>.
226 ################################
227 # Commandline options handling #
228 ################################
230 # Parse commandline options (taken from the getopt examples from the Debian util-linux package)
231 # Note that we use `"$@"' to let each command-line parameter expand to a
232 # separate word. The quotes around `$@' are essential!
233 # We need CLOPTS as the `eval set --' would nuke the return value of getopt.
234 CLOPTS=`getopt -o h,d:,s:,p: --long help,verbose-help,version,target-distribution:,version-suffix:,version-prefix:,maint-name:,maint-email:,no-color,no-backport-patches,verbose,mod-control:,no-maintainer-update, -n 'backport-dsc' -- "$@"`
236 if [ $? != 0 ] ; then
237 echo "Terminating..." >&2
241 # Note the quotes around `$CLOPTS': they are essential!
242 eval set -- "$CLOPTS"
246 -d|--target-distribution) shift; bp_distribution=$1; shift;;
247 -s|--version-suffix) shift; bp_version_suffix=$1; shift;;
248 -p|--version-prefix) shift; bp_version_prefix=$1; shift;;
249 --maint-name) shift; bp_maintainer_name=$1; shift;;
250 --maint-email) shift; bp_maintainer_email=$1; shift;;
251 --no-maintainer-update) bp_update_maintainer=0; shift;;
252 --no-backport-patches) apply_patches=0; shift;;
253 --no-color) bp_color_output=0; shift;;
254 --verbose) bp_verbose=1; shift;;
255 --mod-control) shift; bp_mod_control="$bp_mod_control -e '$1'"; shift;;
256 -h|--help) print_short_description; print_help; exit 0;;
257 --verbose-help) print_short_description; print_help; print_additional_description; exit 0;;
258 --version) print_version; exit 0;;
260 *) echo "Internal error! ($1)"; exit 1;;
264 # colorful output requested?
265 if [ "$bp_color_output" = 1 ]; then
266 black='\e[0;30m'; Black='\e[1;30m'
267 red='\e[0;31m'; Red='\e[1;31m'
268 green='\e[0;32m'; Green='\e[1;32m'
269 yellow='\e[0;33m'; Yellow='\e[1;33m'
270 blue='\e[0;34m'; Blue='\e[1;34m'
271 cyan='\e[0;36m'; Cyan='\e[1;36m'
272 white='\e[0;37m'; White='\e[1;37m'
286 if [ $# -ne 1 ]; then
287 printf "${Red}Error: This command needs exactly one positional argument.\n${NC}"
291 # to be processed source package
294 if [ ! -f "$dsc_file" ]; then
295 printf "${Red}Error: Cannot find DSC file at '$dsc_file'.\n${NC}"
299 # determine basic DSC properties
300 src_name=$(basename "${dsc_file%%_*}")
301 src_version=${dsc_file#*_}
302 src_version=${src_version%%.dsc}
304 wdir=$(mktemp -d -t backport-dsc.XXXXXX)
305 sdir=$wdir/${src_name}-${src_version}
307 bp_version="${bp_version_prefix}${bp_version_suffix}+"
310 # setup environment for dpkg
311 DEBEMAIL="$bp_maintainer_email"
312 DEBFULLNAME="$bp_maintainer_name"
313 export DEBEMAIL DEBFULLNAME
315 if [ "$bp_verbose" = 1 ]; then
316 printf "${green}DSC name: '$src_name'\nDSC version: '$src_version'\n${NC}"
317 printf "${green}Backporting to '$bp_distribution', version suffix '$bp_version'\n${NC}"
318 printf "${green}Extracting source package to '$sdir'\n${NC}"
321 # common debchange call
322 bp_dch_cmd="dch --noconf --force-distribution --force-bad-version -c $sdir/debian/changelog"
324 # extract the original source package
325 dpkg-source -x $dsc_file $sdir
326 # note backport in changelog
327 # This will create a new changelog entry
328 # All subsequent calls to dch should use -a to assure that those entries
329 # are appended to the existing entry (otherwise with wheezy new entries will be added)
330 $bp_dch_cmd -D ${bp_distribution} -l "${bp_version}" "Backported for ${bp_distribution}."
332 if [ "$bp_update_maintainer" = 1 ]; then
333 if [ "$bp_verbose" = 1 ]; then
334 printf "${green}Set backport maintainer to: '$bp_maintainer_name <$bp_maintainer_email>'\n${NC}"
336 bp_mod_control="$bp_mod_control -e 's/^Maintainer:.*$/Maintainer: $bp_maintainer_name <$bp_maintainer_email>\nX-Original-&/'"
339 # handle patches if desired
340 if [ "$bp_apply_patches" = 1 ]; then
341 dsc_format=$(dpkg-source --print-format $sdir)
342 # per each supported source package format
343 if [ "$dsc_format" = "3.0 (quilt)" -a -f "$sdir/debian/patches/series-$bp_distribution" ]; then
344 if [ "$bp_verbose" = 1 ]; then
345 printf "${green}Enabling additional quilt patch series for $bp_distribution.\n${NC}"
347 cat $sdir/debian/patches/series-$bp_distribution >> $sdir/debian/patches/series
348 $bp_dch_cmd -a "Added 'series-$bp_distribution' in quilt patch series."
350 # look for backport patches
351 for p in $(ls -1 $sdir/debian/patches/$bp_distribution-dsc-patch* 2> /dev/null || true); do
352 if [ "$bp_verbose" = 1 ]; then
353 printf "${green}Applying additional patch $(basename "$p").\n${NC}"
355 patch -p1 --directory=$sdir < "$p"
356 $bp_dch_cmd -a "Applied additional patch from debian/patches/$(basename "$p")."
360 # modify control file
361 if [ -n "$bp_mod_control" ]; then
362 if [ "$bp_verbose" = 1 ]; then
363 printf "${green}Modifying debian/control with given instructions.\n${NC}"
365 bash -c "sed -i $bp_mod_control $sdir/debian/control"
366 $bp_dch_cmd -a "Used following sed expression to modify debian/control:$bp_mod_control."
369 # extract final version
370 final_version=$(dpkg-parsechangelog -l$sdir/debian/changelog | egrep '^Version: ' | cut -d ' ' -f 2,2)
371 # build backported source package
372 bash -c "cd $wdir && dpkg-source -b $sdir"
373 # remove extracted source tree
375 # move generated source package into working dir
380 if [ "$bp_verbose" = 1 ]; then
381 printf "${green}Backported source package is at '${src_name}_$final_version.dsc'\n${NC}"