#!/bin/bash # update an archlinux32 package # archiso # archlinux32-keyring # archlinux32-keyring-transition # asp # dart # devtools # eclipse # flashplugin # freebasic # linux # linux-lts # linux-pae (no upstream) # linux-zen # python-pip-bootstrap # python-setuptools-bootstrap # reflector # teamspeak3-server git_repo_path='/usr/src/archlinux32/packages' upstream_git_path='/usr/src/archlinux/packages' upstream_community_git_path='/usr/src/archlinux/community' archlinuxewe_git_path=~erich/'eigeneSkripte/archPackages' vagrant_path=$( readlink -f ~/"virtual-boxes/archlinux32-test" ) base_dir=$( dirname "$( readlink -f "$0" )" ) if [ "x$1" = "x-" ]; then shift else if ! git -C "${git_repo_path}" pull --ff-only || \ ! git -C "${upstream_git_path}" pull --ff-only || \ ! git -C "${upstream_community_git_path}" pull --ff-only || \ ! git -C "${archlinuxewe_git_path}" pull --ff-only; then >&2 echo 'Your git repos cannot cleanly be updated' exit 1 fi fi case $# in 0) >&2 echo "usage: $0 pkg1 pkg2 ..." exit 1 ;; 1) ;; *) for param in "$@"; do "$0" - "${param}" || exit $? done exit 0 ;; esac pkgname="$1" repo=$( git -C "${git_repo_path}" archive HEAD -- | \ tar -t --wildcards "*/${pkgname}/PKGBUILD" | \ cut -d/ -f1 ) if [ "$(printf '%s\n' "${repo}" | wc -l)" -ne 1 ]; then >&2 printf 'package "%s" does not exist in exactly one repository\n' "${pkgname}" exit 1 fi update_checksum() { checksums=$( ssh arch32-test ' cd '"${pkgname}"' makepkg -g ' \ mostly upstream, but with # replaced sources, checksums and pkgver (might be identical to # upstream, though) update_path='archlinuxewe' ;; 'dart'|'eclipse'|'flashplugin'|'freebasic'|'reflector'|'teamspeak3-server') # an upstream package which is updated by solely updating its checksum update_path='checksum' ;; 'archlinux32-keyring'|'archlinux32-keyring-transition'|'python-pip-bootstrap'|'python-setuptools-bootstrap'|*'-dummy') # a package without upstream which is updated by updating its # version (according to watch-versions) and checksum update_path='version and checksum without upstream' ;; 'linux'|'linux-lts'|'linux-zen') # a kernel which exists upstream -> different config and checksums update_path='kernel with upstream' ;; 'linux-pae') # a kernel which does not exist upstream -> complete package sources # in our repository update_path='kernel without upstream' ;; *) >&2 printf 'I don'"'"'t know how to update package "%s"\n' "${pkgname}" exit 1 ;; esac if ssh -o ConnectTimeout=1 arch32-test true; then vm_is_running=true else vm_is_running=false fi if ! ${vm_is_running}; then cd "${vagrant_path}" vagrant up fi ssh arch32-test 'rm -rf --one-file-system "'"${pkgname}"'"' case ${update_path} in 'archlinuxewe') archlinuxewe_PKGBUILD=$( git -C "${archlinuxewe_git_path}" archive HEAD -- "${pkgname}32/PKGBUILD" | \ tar -Ox ) repo_arch=$( printf '%s\n' "${archlinuxewe_PKGBUILD}" | \ grep '^arch=' | \ cut -d'=' -f2 | \ tr '()"'"'" '\n' | \ grep -xF 'x86_64' || \ echo any ) old_pkgver=$( grep '^pkgver=' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" | \ cut -d'=' -f2 ) new_pkgver=$( printf '%s\n' "${archlinuxewe_PKGBUILD}" | \ grep '^pkgver=' | \ cut -d'=' -f2 ) if [ "${old_pkgver}" = "${new_pkgver}" ]; then >&2 echo 'nothing to do' exit fi sha512sums=$( cd "${archlinuxewe_git_path}/${pkgname}32" makepkg -g | \ sed ' s/^/\\1/ $! s/$/\\n/ ' | \ tr -d '\n' ) sed -i ' s/^pkgver=.*/pkgver='"${new_pkgver}"'/ s/^pkgrel=.*/pkgrel=1/ /^\s*sha512sums=(/ { :sum_loop $b N s/^\(\s*\)sha512sums=(.*)/'"${sha512sums}"'/ T sum_loop } ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" scp -r "${upstream_git_path}/${pkgname}/repos/${repo}-${repo_arch}" \ "arch32-test:${pkgname}" if ! ssh arch32-test ' cd "'"${pkgname}"'" cat >> PKGBUILD makepkg --verifysource ' < \ "${git_repo_path}/${repo}/${pkgname}/PKGBUILD"; then >&2 echo 'something went wrong' exit 1 fi git -C "${git_repo_path}" commit "${repo}/${pkgname}/PKGBUILD" -m "${repo}/${pkgname}: ${old_pkgver} -> ${new_pkgver}" ;; 'checksum') used_upstream_git_path="${upstream_git_path}" repo_arch=$( git -C "${used_upstream_git_path}/${pkgname}/repos" archive HEAD -- 2>/dev/null | \ tar -t 2>/dev/null | \ sed 's/^'"${repo}-"'//;t;d' | \ head -n1 ) if [ -z "${repo_arch}" ]; then used_upstream_git_path="${upstream_community_git_path}" repo_arch=$( git -C "${used_upstream_git_path}/${pkgname}/repos" archive HEAD -- | \ tar -t | \ sed 's/^'"${repo}-"'//;t;d' | \ head -n1 ) fi scp -r "${used_upstream_git_path}/${pkgname}/repos/${repo}-${repo_arch}" \ "arch32-test:${pkgname}" sums=$( ssh arch32-test ' cd "'"${pkgname}"'" cat >> PKGBUILD echo '"'"'[ "${arch[0]}" = any ] || arch+=(i686 pentium4)'"'"' >> PKGBUILD makepkg -g ' < "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" \ | sed -n "$( sed ' s,^\([^[:space:]=]\+sums\(_[^[:space:]=]\+\)\?=\).*$,/^\1/ { :a; $be; N; /(.*)/ { p; d; }; :e; p }, t d ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" \ | sort -u )" \ | sed ' $! s/$/\\n/ ' | \ tr -d '\n' ) sed -i ' /^\S\+sums\(_[^=]\+\)\?=(/{ :a s/^\S\+sums[^=]*=(.*)/'"${sums}"'/ tb $b N ba :b p :c s/\(^\|\n\)\S\+sums[^=]*=([^()]*)\($\|\n\)/\1\2/ s/\n\n\+/\n/g $! { N bc } } ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" if ! cat "${used_upstream_git_path}/${pkgname}/repos/${repo}-${repo_arch}/PKGBUILD" "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" \ | ssh arch32-test ' cd "'"${pkgname}"'" cat > PKGBUILD echo '"'"'[ "${arch[0]}" = any ] || arch+=(i686 pentium4)'"'"' >> PKGBUILD makepkg --verifysource '; then >&2 echo 'something went wrong' exit 1 fi git -C "${git_repo_path}" commit "${repo}/${pkgname}/PKGBUILD" -m "${repo}/${pkgname}: new version => new checksum" ;; 'version and checksum without upstream') newver=$( "${base_dir}/watch-versions" -m "${pkgname}" \ | sed ' s/^newver="\([^"]\+\)";$/\1/ t d ' ) if [ -z "${newver}" ]; then >&2 printf 'watch-versions reports no new version for %s\n' "${pkgname}" exit fi sed -i ' s/^epoch=.*$/epoch='"'${newver%:*}'"'/ s/^pkgver=.*$/pkgver='"'${newver#*:}'"'/ s/^pkgrel=.*$/pkgrel='"'1'"'/ ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" git -C "${git_repo_path}/${repo}/${pkgname}" diff HEAD -- PKGBUILD scp -r "${git_repo_path}/${repo}/${pkgname}" \ "arch32-test:${pkgname}" sums=$( ssh arch32-test ' cd "'"${pkgname}"'" echo '"'"'[ "${arch[0]}" = any ] || arch+=(i686 pentium4)'"'"' >> PKGBUILD makepkg -g ' \ | sed ' $! s/$/\\n/ ' | \ tr -d '\n' ) echo "'$sums'" sed -i ' /^\S\+sums\(_[^=]\+\)\?=(/{ :a $b N s/^\S\+sums[^=]*=(.*)/'"${sums}"'/ Ta } ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" if ! ssh arch32-test ' cd "'"${pkgname}"'" cat > PKGBUILD echo '"'"'[ "${arch[0]}" = any ] || arch+=(i686 pentium4)'"'"' >> PKGBUILD makepkg --verifysource ' < "${git_repo_path}/${repo}/${pkgname}/PKGBUILD"; then >&2 echo 'something went wrong' exit 1 fi git -C "${git_repo_path}" commit "${repo}/${pkgname}/PKGBUILD" -m "${repo}/${pkgname}: new version => new checksum" ;; 'kernel without upstream') infos=$( "${base_dir}/watch-versions" "${pkgname}" ) if [ -z "${infos}" ]; then >&2 echo 'Nothing to do.' exit fi old_pkgver=$( printf '%s\n' "${infos}" | \ cut -d' ' -f4 ) new_pkgver=$( printf '%s\n' "${infos}" | \ cut -d' ' -f2 ) sed -i ' s/^pkgver=.*$/pkgver='"'${new_pkgver}'"'/ s/^pkgrel=.*$/pkgrel='"'1'"'/ ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" scp -r "${git_repo_path}/${repo}/${pkgname}" 'arch32-test:' update_checksum case "${pkgname}" in 'linux-pae') scp "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" 'arch32-test:'"${pkgname}/" ssh arch32-test ' cd '"${pkgname}"' sed -i '"'"' /make oldconfig/ s/^\s*#// s/^}$/return 1\n\0/ '"'"' PKGBUILD makepkg -fcrs --asdeps --noconfirm cp src/linux-'"${new_pkgver}"'/.config config ' update_checksum scp 'arch32-test:'"${pkgname}"'/config' "${git_repo_path}/${repo}/${pkgname}/" git -C "${git_repo_path}/${repo}/${pkgname}" add 'PKGBUILD' 'config' ;; *) >&2 printf 'Whoops, I thought %s should be updated as %s, but I don'"'"'t know the details.\n' \ "${pkgname}" "${update_path}" exit 1 ;; esac git -C "${git_repo_path}" commit -m "${repo}/${pkgname}: ${old_pkgver} -> ${new_pkgver}" ;; 'kernel with upstream') old_revision=$( sed -n ' s/^# upstream git\( revision\)\?: *// T p ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" ) if [ -z "${old_revision}" ]; then >&2 printf 'Cannot determine old upstream git revision of "%s".\n' "${pkgname}" >&2 echo '"# upstream git revision: ..." line is missing.' exit 1 fi config_names=$( git -C "${git_repo_path}/${repo}/${pkgname}" archive HEAD -- | \ tar -t | \ grep '^config\($\|\.\)' | \ tr '\n' ' ' ) diff=$( diff -u <( git -C "${upstream_git_path}/${pkgname}/repos/${repo}-x86_64" archive "${old_revision}" -- config | \ tar -Ox | \ sort ) \ <( git -C "${upstream_git_path}/${pkgname}/repos/${repo}-x86_64" archive HEAD -- config | \ tar -Ox | \ sort ) | \ grep '^[+-].' | \ grep -v '^+++\|^---' ) if [ -z "${diff}" ]; then >&2 echo 'nothing changed.' exit 0 fi for config_name in ${config_names}; do { grep -vxF "$( printf '%s\n' "${diff}" | \ sed ' s/^-// t d ' )" "${git_repo_path}/${repo}/${pkgname}/${config_name}" printf '%s\n' "${diff}" | \ sed ' s/^+// t d ' } | \ sponge "${git_repo_path}/${repo}/${pkgname}/${config_name}" done sed -i ' 1 s/^#.*$/# upstream git revision: '"$( git -C "${upstream_git_path}" rev-parse HEAD )"'/ s/'"$( git -C "${upstream_git_path}/${pkgname}/repos/${repo}-x86_64" archive "${old_revision}" -- config | \ tar -Ox | \ sha256sum | \ awk '{print $1}' )"'/'"$( git -C "${upstream_git_path}/${pkgname}/repos/${repo}-x86_64" archive HEAD -- config | \ tar -Ox | \ sha256sum | \ awk '{print $1}' )"'/g ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" { git -C "${upstream_git_path}/${pkgname}/repos/${repo}-x86_64" archive HEAD -- for config_name in ${config_names}; do tar -c -C "${git_repo_path}/${repo}/${pkgname}" "${config_name}" done } | \ ssh arch32-test ' mkdir "'"${pkgname}"'" tar -xiC "'"${pkgname}"'" ' ssh arch32-test ' cd "'"${pkgname}"'" cat >> PKGBUILD sed -i '"'"' '"$( for config_name in ${config_names}; do printf 's/' git -C "${git_repo_path}/${repo}/${pkgname}" archive HEAD -- "${config_name}" | \ tar -Ox | \ sha256sum | \ awk '{print $1}' | \ tr -d '\n' printf '/SKIP/g\n' done )"' /^arch=[^#]*any/!{ /^arch=(/s/(/(i486 i686 pentium4 / } /^\s*cp .\+ \.config\s$/ a make oldconfig s/^}$/return 1\n\0/ '"'"' PKGBUILD ' < \ "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" ssh arch32-test ' cd "'"${pkgname}"'" eval "$(grep '"'"'^\(pkgver\|_srcname\)='"'"' PKGBUILD)" for config_name in '"${config_names}"'; do rm -rf --one-file-system src pkg if [ "${config_name}" = "config" ]; then makepkg -fcrs --asdeps --noconfirm else CARCH=${config_name#config.} makepkg -fcrs --asdeps --noconfirm fi mv src/${_srcname}/.config ${config_name} done ' for config_name in ${config_names}; do scp "arch32-test:${pkgname}/${config_name}" "${git_repo_path}/${repo}/${pkgname}/" done sed -i "$( for config_name in ${config_names}; do printf 's/' git -C "${git_repo_path}/${repo}/${pkgname}" archive HEAD -- "${config_name}" | \ tar -Ox | \ sha256sum | \ awk '{print $1}' | \ tr -d '\n' printf '/' sha256sum "${git_repo_path}/${repo}/${pkgname}/${config_name}" | \ awk '{print $1}' | \ tr -d '\n' printf '/g\n' done )" "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" git -C "${git_repo_path}/${repo}/${pkgname}" commit PKGBUILD ${config_names} -m "${repo}/${pkgname}: new version => new config => new checksum" ;; *) >&2 printf 'Whoops, I thought I knew how to update %s, but apparently I don'"'"'t.\n' \ "${update_path}" exit 1 ;; esac ssh arch32-test 'rm -rf --one-file-system '"${pkgname}" if ! ${vm_is_running}; then ssh arch32-test 'sudo poweroff' err=$? if [ ${err} -eq 255 ]; then err=0 fi exit ${err} fi