Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#!/bin/zsh
setopt extendedglob nomatch
TRAPERR() { exit 1 }
arch=(x86_64 i686) # arches to build ("any" builds x86_64 and repo-adds x86_64 and i686)
check=1
chroot=extra # The chroot to use (without arch)
mailaddr= # send failed build logs where?
packagedir=~/packages # root directory for packages
pkgname=()
builddeps=()
repodb=$USERNAME.db.tar.gz # repo db filename
repodir=~/public_html/repo # repo to use. arch dir is appended
srcdest=.
usage=0
argerror() {
echo "type: 'mkpkg -h' for more information" >&2
exit 1
}
usage() {
echo 'Usage: mkpkg [OPTION]... PACKAGE...'
echo 'Automatically builds PACKAGE(s) and adds each to a repository'
echo
echo 'Options:'
echo ' -f Ignore check_* requests'
echo ' -h Display this message. Specify twice for more details'
}
usage2() {
echo
echo '--- Configurables ---'
echo ' arch Arches to build (array); "any" is special-cased.'
echo " Default: $(declare -m arch)"
echo
echo ' chroot Chroot setup to use. Does not include architecture.'
echo " Default: $(declare -m chroot)"
echo
echo ' mailaddr Where to mail logs from failed builds. May be an array.'
echo " Default: $(declare -m mailaddr)"
echo
echo ' packagedir Root directory for packages.'
echo " Default: $(declare -m packagedir)"
echo
echo ' pkgname Product pkgnames, not unlike makepkg. REQUIRED'
echo " Default: $(declare -m pkgname)"
echo
echo ' builddeps Additional pkgnames to install from local repo (array).'
echo " Default: $(declare -m builddeps)"
echo
echo ' repodb Repo db filename.'
echo " Default: $(declare -m repodb)"
echo
echo ' repodir Repo to use. Architecture dir is appended.'
echo " Default: $(declare -m repodir)"
echo
echo ' srcdest Where to find sources. Used by check_* functions.'
echo " Default: $(declare -m srcdest)"
echo
echo ' build() Calls archbuild.'
echo ' First argument: arch'
echo ' Rest: makechrootpkg args'
echo
echo '--- Default build function ---'
declare -f build
echo
echo '--- Program outline ---'
echo ' - source ~/.mkpkg'
echo ' - cd $packagedir'
echo ' - for PACKAGE:'
echo ' - cd PACKAGE'
echo ' - source MKPKG'
echo ' - Remove old built packages'
echo ' - for $arch:'
echo ' - Call build() with $arch makechrootpkg_args'
echo ' - On failure, mail logs if $mailaddr is set'
echo ' - Copy built packages to $repodir/$arch'
echo ' - Repo-remove old deltas from $repodb'
echo ' - Remove old delta files'
echo ' - Repo-add built packages to $repodb'
echo ' - Remove old package files'
echo ' - Remove duplicate log files'
echo
echo '--- Quick start ---'
echo " 1. Put a PKGBUILD for foo-git into $packagedir/foo-git/"
echo ' 2. Also put a file named MKPKG into this directory, containing:'
echo ' pkgname=(foo-git)'
echo ' 3. Now run: mkpkg foo-git'
echo
echo 'mkpkg will build the package and publish it in a repository named'
echo " $repodir/\$arch/$repodb"
echo
echo 'For builds conditional on VCS updates, run check_{bzr,git,hg,svn} DIR [BRANCH]'
echo 'from MKPKG, with DIR being a makepkg VCS source and BRANCH a branch (optional).'
echo 'mkpkg will attempt to update the repository. If it is up to date, the build is'
echo 'skipped. The option -f can be used to suppress this behavior, so packages are'
echo 'always built.'
echo
echo 'The primary use of this script is running it from cron to build nightlies.'
}
check_bzr() {
local oldver
if [[ -d $srcdest/$1 && $check == 1 ]]; then
pushd $srcdest/$1
oldver=$(bzr revno)
bzr pull &>/dev/null || :
[[ $oldver == $(bzr revno) ]] && exit 0
popd
fi
}
check_git() {
local oldver
if [[ -d $srcdest/$1 && $check == 1 ]]; then
pushd $srcdest/$1
oldver=$(git rev-parse ${2:-HEAD})
git fetch --all -p &>/dev/null || :
[[ $oldver == $(git rev-parse ${2:-HEAD}) ]] && exit 0
popd
fi
}
check_hg() {
local oldver
if [[ -d $srcdest/$1 && $check == 1 ]]; then
pushd $srcdest/$1
oldver=$(hg id -ir ${2:-tip})
hg pull &>/dev/null || :
[[ $oldver == $(hg id -ir ${2:-tip}) ]] && exit 0
popd
fi
}
check_svn() {
local oldver
if [[ -d $srcdest/$1 && $check == 1 ]]; then
pushd $srcdest/$1
oldver=$(svnversion)
svn up &>/dev/null || :
[[ $oldver == $(svnversion) ]] && exit 0
popd
fi
}
build() {
[[ $chroot == multilib* ]] && 1=
ionice -c 3 chrt -b 0 sudo ${chroot}${1:+-$1}-build -- ${*:2}
}
# Parameters: arch
repoadd() {
local -a pkgs olddeltas repopkgs
pkgs=( ${^pkgname}-[^-]##-[^-]##-($1|any).pkg.tar.xz(-om[1]) )
mkdir -p $repodir/$1
cp $pkgs $repodir/$1/
pushd $repodir/$1
# clean up old deltas, keep 2 newest
olddeltas=( ${^pkgname}-[^-]##-[^-]##_to_[^-]##-[^-]##-($1|any).delta(-Nom[3,-1]) )
repo-remove -q $repodb $olddeltas &>/dev/null || :
rm -f $olddeltas
# Add to databases, with delta generation
XDELTA="-9 -S lzma" repo-add -d -q $repodb $pkgs
# clean up old packages
repopkgs=( ${^pkgname}-[^-]##-[^-]##-($1|any).pkg.tar.xz )
rm -f ${repopkgs:|pkgs}
popd
}
# Parameters: message logfile
maillog() {
if [[ -n $mailaddr ]]; then
xz <$2 >$2.xz
mail -s "mkpkg failure" -a $2.xz $mailaddr <<MESSAGE
${1}
MESSAGE
rm $2.xz
else
echo $1 >&2
fi
}
# Parameters: arch
build_and_add() {
local -a buildargs
local dep
buildargs=(-l $USERNAME-mkpkg -T)
for dep in $builddeps; do
buildargs+=(-I $repodir/$1/${dep}-[^-]##-[^-]##-($1|any).pkg.tar.xz(-om[1]) )
done
if build $1 $buildargs &>$1.log; then
repoadd $1 || :
return 0
else
maillog "$0:$LINENO: '$1' build for '$package' failed" $1.log
return 1
fi
}
mkpkg_one() (
cd $package
source MKPKG
if [[ -z $pkgname ]]; then
echo "$0:$LINENO: no pkgnames found for '$package'" >&2
echo "Please set \$pkgname in $PWD/MKPKG" >&2
exit 1
fi
rm -f ${^pkgname}-[^-]##-[^-]##-[^-]##.pkg.tar.xz(N)
for a in $arch; do
case $a in
any) build_and_add x86_64 && repoadd i686 || : ;;
i686|x86_64) build_and_add $a || : ;;
*) echo "$0:$LINENO: invalid arch '$a' for '$package'" >&2 ;;
esac
done
rm -f *-*.log(|.[0-9])(N) logpipe.*(N)
)
[[ -f ~/.mkpkg ]] && source ~/.mkpkg
while getopts fh option; do
case $option in
f) check=0 ;;
h) (( usage += 1 )) ;;
\?) argerror ;;
esac
done
shift $((OPTIND - 1))
if (( usage > 0 )); then
usage
(( usage > 1 )) && usage2
exit 0
fi
if [[ -z $1 ]]; then
echo "$0:$LINENO: no packages given" >&2
argerror
fi
cd $packagedir
for package; do
mkpkg_one
done