chiark / gitweb /
bin/disorder-notify: Rewrite and take over the functionality of `media-keys'.
[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
816af8ee
MW
56###--------------------------------------------------------------------------
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}
ac504698 86: ${make=make}
b94830d9 87default_depends sbuild sbuildsrv
5a91acc5
MW
88default_depends sign signkey
89default_depends upload uploadpath
90default_depends dput dputtarget
816af8ee
MW
91: ${DEB_BUILD_OPTIONS=parallel=4}; export DEB_BUILD_OPTIONS
92
7ee12623
MW
93###--------------------------------------------------------------------------
94### Parse options.
95
0660d224
MW
96prog=${0##*/}
97
7ee12623
MW
98usage () {
99 cat <<EOF
24a3095a 100Usage: $prog [-v] BUILDOPT
7ee12623
MW
101
102Build options:
103
104 [no]checkout[=REV]
105 [no]release
9c586ae1 106 [no]setup[=RUNE]
7ee12623
MW
107 [no]distcheck
108 [no]debian
5a91acc5
MW
109 [no]upload[=SERVER:PATH]
110 [no]dput[=TARGET]
7ee12623 111 [no]clean
f5b3423e 112 [no]vpath
b94830d9 113 [no]sbuild[=SERVER]
5a91acc5 114 [no]sign[=KEYID]
d87d7867 115 [no]native
ac504698 116 make=MAKE
7ee12623
MW
117EOF
118}
119
120## Parse simple options.
121verbose=no
24a3095a 122while getopts "hv" opt; do
7ee12623
MW
123 case "$opt" in
124 h) usage; exit 0 ;;
125 v) verbose=yes ;;
126 *) exit 1 ;;
127 esac
128done
129shift $((OPTIND - 1))
130
131## Parse the build options.
5a91acc5
MW
132maybe_set () {
133 var=$1 want=$2
134 eval "p=\${$want+t}\${$want-nil}"
135 case $p in
136 t) eval $var=yes ;;
137 nil) echo >&2 "$prog: $want not set"; exit 1 ;;
138 esac
139}
7ee12623
MW
140for opt; do
141 case "$opt" in
142 checkout) checkout=yes checkoutrev=HEAD ;;
143 checkout=*) checkout=yes checkoutrev=${opt#*=} ;;
7ee12623
MW
144 release) build=release ;;
145 norelease) build=test ;;
9c586ae1
MW
146 setup) setup=yes setupcmd=mdw-setup ;;
147 setup=*) setup=yes setupcmd=${opt#*=} ;;
5a91acc5
MW
148 upload) maybe_set upload uploadpath ;;
149 upload=*) upload=yes uploadpath=${opt#*=} ;;
150 sign) maybe_set sign signkey ;;
151 sign=*) sign=yes signkey=${opt#*=} ;;
b94830d9
MW
152 sbuild) maybe_set sbuild sbuildsrv ;;
153 sbuild=*) sbuild=yes sbuildsrv=${opt#*=} ;;
5a91acc5
MW
154 dput) maybe_set dput dputtarget ;;
155 dput=*) dput=yes dputtarget=${opt#*=} ;;
ac504698 156 make=*) make=${opt#*=} ;;
5a91acc5
MW
157
158 distcheck | debian | clean | vpath | native)
7ee12623
MW
159 eval "$opt=yes"
160 ;;
50c72b0f 161 nocheckout | nosetup | nodistcheck | nodebian | \
b94830d9 162 noupload | nodput | noclean | novpath | nonative | nosbuild | nosign)
7ee12623
MW
163 eval "${opt#no}=no"
164 ;;
165 *)
166 usage >&2
167 exit 1
168 ;;
169 esac
170done
171
84dd9069
MW
172## Parse DEB_BUILD_OPTIONS.
173jobs=1
174set -- $DEB_BUILD_OPTIONS
175for opt; do
176 case "$opt" in
177 parallel=*) jobs=${opt#*=} ;;
178 esac
179done
180
181makeopts=""
182case $jobs in 1) ;; *) makeopts="$makeopts -j$jobs" ;; esac
183
7ee12623
MW
184###--------------------------------------------------------------------------
185### Utility functions.
186
190c1efc
MW
187## File descriptor assignments:
188##
189## 0 -- original stdin (never touched)
190## 1, 2 -- stdout, stderr, redirected to 3 while running comamnds
4ed33f50
MW
191## log -- logfile and original stderr (verbose), or logfile only (quiet);
192## captures command output
193## diag -- logfile; primary diagnostic output
ab9fae2a 194## term -- orginal stderr; secondary diagnostic output (with colours)
190c1efc 195
7ee12623
MW
196notify () {
197 colour=$1 message=$2
ab9fae2a
MW
198 echo $message >&$diag
199 echo "$(tput bold; tput setaf $colour)$message$(tput sgr0; tput op)" >&$term
7ee12623
MW
200}
201
202fail () {
203 notify 1 "!!! $*"
204 exit 1
205}
206
f282ba46
MW
207warn () {
208 case $build in
209 release) fail "$*" ;;
210 *) notify 5 "??? $*" ;;
211 esac
212}
213
7ee12623
MW
214info () {
215 notify 6 "--- $*"
216}
217
218assign () {
219 info "$1 = $2"
220 eval "$1=$2"
221}
222
223runx () {
224 notify 2 "+++ $*"
5b950572 225 nice "$@" 2>&$log {log}>&- {diag}>&- {term}>&- || fail "$1: exit $?"
7ee12623
MW
226}
227
ab9fae2a 228run () { runx "$@" >&$log; }
7ee12623
MW
229
230yesno () {
ab9fae2a
MW
231 echo -n "(test $*)" >&$diag
232 if "$@" >&$diag 2>&$diag {log}>&- {diag}>&- {term}>&-; then
233 echo "(yes)" >&$diag
7ee12623
MW
234 echo yes
235 else
ab9fae2a 236 echo "(no)" >&$diag
7ee12623
MW
237 echo no
238 fi
239}
240
241###--------------------------------------------------------------------------
242### Do the building.
243
244## Find the top-level package directory.
d43de82b
MW
245while [ ! -f configure.ac -a ! -f configure.in -a \
246 ! -f .links -a ! -d .git ]; do
7ee12623
MW
247 case "$(pwd)" in
248 /)
249 fail "couldn't find top-level directory"
250 ;;
251 esac
252 cd ..
253done
c3a2e2b1 254toppath=$(pwd)
7ee12623 255
9243a740
MW
256## Build any necessary qualifiers.
257qual= sep=.
258case ${SBOX_SESSION_DIR+t},${DEB_BUILD_ARCH+t} in
259 t,t) qual=$qual$sep$DEB_BUILD_ARCH; sep=- ;;
260 t,*) fail "unknown build arch" ;;
261esac
262
7ee12623 263## Construct the output directory.
c3a2e2b1 264releasepath=$toppath/dist-$build$qual
47539e6a 265chmod -R +w $releasepath 2>/dev/null || :
7ee12623
MW
266rm -rf $releasepath 2>/dev/null || :
267mkdir $releasepath
4ed33f50 268logfile=$releasepath/mdw-build.log
5043931a 269exec {term}>&2
4ed33f50 270exec {diag}>>$logfile || fail "Failed to create log."
7ee12623 271case $verbose in
4ed33f50
MW
272 no) exec {log}>&$diag ;;
273 yes) exec {log}> >(tee -a $logfile >&$term {term}>&- {diag}>&-) ;;
7ee12623
MW
274esac
275
c3a2e2b1
MW
276## Repeat the earlier assignments for tbe benefit of the logfile.
277assign toppath $toppath
278assign releasepath $releasepath
4ed33f50 279assign logfile $logfile
c3a2e2b1 280
f282ba46 281## Do we have a Git repository?
be2a2314 282case "$checkout,$setup,$(yesno [ -d $toppath/.git ])" in
7ee12623
MW
283 yes,no,*)
284 fail "Inconsistent options: can't check out without setup."
285 ;;
286 yes,yes,no)
287 info "No Git repository found."
f282ba46 288 checkout=no gitver=none
7ee12623
MW
289 ;;
290 yes,yes,yes)
be2a2314 291 cd $toppath
7ee12623 292 [ "$(git ls-files -m)" = "" ] ||
f282ba46 293 warn "working tree has uncommitted changes"
66305913 294 ;;
f282ba46
MW
295esac
296
297## Is there Debian build equipment?
be2a2314 298case "$debian,$(yesno [ -d $toppath/debian ])" in
f282ba46
MW
299 yes,no)
300 info "No debian directory found."
301 debian=no debver=none
302 ;;
f0905f8c
MW
303 no,*)
304 debver=none
305 ;;
f282ba46 306 yes,yes)
ac1bda22 307 debver=$(dpkg-parsechangelog | sed -n 's/^Version: //p')
40196145
MW
308 debsrc=$(dpkg-parsechangelog | sed -n 's/^Source: //p')
309 debname=$(git config user.name) debemail=$(git config user.email)
f282ba46
MW
310 ;;
311esac
312
46fced9d
MW
313## Maybe check out a copy of the source.
314case "$checkout" in
315 yes)
316 cd $releasepath
be2a2314 317 run git clone -sn $toppath/.git _source
46fced9d
MW
318 assign srcpath $releasepath/_source
319 cd $srcpath
493856f1
MW
320 run git update-ref refs/heads/mdw-build $checkoutrev ""
321 run git symbolic-ref HEAD refs/heads/mdw-build
322 run git read-tree --reset refs/heads/mdw-build
323 run git checkout-index -afu
ac1bda22 324 assign gitversion "$(git describe --abbrev=4)"
46fced9d 325 ;;
be2a2314
MW
326 no)
327 assign srcpath $toppath
328 ;;
46fced9d
MW
329esac
330
f282ba46 331## Check the version number.
40196145 332hack_dch_p=no
ac1bda22 333case "$gitversion,$debver" in
f282ba46
MW
334 none,* | *,none)
335 ;;
336 *)
ac1bda22
MW
337 dvref=$(echo "$debver" | tr '~' '_')
338 if [ "$gitversion" = "$dvref" ]; then
339 assign debversion "$debver"
340 else
341 warn "Git version $gitversion doesn't match Debian version $debver"
40196145 342 hack_dch=yes
ac1bda22
MW
343 dver=$(echo $gitversion | sed 's/-/+/; s/-/./g')
344 case $debver in *~) dver=$debver$dver ;; esac
345 assign debversion "$dver"
346 now=$(date -R)
40196145 347 fi
f282ba46
MW
348 ;;
349esac
350
7ee12623
MW
351## Maybe refresh the build machinery.
352case "$setup" in
353 yes)
9c586ae1 354 run $setupcmd
7ee12623
MW
355 ;;
356esac
357
358## Initialize the build directory.
f5b3423e
MW
359case "$vpath,$(yesno [ -e $srcpath/configure ])" in
360 yes,yes)
361 assign buildpath $releasepath/_build
362 mkdir $buildpath
363 cd $buildpath
364 run $srcpath/configure
365 ;;
366 no,yes)
367 info "VPATH build disabled"
368 assign buildpath $srcpath
369 distcheck=no
370 cd $srcpath
371 run ./configure
372 ;;
373 *,no)
374 info "no configure script"
375 assign buildpath $srcpath
376 cd $srcpath
377 ;;
378esac
7ee12623
MW
379
380## Discover the release name.
381cat >find-distdir.mk <<'EOF'
382include Makefile
383print-distdir:
ab9fae2a 384 @echo >&$(fd) $(distdir)
7ee12623 385EOF
dd8d9a6c 386assign distdir \
ab9fae2a 387 $({ $make -f find-distdir.mk print-distdir fd=$t >/dev/null 2>&1; } {t}>&1)
7ee12623
MW
388
389## Get a tarball distribution.
390case "$distcheck" in
391 yes)
ac504698 392 run $make $makeopts distcheck
7ee12623
MW
393 ;;
394 no)
ac504698 395 run $make $makeopts dist
7ee12623
MW
396 ;;
397esac
398
399cd $releasepath
400
d87d7867
MW
401case $native in
402 yes)
403 if ! tar tf $buildpath/$distdir.tar.gz 2>/dev/null | grep -q RELEASE
404 then
405 fail "missing RELEASE file in distribution"
406 fi
407 ;;
408esac
7ee12623
MW
409
410run mv $buildpath/$distdir.tar.gz .
5a91acc5
MW
411case $build,$sign in
412 release,yes)
413 run gpg -u$signkey -ab -o$distdir.tar.gz.gpg $distdir.tar.gz
47f56ea2
MW
414 ;;
415esac
7ee12623
MW
416
417## Maybe build the Debian packages.
f282ba46
MW
418case "$debian" in
419 yes)
7ee12623
MW
420 run tar xvfz $distdir.tar.gz
421 cd $distdir
40196145
MW
422 case $hack_dch in
423 yes)
40196145 424 cat - debian/changelog >debian/changelog.new <<EOF
ac1bda22 425$debsrc ($debversion) experimental; urgency=low
40196145
MW
426
427 * Hacking in process, not intended for release.
428
429 -- $debname <$debemail> $now
430
431EOF
432 mv debian/changelog.new debian/changelog
433 ;;
434 esac
e5099dd8
MW
435 sbuildargs=$sbuildsrv
436 case $sbuild,$build in
437 yes,release)
438 case $sign in yes) sbuildargs="-k$signkey $sbuildargs" ;; esac
439 ;;
6cf97414
MW
440 yes,*)
441 if [ -d $toppath/dist-$build.pkgs ]; then
442 sbuildargs="-p$toppath/dist-$build.pkgs $sbuildargs"
443 fi
444 ;;
e5099dd8 445 esac
b94830d9 446 case $sbuild,$build,$sign in
e5099dd8 447 yes,*) run mdw-sbuild $sbuildargs ;;
b94830d9 448 no,release,yes) run dpkg-buildpackage -k$signkey ;;
5a91acc5
MW
449 no,*) run dpkg-buildpackage -us -uc ;;
450 esac
7ee12623
MW
451 ;;
452esac
453
454## Maybe upload Debian packages.
455cd $releasepath
456case "$upload,$build" in
5a91acc5
MW
457 yes,test) info "Test build: not uploading." ;;
458 yes,release) run rsync $distdir.tar.gz $distdir.tar.gz.gpg $uploadpath ;;
459esac
460case "$debian,$upload,$dput,$build" in
461 yes,yes,yes,release) run dput -f $dputtarget *.changes ;;
7ee12623
MW
462esac
463
464## Tidy up.
465case "$clean" in
466 yes)
467 rm -rf $releasepath/$distdir
468 rm -rf $releasepath/_source
469 rm -rf $releasepath/_build
470 ;;
471esac
472
473## Done.
474info "All OK."
475
476###----- That's all, folks --------------------------------------------------