madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

fix up arch handling
[code/mbuild.git] / sbuild-wrapper.sh
1 #!/bin/sh
2 #
3 #  - automate builds with sbuild and dinstall the result
4 #
5 # Copyright (c) 2008–2010 martin f. krafft <madduck@debian.org>
6 # Released under the terms of the Artistic Licence 2.0.
7 #
8 set -eu
9
10 ME="${0##*/}"
11
12 BUILDDIR="$(mktemp -dt $ME.XXXXXXXX)"
13 cleanup() {
14   cd /tmp && rm -r "$BUILDDIR"
15   trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15
16 }
17 trap cleanup 1 2 3 4 5 6 7 8 10 11 12 13 14 15
18
19 BUNDLE_DIR="${TMPDIR:-/tmp}"
20 TARGET_DIR="$PWD"
21 copy_back_files() {
22   echo "Copying files destined for $1 back to $TARGET_DIR..."
23   dcmd cp -v "$2" "$TARGET_DIR"
24 }
25 dinstall() {
26   copy_back_files "$@"
27 }
28 print_bundle_location() {
29   echo "Bundle available at $@ ."
30 }
31 postbuild() {
32   :
33 }
34
35 KEYID=
36
37 MBUILDRCS="/etc/mbuild/rc $HOME/.mbuildrc $HOME/.mbuild/rc"
38 for rc in $MBUILDRCS; do
39   [ -r "$rc" ] && . "$rc"
40 done
41
42 if [ -z "$KEYID" ]; then
43   echo "E: \$KEYID is not defined in rc file." >&2
44   exit 1
45 fi
46
47 DEB_BUILD_ARCH="$(dpkg-architecture -qDEB_BUILD_ARCH)"
48
49 about()
50 {
51   echo "$ME -- wrapper for sbuild"
52   echo "Copyright © martin f. krafft <madduck@debian.org>"
53   echo "Released under the terms of the Artistic Licence 2.0"
54 }
55
56 usage()
57 {
58   about
59   echo
60   echo "Usage: $ME [options] [sbuild_options] file_source.changes"
61   echo
62   echo "Valid options are:"
63   cat <<-_eof | column -s\& -t
64         --dist & specify the target distribution (default: from changes file)
65         --arch & specify the target architecture (default: $DEB_BUILD_ARCH)
66         -sa & pass --force-orig-source to sbuild
67         -B & do a binary-only build
68         -h|--help & show this output.
69         -V|--version & show version information.
70         _eof
71 }
72
73 binonly=0
74 sbuild_args=
75 sbuild_args_sourceful=
76 schangesfile=
77 arch=
78 for opt in "$@"; do
79   case "$opt" in
80     -h|--help) usage; exit 0;;
81     -V|--version) about; exit 0;;
82     --arch=*) arch="${opt#--arch=}";;
83     -D) sbuild_args="${sbuild_args:+$sbuild_args }$opt";;
84     -sa) sbuild_args="${sbuild_args:+$sbuild_args }--force-orig-source";;
85     -B) binonly=1;;
86     --*) sbuild_args="${sbuild_args:+$sbuild_args }$opt";;
87     *_source.changes)
88       if [ -z "$schangesfile" ]; then
89         if [ -f "$opt" ] && [ -r "$opt" ]; then
90           schangesfile="$opt"
91         else
92           echo "E: file does not exist: $opt" >&2
93           exit 1
94         fi
95       else
96         echo "E: cannot pass more than one source changes file: $opt" >&2
97         exit 1
98       fi
99       ;;
100     *)
101       echo "E: unknown option: $opt" >&2
102       exit 1
103       ;;
104   esac
105 done
106
107 if [ -z "$schangesfile" ]; then
108   usage
109   exit 1
110 fi
111
112 dist="$(sed -ne 's,Distribution: ,,p' "$schangesfile")"
113
114 schangesfile_basename="${schangesfile##*/}"
115 packagename="${schangesfile_basename%%_*}"
116 packagenameversion="${schangesfile_basename%_*}"
117 debversion="${packagenameversion#*_}"
118 upstream_version="${debversion%-*}"
119 dscfile_basename="$packagenameversion".dsc
120
121 case "$schangesfile" in
122   */*) cd "${schangesfile%/*}";;
123   *) :;;
124 esac
125 dcmd cp "${schangesfile##*/}" "$BUILDDIR"
126 schangesfile="$schangesfile_basename"
127
128 OLDPWD="$PWD"
129 cd "$BUILDDIR"
130
131 dcmd "$dscfile_basename" | while read f; do
132   test -f "$f" && continue
133
134   case "$f" in
135     *.tar.gz|*.tar.bz2|*.tar.lzma|*.tar.xz)
136       if [ -f "$OLDPWD/$f" ]; then
137         echo "I: using existing tarball for $upstream_version…" >&2
138         cp $OLDPWD/$f $f
139       else
140         last_version="$(apt-cache madison $packagename | sed -rne "s,.+(\<${upstream_version}[^[:space:]]+).*,\1,p")"
141         echo "I: fetching missing tarball for $upstream_version (from $last_version)…" >&2
142         if ! apt-get --tar-only --only-source source "${packagename}=${last_version}"; then
143           echo "E: I do not know how to obtain the file: $f" >&2
144           exit 1
145         fi
146       fi
147       ;;
148     *)
149       echo "E: I do not know how to obtain the file: $f" >&2
150       exit 1
151       ;;
152   esac
153 done
154
155 rm $schangesfile
156 unset schangesfile
157
158 [ -z "$arch" ] && arch="$DEB_BUILD_ARCH"
159
160 target_arch="$(sed -ne 's,^Architecture: ,,p' $dscfile_basename)"
161 case "$binonly/$target_arch" in
162   1/all)
163     echo "E: cannot build arch:all packages with -B." >&2
164     exit 1
165     ;;
166   0/all) arch=all;;
167   */any)
168     arch="$(schroot -l | sed -rne 's,^sid-([^-]+).*,\1,p' | uniq | tr '\n' ' ')"
169     if [ "$binonly" = 0 ]; then
170       sbuild_args_sourceful="--source --arch-all"
171     fi
172     ;;
173 esac
174
175 for a in $arch; do
176   echo "I: building $packagenameversion for $a/$dist…" >&2
177
178   case "$a" in
179     all)
180       arch_arg=--arch-all
181       a="$DEB_BUILD_ARCH"
182       ;;
183     *) --arch=$a;;
184   esac
185
186   sbuild $sbuild_args $sbuild_args_sourceful $arch_arg \
187     --dist="$dist" --keyid=$KEYID \
188     "$dscfile_basename" || ret=$?
189
190   changesfile="${packagenameversion}_${a}.changes"
191
192   if [ -n "$sbuild_args_sourceful" ]; then
193     schangesfile="${packagenameversion}_source+${changesfile#${packagenameversion}_}"
194     mv "$changesfile" "$schangesfile"
195     changesfile="$schangesfile"
196   fi
197
198   # subsequent iterations should be binonly
199   sbuild_args_sourceful=
200
201   echo "I: running post-build hook ($packagenameversion/$a/$dist)…" >&2
202   postbuild "$dist" "$a" "$changesfile"
203   echo "I: running dinstall ($packagenameversion/$a/$dist)…" >&2
204   dinstall "$dist" "$changesfile"
205
206   echo "I: done building $packagenameversion for $a/$dist" >&2
207 done
208
209 if [ -n "${schangesfile:-}" ]; then
210   sarch="${schangesfile##*_}"; sarch=${sarch%.changes}
211   combined_arch="$(echo -n "${sarch}+";
212                    for i in *.changes; do
213                      [ "$i" = "$schangesfile" ] && continue
214                      t="${i##*_}"; echo "${t%.changes}"
215                    done)"
216
217   if [ -n "$combined_arch" ]; then
218     mergechanges *.changes > ${packagenameversion}_${combined_arch}.changes
219     arch="$combined_arch"
220   fi
221 fi
222
223 bundle="${BUNDLE_DIR}/${packagenameversion}_${arch}_bundle.tar.gz"
224 tar -chzf "$bundle" *
225 chmod 644 "$bundle"
226 print_bundle_location "$bundle"
227
228 cleanup
229
230 exit 0