1#!/bin/sh -eu
2usage() {
3 printf "%s\n\n" "Usage: $0 [command...] [flags...] [args...]"
4 printf "%s\n" "$0 add-repo [-s] <name> <key>"
5 printf "\t%s\n" "Trusts <key> and adds the local repo to /etc/apk/repositories"
6 printf "\t%s\n\n" "-s: set this key as default in abuild.conf"
7 printf "%s\n" "$0 build [-cu] [-v <pkgver>] <packages...>"
8 printf "\t%s\n" "Builds packages"
9 printf "\t%s\n" "-c: update checksums"
10 printf "\t%s\n" "-u: update pkgrel"
11 printf "\t%s\n\n" "-v <pkgver>: update pkgver"
12 printf "%s\n" "$0 pkgver"
13 printf "\t%s\n\n" "Prints the suggested package ver for this directory"
14 printf "%s\n" "$0 upload <ssh server> <remote path> <packages...>"
15 printf "\t%s\n" "Uploads packages via rsync and updates remote APKINDEX"
16}
17
18get_pkgvar() (
19 var="$1"
20 set +u
21 . APKBUILD
22 eval 'printf "%s\n" "$'"$var"'"'
23)
24
25find_repos() (
26 find . -maxdepth 1 -type d -not -name . -not -name .git
27)
28
29find_pkg_repo() (
30 pkg=$1
31 for repo in $(find_repos)
32 do
33 if [ -d "$repo"/"$pkg" ]
34 then
35 echo "$repo"
36 return 0
37 fi
38 done
39 return 1
40)
41
42update_pkgrel() (
43 pkg="$1"
44 pkgver="$(get_pkgvar pkgver)"
45 prev_ver=$(apk search -x "$pkg" | cut -c$((${#pkg}+2))-)
46 prev_pkgver=$(printf "%s" "$prev_ver" | cut -d'-' -f1)
47 prev_pkgrel=$(printf "%s" "$prev_ver" | cut -d'-' -f2 | cut -d'r' -f2-)
48 if [ "$prev_pkgver" == "$pkgver" ]
49 then
50 pkgrel=$((prev_pkgrel + 1))
51 sed -e "s/pkgrel=.*/pkgrel=$pkgrel/" -i APKBUILD
52 fi
53)
54
55update_pkgver() {
56 pkgver="$1"
57 prev_pkgver=$(apk search -x ${project} | cut -d '-' -f2)
58 sed -e "s/pkgver=.*/pkgver=$pkgver/" -i APKBUILD
59 if [ "$prev_pkgver" != "$pkgver" ]
60 then
61 sed -e "s/pkgrel=.*/pkgrel=0/" -i APKBUILD
62 fi
63}
64
65add_repo() {
66 set_default=0
67 while getopts s flag
68 do
69 case $flag in
70 s) set_default=1 ;;
71 *) usage && exit 1 ;;
72 esac
73 done
74 shift $((OPTIND-1))
75 echo "$@"
76 if [ $# -ne 2 ]
77 then
78 usage
79 exit 1
80 fi
81 repo="$1"
82 key="$2"
83 mkdir -p ~/packages/$repo
84 echo ~/packages/$repo | cat - /etc/apk/repositories > /tmp/repositories
85 sudo mv /tmp/repositories /etc/apk/repositories
86 if ! [ -f "$key" ]
87 then
88 echo "Warning: generating new abuild key"
89 key="$HOME/.abuild/abuild.rsa"
90 mkdir -p $HOME/.abuild
91 (
92 umask 0007
93 openssl genrsa -out "$key" 2048
94 )
95 fi
96 pkey="$(basename "$key").pub"
97 sudo openssl rsa -in $key -pubout \
98 -out /etc/apk/keys/"$pkey"
99 cp /etc/apk/keys/"$pkey" ~/.abuild/"$pkey"
100 if [ $set_default -eq 1 ]
101 then
102 echo "PACKAGER_PRIVKEY="'"'$key'"' >> \
103 ~/.abuild/abuild.conf
104 fi
105}
106
107build() (
108 builddeps=0
109 checksum=0
110 updpkgrel=0
111 pkgver=""
112 # Disable progress on abuild-apk
113 cat <<-"EOF" | sudo tee /usr/local/bin/abuild-apk
114 #!/bin/sh
115 exec /usr/bin/abuild-apk --no-progress $@
116 EOF
117 sudo chmod +x /usr/local/bin/abuild-apk
118 export PATH=/usr/local/bin:$PATH
119 while getopts Rcuv: flag
120 do
121 case $flag in
122 R) builddeps=1 ;;
123 c) checksum=1 ;;
124 u) updpkgrel=1 ;;
125 v) pkgver="$OPTARG" ;;
126 *) usage && exit 1 ;;
127 esac
128 done
129 shift $((OPTIND-1))
130 if [ $# -eq 0 ]
131 then
132 echo "No packages specified."
133 exit 1
134 fi
135 for pkg in $@
136 do
137 repo="$(find_pkg_repo "$pkg")"
138 (
139 cd "$repo"/"$pkg"
140 if [ -n "$pkgver" ]
141 then
142 update_pkgver "$pkgver"
143 fi
144 if [ $updpkgrel -eq 1 ]
145 then
146 update_pkgrel "$pkg"
147 fi
148 if [ $checksum -eq 1 ]
149 then
150 abuild checksum
151 fi
152 if [ $builddeps -eq 1 ]
153 then
154 abuild -R
155 else
156 abuild -r
157 fi
158 )
159 done
160)
161
162print_pkgver() {
163 if [ $# -ne 0 ]
164 then
165 usage
166 exit 1
167 fi
168 if [ -d .git ]
169 then
170 set +e
171 pkgver=$(git describe --abbrev=0 2>/dev/null)
172 if [ $? -ne 0 ]
173 then
174 pkgver=0
175 fi
176 set -e
177 if ! git describe --exact-match HEAD >/dev/null 2>&1
178 then
179 cdate=$(git show -s -1 --format='%ci' HEAD)
180 cdate=$(echo "$cdate" | cut -d' ' -f1 | sed -e 's/-//g')
181 pkgver="${pkgver}_git${cdate}"
182 fi
183 elif [ -d .hg ]
184 then
185 pkgver=$(hg id -T '{latesttag}')
186 if [ "$(hg id -T '{latesttagdistance}')" -ne 0 ]
187 then
188 pkgver="$(hg id -T '{latesttag}_hg{sub("-", "", date|shortdate)}')"
189 fi
190 else
191 pkgver=unknown_0000
192 fi
193 echo "$pkgver"
194}
195
196mirror_ver() (
197 mirror="$1"
198 pkg="$2"
199 apk policy "$pkg" | while read -r line
200 do
201 case "$line" in
202 *:)
203 ver="${line%:}"
204 ver="${ver## }"
205 ;;
206 *$mirror*)
207 echo "$ver"
208 ;;
209 esac
210 done
211)
212
213get_aver() {
214 aver="${REPOSITORY:-}"
215 if [ ${#aver} -eq 0 ]
216 then
217 . /etc/os-release
218 aver="v$(printf "%s" "$VERSION_ID" | cut -d. -f1-2)"
219 fi
220 echo "$aver"
221}
222
223upload_pkg() (
224 repo="$1"
225 pkg="$2"
226 arch="$(uname -m)"
227 aver="$(get_aver)"
228
229 set -x
230 path="$remote_path/$aver/$repo/$arch"
231 ssh "$remote" mkdir -p "$path"
232
233 url=$(echo "$remote" | cut -d@ -f2)
234 prev_ver=$(mirror_ver "$url" "$pkg")
235
236 for ver in $prev_ver
237 do
238 if [ "$prev_ver" != "none" ]
239 then
240 ssh "$remote" rm -f "$path/$pkg-$ver.apk"
241 fi
242 done
243 pkgver="$(get_pkgvar pkgver)"
244 pkgrel="$(get_pkgvar pkgrel)"
245
246 rsync --blocking-io -rsP \
247 ~/packages/"$repo/$arch/$pkg-$pkgver-r$pkgrel.apk" "$remote":"$path/"
248 set +x
249)
250
251update_index() (
252 repo="$1"
253 arch="$(uname -m)"
254
255 . /etc/os-release
256 aver="$(get_aver)"
257
258 path="$remote_path/$aver/$repo/$arch"
259
260 set -x
261 ssh "$remote" \
262 find "$path" -type f -name '*.apk' -print0 |
263 ssh "$remote" xargs -0 apk index \
264 --rewrite-arch "$(uname -m)" \
265 -x "$path"/APKINDEX.tar.gz \
266 -o "$path"/APKINDEX.unsigned.tar.gz
267 rsync --blocking-io -rP \
268 "$remote:$path/APKINDEX.unsigned.tar.gz" \
269 /tmp/APKINDEX.tar.gz
270 abuild-sign /tmp/APKINDEX.tar.gz
271 rsync --blocking-io -rP /tmp/APKINDEX.tar.gz "$remote:$path/"
272 set +x
273)
274
275upload() (
276 if [ $# -lt 2 ]
277 then
278 usage
279 exit 1
280 fi
281 remote="$1"
282 remote_path="$2"
283 shift 2
284 if [ $# -eq 0 ]
285 then
286 echo "No packages specified"
287 exit 1
288 fi
289 repos=""
290 for pkg in $@
291 do
292 repo=$(find_pkg_repo "$pkg")
293 if ! echo "$repos" | grep "$repo" >/dev/null
294 then
295 repos="$repo $repos"
296 fi
297 (
298 cd "$repo"/"$pkg"
299 arch="$(get_pkgvar arch)"
300 subpkgs="$pkg:_:$arch $(get_pkgvar subpackages)"
301 for subpkg in $subpkgs
302 do
303 name="$(echo "$subpkg" | cut -d':' -f1)"
304 upload_pkg "$repo" "$name"
305 done
306 )
307 done
308 for repo in $repos
309 do
310 update_index $repo
311 done
312)
313
314if [ $# -lt 1 ]
315then
316 usage
317 exit 1
318fi
319cmd="$1"
320shift
321
322case "$cmd" in
323 add-repo)
324 add_repo "$@"
325 ;;
326 build)
327 build "$@"
328 ;;
329 pkgver)
330 print_pkgver "$@"
331 ;;
332 upload)
333 upload "$@"
334 ;;
335 help|-h)
336 usage
337 ;;
338esac