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 sudo openssl rsa -in $key -pubout \
97 -out /etc/apk/keys/$(basename "$key").pub
98 if [ $set_default -eq 1 ]
99 then
100 echo "PACKAGER_PRIVKEY="'"'$key'"' >> \
101 ~/.abuild/abuild.conf
102 fi
103}
104
105build() (
106 builddeps=0
107 checksum=0
108 updpkgrel=0
109 pkgver=""
110 # Disable progress on abuild-apk
111 cat <<-"EOF" | sudo tee /usr/local/bin/abuild-apk
112 #!/bin/sh
113 exec /usr/bin/abuild-apk --no-progress $@
114 EOF
115 sudo chmod +x /usr/local/bin/abuild-apk
116 export PATH=/usr/local/bin:$PATH
117 while getopts Rcuv: flag
118 do
119 case $flag in
120 R) builddeps=1 ;;
121 c) checksum=1 ;;
122 u) updpkgrel=1 ;;
123 v) pkgver="$OPTARG" ;;
124 *) usage && exit 1 ;;
125 esac
126 done
127 shift $((OPTIND-1))
128 if [ $# -eq 0 ]
129 then
130 echo "No packages specified."
131 exit 1
132 fi
133 for pkg in $@
134 do
135 repo="$(find_pkg_repo "$pkg")"
136 (
137 cd "$repo"/"$pkg"
138 if [ -n "$pkgver" ]
139 then
140 update_pkgver "$pkgver"
141 fi
142 if [ $updpkgrel -eq 1 ]
143 then
144 update_pkgrel "$pkg"
145 fi
146 if [ $checksum -eq 1 ]
147 then
148 abuild checksum
149 fi
150 if [ $builddeps -eq 1 ]
151 then
152 abuild -R
153 else
154 abuild -r
155 fi
156 )
157 done
158)
159
160print_pkgver() {
161 if [ $# -ne 0 ]
162 then
163 usage
164 exit 1
165 fi
166 if [ -d .git ]
167 then
168 set +e
169 pkgver=$(git describe --abbrev=0 2>/dev/null)
170 if [ $? -ne 0 ]
171 then
172 pkgver=0
173 fi
174 set -e
175 if ! git describe --exact-match HEAD >/dev/null 2>&1
176 then
177 cdate=$(git show -s -1 --format='%ci' HEAD)
178 cdate=$(echo "$cdate" | cut -d' ' -f1 | sed -e 's/-//g')
179 pkgver="${pkgver}_git${cdate}"
180 fi
181 elif [ -d .hg ]
182 then
183 pkgver=$(hg id -T '{latesttag}')
184 if [ "$(hg id -T '{latesttagdistance}')" -ne 0 ]
185 then
186 pkgver="$(hg id -T '{latesttag}_hg{sub("-", "", date|shortdate)}')"
187 fi
188 else
189 pkgver=unknown_0000
190 fi
191 echo "$pkgver"
192}
193
194mirror_ver() (
195 mirror="$1"
196 pkg="$2"
197 apk policy "$pkg" | while read -r line
198 do
199 case "$line" in
200 *:)
201 ver="${line%:}"
202 ver="${ver## }"
203 ;;
204 *$mirror*)
205 echo "$ver"
206 ;;
207 esac
208 done
209)
210
211get_aver() {
212 aver="${REPOSITORY:-}"
213 if [ ${#aver} -eq 0 ]
214 then
215 . /etc/os-release
216 aver="v$(printf "%s" "$VERSION_ID" | cut -d. -f1-2)"
217 fi
218 echo "$aver"
219}
220
221upload_pkg() (
222 repo="$1"
223 pkg="$2"
224 arch="$(uname -m)"
225 aver="$(get_aver)"
226
227 set -x
228 path="$remote_path/$aver/$repo/$arch"
229 ssh "$remote" mkdir -p "$path"
230
231 url=$(echo "$remote" | cut -d@ -f2)
232 prev_ver=$(mirror_ver "$url" "$pkg")
233
234 for ver in $prev_ver
235 do
236 if [ "$prev_ver" != "none" ]
237 then
238 ssh "$remote" rm -f "$path/$pkg-$ver.apk"
239 fi
240 done
241 pkgver="$(get_pkgvar pkgver)"
242 pkgrel="$(get_pkgvar pkgrel)"
243
244 rsync --blocking-io -rsP \
245 ~/packages/"$repo/$arch/$pkg-$pkgver-r$pkgrel.apk" "$remote":"$path/"
246 set +x
247)
248
249update_index() (
250 repo="$1"
251 arch="$(uname -m)"
252
253 . /etc/os-release
254 aver="$(get_aver)"
255
256 path="$remote_path/$aver/$repo/$arch"
257
258 set -x
259 ssh "$remote" \
260 find "$path" -type f -name '*.apk' -print0 |
261 ssh "$remote" xargs -0 apk index \
262 --rewrite-arch "$(uname -m)" \
263 -x "$path"/APKINDEX.tar.gz \
264 -o "$path"/APKINDEX.unsigned.tar.gz
265 rsync --blocking-io -rP \
266 "$remote:$path/APKINDEX.unsigned.tar.gz" \
267 /tmp/APKINDEX.tar.gz
268 abuild-sign /tmp/APKINDEX.tar.gz
269 rsync --blocking-io -rP /tmp/APKINDEX.tar.gz "$remote:$path/"
270 set +x
271)
272
273upload() (
274 if [ $# -lt 2 ]
275 then
276 usage
277 exit 1
278 fi
279 remote="$1"
280 remote_path="$2"
281 shift 2
282 if [ $# -eq 0 ]
283 then
284 echo "No packages specified"
285 exit 1
286 fi
287 repos=""
288 for pkg in $@
289 do
290 repo=$(find_pkg_repo "$pkg")
291 if ! echo "$repos" | grep "$repo" >/dev/null
292 then
293 repos="$repo $repos"
294 fi
295 (
296 cd "$repo"/"$pkg"
297 arch="$(get_pkgvar arch)"
298 subpkgs="$pkg:_:$arch $(get_pkgvar subpackages)"
299 for subpkg in $subpkgs
300 do
301 name="$(echo "$subpkg" | cut -d':' -f1)"
302 upload_pkg "$repo" "$name"
303 done
304 )
305 done
306 for repo in $repos
307 do
308 update_index $repo
309 done
310)
311
312if [ $# -lt 1 ]
313then
314 usage
315 exit 1
316fi
317cmd="$1"
318shift
319
320case "$cmd" in
321 add-repo)
322 add_repo "$@"
323 ;;
324 build)
325 build "$@"
326 ;;
327 pkgver)
328 print_pkgver "$@"
329 ;;
330 upload)
331 upload "$@"
332 ;;
333 help|-h)
334 usage
335 ;;
336esac