el/dot-emacs.el: Show italic characters in manpages correctly where possible.
[profile] / bin / mdw-build
CommitLineData
7ee12623
MW
1#! /bin/bash
2###
3### Build script for Debian packages
4###
5### (c) 2008 Mark Wooding
6###
7
8###----- Licensing notice ---------------------------------------------------
9###
10### This program is free software; you can redistribute it and/or modify
11### it under the terms of the GNU General Public License as published by
12### the Free Software Foundation; either version 2 of the License, or
13### (at your option) any later version.
14###
15### This program is distributed in the hope that it will be useful,
16### but WITHOUT ANY WARRANTY; without even the implied warranty of
17### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18### GNU General Public License for more details.
19###
20### You should have received a copy of the GNU General Public License
21### along with this program; if not, write to the Free Software Foundation,
22### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
85b7c21c
MW
24###--------------------------------------------------------------------------
25### Conventions for build systems.
26###
27### This script is designed to work with a variety of `make'-based build
28### systems, but there are a number of conventions which must be followed if
29### this is going to work properly.
30###
31### * There must be a `configure.ac', `configure.in', or `.links' file, or
32### a `.git' directory in the project top-level, so that we can find it.
33###
34### * The following `make' variables must be assigned in the top-level
35### Makefile, after `mdw-build' has constructed it.
36###
37### distdir The name of the top-level project directory in the
38### source distribution, and the base name for
39### distribution archives; should be of the form
40### `PROJECT-VERSION'.
41###
42### The following `make' targets must be available in the top-level
43### Makefile.
44###
45### dist Write to $(distdir).tar.gz a source distribution of
46### the package.
47###
48### distcheck As for `dist', but also build and test the project.
49###
50### * The source distribution constructed by `make dist' must contain a file
51### $(distdir)/RELEASE containing the release name. This isn't currently
52### tested, but it might be later.
53
7ee12623
MW
54set -e
55
56###--------------------------------------------------------------------------
816af8ee
MW
57### Configuration.
58
59unset checkout checkoutrev
60unset setup setupcmd
5a91acc5 61unset sign signkey
b94830d9 62unset sbuild sbuildsrv
5a91acc5 63unset upload uploadpath
816af8ee 64unset dput dputtarget
5a91acc5 65unset build distcheck debian clean vpath native
816af8ee
MW
66for i in \
67 "/etc/mdw-build.conf" \
68 "${XDG_CONFIG_HOME-$HOME/.config}/mdw-build.conf" \
69 "./.mdw-build.conf"
70do
71 if [ -f "$i" ]; then . "$i"; fi
72done
5a91acc5
MW
73default_depends () {
74 var=$1 want=$2
75 eval "p=\${$var+t} q=\${$want+t}"
76 case $p,$q in t,*) ;; *,t) eval "$var=yes" ;; *) eval "$var=no" ;; esac
77}
816af8ee
MW
78: ${checkout=yes} ${checkoutrev=HEAD}
79: ${build=test}
80: ${setup=yes} ${setupcmd=mdw-setup}
81: ${distcheck=yes}
82: ${debian=yes}
816af8ee
MW
83: ${clean=yes}
84: ${vpath=yes}
85: ${native=yes}
b94830d9 86default_depends sbuild sbuildsrv
5a91acc5
MW
87default_depends sign signkey
88default_depends upload uploadpath
89default_depends dput dputtarget
816af8ee
MW
90: ${DEB_BUILD_OPTIONS=parallel=4}; export DEB_BUILD_OPTIONS
91
92###--------------------------------------------------------------------------
7ee12623
MW
93### Parse options.
94
0660d224
MW
95prog=${0##*/}
96
7ee12623
MW
97usage () {
98 cat <<EOF
24a3095a 99Usage: $prog [-v] BUILDOPT
7ee12623
MW
100
101Build options:
102
103 [no]checkout[=REV]
104 [no]release
9c586ae1 105 [no]setup[=RUNE]
7ee12623
MW
106 [no]distcheck
107 [no]debian
5a91acc5
MW
108 [no]upload[=SERVER:PATH]
109 [no]dput[=TARGET]
7ee12623 110 [no]clean
f5b3423e 111 [no]vpath
b94830d9 112 [no]sbuild[=SERVER]
5a91acc5 113 [no]sign[=KEYID]
d87d7867 114 [no]native
7ee12623
MW
115EOF
116}
117
118## Parse simple options.
119verbose=no
24a3095a 120while getopts "hv" opt; do
7ee12623
MW
121 case "$opt" in
122 h) usage; exit 0 ;;
123 v) verbose=yes ;;
124 *) exit 1 ;;
125 esac
126done
127shift $((OPTIND - 1))
128
129## Parse the build options.
5a91acc5
MW
130maybe_set () {
131 var=$1 want=$2
132 eval "p=\${$want+t}\${$want-nil}"
133 case $p in
134 t) eval $var=yes ;;
135 nil) echo >&2 "$prog: $want not set"; exit 1 ;;
136 esac
137}
7ee12623
MW
138for opt; do
139 case "$opt" in
140 checkout) checkout=yes checkoutrev=HEAD ;;
141 checkout=*) checkout=yes checkoutrev=${opt#*=} ;;
7ee12623
MW
142 release) build=release ;;
143 norelease) build=test ;;
9c586ae1
MW
144 setup) setup=yes setupcmd=mdw-setup ;;
145 setup=*) setup=yes setupcmd=${opt#*=} ;;
5a91acc5
MW
146 upload) maybe_set upload uploadpath ;;
147 upload=*) upload=yes uploadpath=${opt#*=} ;;
148 sign) maybe_set sign signkey ;;
149 sign=*) sign=yes signkey=${opt#*=} ;;
b94830d9
MW
150 sbuild) maybe_set sbuild sbuildsrv ;;
151 sbuild=*) sbuild=yes sbuildsrv=${opt#*=} ;;
5a91acc5
MW
152 dput) maybe_set dput dputtarget ;;
153 dput=*) dput=yes dputtarget=${opt#*=} ;;
154
155 distcheck | debian | clean | vpath | native)
7ee12623
MW
156 eval "$opt=yes"
157 ;;
50c72b0f 158 nocheckout | nosetup | nodistcheck | nodebian | \
b94830d9 159 noupload | nodput | noclean | novpath | nonative | nosbuild | nosign)
7ee12623
MW
160 eval "${opt#no}=no"
161 ;;
162 *)
163 usage >&2
164 exit 1
165 ;;
166 esac
167done
168
84dd9069
MW
169## Parse DEB_BUILD_OPTIONS.
170jobs=1
171set -- $DEB_BUILD_OPTIONS
172for opt; do
173 case "$opt" in
174 parallel=*) jobs=${opt#*=} ;;
175 esac
176done
177
178makeopts=""
179case $jobs in 1) ;; *) makeopts="$makeopts -j$jobs" ;; esac
180
7ee12623
MW
181###--------------------------------------------------------------------------
182### Utility functions.
183
184exec 3>&2 4>/dev/null 5>&2
185
186notify () {
187 colour=$1 message=$2
188 echo $message >&4
189 echo "$(tput bold; tput setaf $colour)$message$(tput sgr0; tput op)" >&5
190}
191
192fail () {
193 notify 1 "!!! $*"
194 exit 1
195}
196
f282ba46
MW
197warn () {
198 case $build in
199 release) fail "$*" ;;
200 *) notify 5 "??? $*" ;;
201 esac
202}
203
7ee12623
MW
204info () {
205 notify 6 "--- $*"
206}
207
208assign () {
209 info "$1 = $2"
210 eval "$1=$2"
211}
212
213runx () {
214 notify 2 "+++ $*"
215 "$@" 2>&3 || fail "$1: exit $?"
216}
217
218run () { runx "$@" >&3; }
219
220yesno () {
221 echo -n "(test $*)" >&4
222 if "$@" >&4 2>&4; then
223 echo "(yes)" >&4
224 echo yes
225 else
226 echo "(no)" >&4
227 echo no
228 fi
229}
230
231###--------------------------------------------------------------------------
232### Do the building.
233
234## Find the top-level package directory.
d43de82b
MW
235while [ ! -f configure.ac -a ! -f configure.in -a \
236 ! -f .links -a ! -d .git ]; do
7ee12623
MW
237 case "$(pwd)" in
238 /)
239 fail "couldn't find top-level directory"
240 ;;
241 esac
242 cd ..
243done
b9ad2dae
MW
244assign toppath $(pwd)
245assign srcpath $toppath
7ee12623 246
9243a740
MW
247## Build any necessary qualifiers.
248qual= sep=.
249case ${SBOX_SESSION_DIR+t},${DEB_BUILD_ARCH+t} in
250 t,t) qual=$qual$sep$DEB_BUILD_ARCH; sep=- ;;
251 t,*) fail "unknown build arch" ;;
252esac
253
7ee12623 254## Construct the output directory.
9243a740 255assign releasepath $srcpath/dist-$build$qual
47539e6a 256chmod -R +w $releasepath 2>/dev/null || :
7ee12623
MW
257rm -rf $releasepath 2>/dev/null || :
258mkdir $releasepath
259case $verbose in
260 no)
261 exec 4>$releasepath/mdw-build.log 3>&4 ||
262 fail "Failed to create log."
263 ;;
264esac
265
f282ba46 266## Do we have a Git repository?
7ee12623
MW
267case "$checkout,$setup,$(yesno [ -d $srcpath/.git ])" in
268 yes,no,*)
269 fail "Inconsistent options: can't check out without setup."
270 ;;
271 yes,yes,no)
272 info "No Git repository found."
f282ba46 273 checkout=no gitver=none
7ee12623
MW
274 ;;
275 yes,yes,yes)
276 cd $srcpath
277 [ "$(git ls-files -m)" = "" ] ||
f282ba46 278 warn "working tree has uncommitted changes"
66305913 279 ;;
f282ba46
MW
280esac
281
282## Is there Debian build equipment?
283case "$debian,$(yesno [ -d $srcpath/debian ])" in
284 yes,no)
285 info "No debian directory found."
286 debian=no debver=none
287 ;;
f0905f8c
MW
288 no,*)
289 debver=none
290 ;;
f282ba46 291 yes,yes)
ac1bda22 292 debver=$(dpkg-parsechangelog | sed -n 's/^Version: //p')
40196145
MW
293 debsrc=$(dpkg-parsechangelog | sed -n 's/^Source: //p')
294 debname=$(git config user.name) debemail=$(git config user.email)
f282ba46
MW
295 ;;
296esac
297
46fced9d
MW
298## Maybe check out a copy of the source.
299case "$checkout" in
300 yes)
301 cd $releasepath
302 run git clone -sn $srcpath/.git _source
303 assign srcpath $releasepath/_source
304 cd $srcpath
305 run git checkout -b mdw-build $checkoutrev
ac1bda22 306 assign gitversion "$(git describe --abbrev=4)"
46fced9d
MW
307 ;;
308esac
309
f282ba46 310## Check the version number.
40196145 311hack_dch_p=no
ac1bda22 312case "$gitversion,$debver" in
f282ba46
MW
313 none,* | *,none)
314 ;;
315 *)
ac1bda22
MW
316 dvref=$(echo "$debver" | tr '~' '_')
317 if [ "$gitversion" = "$dvref" ]; then
318 assign debversion "$debver"
319 else
320 warn "Git version $gitversion doesn't match Debian version $debver"
40196145 321 hack_dch=yes
ac1bda22
MW
322 dver=$(echo $gitversion | sed 's/-/+/; s/-/./g')
323 case $debver in *~) dver=$debver$dver ;; esac
324 assign debversion "$dver"
325 now=$(date -R)
40196145 326 fi
f282ba46
MW
327 ;;
328esac
329
7ee12623
MW
330## Maybe refresh the build machinery.
331case "$setup" in
332 yes)
9c586ae1 333 run $setupcmd
7ee12623
MW
334 ;;
335esac
336
337## Initialize the build directory.
f5b3423e
MW
338case "$vpath,$(yesno [ -e $srcpath/configure ])" in
339 yes,yes)
340 assign buildpath $releasepath/_build
341 mkdir $buildpath
342 cd $buildpath
343 run $srcpath/configure
344 ;;
345 no,yes)
346 info "VPATH build disabled"
347 assign buildpath $srcpath
348 distcheck=no
349 cd $srcpath
350 run ./configure
351 ;;
352 *,no)
353 info "no configure script"
354 assign buildpath $srcpath
355 cd $srcpath
356 ;;
357esac
7ee12623
MW
358
359## Discover the release name.
360cat >find-distdir.mk <<'EOF'
361include Makefile
362print-distdir:
dd8d9a6c 363 @echo >&3 $(distdir)
7ee12623 364EOF
dd8d9a6c
MW
365assign distdir \
366 $({ make -f find-distdir.mk print-distdir >/dev/null 2>&1; } 3>&1)
7ee12623
MW
367
368## Get a tarball distribution.
369case "$distcheck" in
370 yes)
84dd9069 371 run make $makeopts distcheck
7ee12623
MW
372 ;;
373 no)
84dd9069 374 run make $makeopts dist
7ee12623
MW
375 ;;
376esac
377
378cd $releasepath
379
d87d7867
MW
380case $native in
381 yes)
382 if ! tar tf $buildpath/$distdir.tar.gz 2>/dev/null | grep -q RELEASE
383 then
384 fail "missing RELEASE file in distribution"
385 fi
386 ;;
387esac
7ee12623
MW
388
389run mv $buildpath/$distdir.tar.gz .
5a91acc5
MW
390case $build,$sign in
391 release,yes)
392 run gpg -u$signkey -ab -o$distdir.tar.gz.gpg $distdir.tar.gz
47f56ea2
MW
393 ;;
394esac
7ee12623
MW
395
396## Maybe build the Debian packages.
f282ba46
MW
397case "$debian" in
398 yes)
7ee12623
MW
399 run tar xvfz $distdir.tar.gz
400 cd $distdir
40196145
MW
401 case $hack_dch in
402 yes)
40196145 403 cat - debian/changelog >debian/changelog.new <<EOF
ac1bda22 404$debsrc ($debversion) experimental; urgency=low
40196145
MW
405
406 * Hacking in process, not intended for release.
407
408 -- $debname <$debemail> $now
409
410EOF
411 mv debian/changelog.new debian/changelog
412 ;;
413 esac
e5099dd8
MW
414 sbuildargs=$sbuildsrv
415 case $sbuild,$build in
416 yes,release)
417 case $sign in yes) sbuildargs="-k$signkey $sbuildargs" ;; esac
418 ;;
6cf97414
MW
419 yes,*)
420 if [ -d $toppath/dist-$build.pkgs ]; then
421 sbuildargs="-p$toppath/dist-$build.pkgs $sbuildargs"
422 fi
423 ;;
e5099dd8 424 esac
b94830d9 425 case $sbuild,$build,$sign in
e5099dd8 426 yes,*) run mdw-sbuild $sbuildargs ;;
b94830d9 427 no,release,yes) run dpkg-buildpackage -k$signkey ;;
5a91acc5
MW
428 no,*) run dpkg-buildpackage -us -uc ;;
429 esac
7ee12623
MW
430 ;;
431esac
432
433## Maybe upload Debian packages.
434cd $releasepath
435case "$upload,$build" in
5a91acc5
MW
436 yes,test) info "Test build: not uploading." ;;
437 yes,release) run rsync $distdir.tar.gz $distdir.tar.gz.gpg $uploadpath ;;
438esac
439case "$debian,$upload,$dput,$build" in
440 yes,yes,yes,release) run dput -f $dputtarget *.changes ;;
7ee12623
MW
441esac
442
443## Tidy up.
444case "$clean" in
445 yes)
446 rm -rf $releasepath/$distdir
447 rm -rf $releasepath/_source
448 rm -rf $releasepath/_build
449 ;;
450esac
451
452## Done.
453info "All OK."
454
455###----- That's all, folks --------------------------------------------------