]> git.donarmstrong.com Git - neurodebian.git/blob - tools/backport-dsc
Draft of a new backporting helper.
[neurodebian.git] / tools / backport-dsc
1 #!/bin/bash
2
3 # play save
4 set -e
5 set -u
6
7 # version of this script
8 backports_dsc_version=0.1
9
10 ############
11 # Defaults #
12 ############
13
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
20 bp_apply_patches=1
21 # produce fancy colored output
22 bp_color_output=1
23 # enables additional status message if set to true
24 bp_verbose=0
25 # sed expressions to modify debian/control
26 bp_mod_control=""
27
28
29 # source config files
30 if [ -f /etc/backport-dsc ]; then
31     . /etc/backport-dsc
32 fi
33
34 # source user config files
35 if [ -f "$HOME/.backport-dsc" ]; then
36     . $HOME/.backport-dsc
37 fi
38
39
40 print_version()
41 {
42 cat << EOT
43 backport-dsc $backports_dsc_version
44
45 Copyright (C) 2010 Michael Hanke <michael.hanke@gmail.com>
46
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.
50
51 Written by Michael Hanke for the NeuroDebian project.
52
53 EOT
54 }
55
56
57 print_short_description()
58 {
59 cat << EOT
60 Helper to aid backporting a Debian source package to an arbitrary distribution
61 release.
62
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.
68
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.
78
79 EOT
80 }
81
82
83 print_help()
84 {
85 cat << EOT
86
87 Usage:  backport-dsc [OPTIONS] <dsc-file>
88
89
90 Options:
91
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
96   package.
97
98 -h, --help
99   Print short description, usage summary and option list.
100
101 --maint-email <email>
102   Specify the backport maintainer's email address. Alternatively, backport-dsc
103   will use the DEBEMAIL environment setting.
104
105 --maint-name <name>
106   Specify the backport maintainer's real name. Alternatively, backport-dsc will
107   use the DEBFULLNAME environment setting.
108
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.
113
114 --no-backport-patches
115   If set, potentially existing backport patches will not be applied/activated.
116
117 --no-colored
118   If set, backport-dsc won't colorize its status and error messages.
119
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.
125
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:
130
131   <originalversion>~<suffix>+<digit>
132
133   e.g.: 1.2.3-4~bpo50+1
134
135 --verbose
136   Enable additional status messages.
137
138 --verbose-help
139   Print all available help.
140
141 --version
142   Print version information and exit.
143
144 EOT
145 }
146
147
148 print_additional_description()
149 {
150 cat << EOT
151
152 Examples:
153
154 backport-dsc examplepkg_1.2.3-4.dsc
155   Create backport suitable for backports.org
156
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.
159
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.
163
164
165 Files:
166
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:
172
173 bp_distribution="lenny-backports"
174   Backport target distribution (see --backport-distribution)
175
176 bp_version_suffix="bpo50"
177   Version suffix (see --version-suffix)
178
179 bp_maintainer_name="Unkown fellow"
180   Name of the backport maintainer (see --maint-name)
181
182 bp_maintainer_email="user@example.net"
183   Email address of backport maintainer (see --maint-email)
184
185 bp_apply_patches=1
186   Whether or not to apply backport patches found in a source package.
187   (see --no-backport-patches)
188
189 bp_color_output=1
190   Enable or disable colored status output (see --no-color)
191
192 bp_verbose=0
193   Enable verbose status output (see --verbose)
194
195 bp_mod_control="--mod-control 's/^Depends:.*$/&, mypackage/'"
196   sed expressions to modify debian/control, for example to add dependencies
197   (see --mod-control)
198
199 bp_update_maintainer=1
200   Whether or not to replace the original maintainer in the backported source
201   package (see --no-maintainer-update)
202
203
204 Environment:
205
206 backport-dsc acknowledges the common environment variables DEBFULLNAME and
207 DEBEMAIL to specify the maintainer.
208
209
210
211 Report bugs to <michael.hanke@gmail.com>.
212
213 EOT
214 }
215
216
217
218 ################################
219 # Commandline options handling #
220 ################################
221
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' -- "$@"`
227
228 if [ $? != 0 ] ; then
229   echo "Terminating..." >&2
230   exit 1
231 fi
232
233 # Note the quotes around `$CLOPTS': they are essential!
234 eval set -- "$CLOPTS"
235
236 while true ; do
237   case "$1" in
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;;
250           --) shift ; break ;;
251           *) echo "Internal error! ($1)"; exit 1;;
252   esac
253 done
254
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'
264   NC='\e[0m' #no color
265 else
266   black=''; Black=''
267   red=''; Red=''
268   green=''; Green=''
269   yellow=''; Yellow=''
270   blue=''; Blue=''
271   cyan=''; Cyan=''
272   white=''; White=''
273   NC='' #no color
274 fi
275
276
277 if [ $# -ne 1 ]; then
278   printf "${Red}Error: This command needs exactly one positional argument.\n${NC}"
279   exit 1
280 fi
281
282 # to be processed source package
283 dsc_file=$1
284
285 if [ ! -f "$dsc_file" ]; then
286   printf "${Red}Error: Cannot find DSC file at '$dsc_file'.\n${NC}"
287   exit 1
288 fi
289
290 # determine basic DSC properties
291 src_name=$(basename "${dsc_file%%_*}")
292 src_version=${dsc_file#*_}
293 src_version=${src_version%%.dsc}
294
295 wdir=$(mktemp -d -t backport-dsc.XXXXXX)
296 sdir=$wdir/${src_name}-${src_version}
297
298 bp_version="~${bp_version_suffix}+"
299
300
301 # setup environment for dpkg
302 DEBEMAIL="$bp_maintainer_email"
303 DEBFULLNAME="$bp_maintainer_name"
304 export DEBEMAIL DEBFULLNAME
305
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}"
310 fi
311
312 # common debchange call
313 bp_dch_cmd="dch --noconf --force-distribution --force-bad-version -c $sdir/debian/changelog"
314
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}."
319
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}"
323   fi
324   bp_mod_control="$bp_mod_control -e 's/^Maintainer:.*$/Maintainer: $bp_maintainer_name <$bp_maintainer_email>\nX-Original-&/'"
325 fi
326
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}"
334     fi
335     cat $sdir/debian/patches/series-$bp_distribution >> $sdir/debian/patches/series
336     $bp_dch_cmd "Added 'series-$bp_distribution' in quilt patch series."
337   fi
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}"
342     fi
343     patch -p1 --directory=$sdir < "$p"
344     $bp_dch_cmd "Applied additional patch from debian/patches/$(basename "$p")."
345   done
346 fi
347
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}"
352   fi
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."
355 fi
356
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
362 rm -rf $sdir
363 # move generated source package into working dir
364 mv $wdir/* .
365 # cleanup
366 rm -rf $wdir
367
368 if [ "$bp_verbose" = 1 ]; then
369   printf "${green}Backported source package is at '${src_name}_$final_version.dsc'\n${NC}"
370 fi