#!/bin/bash # update an archlinux32 package # devtools # linux-pae (no upstream) # linux # linux-lts # linux-zen 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 ' | \ sed ' $! s/$/\\n/ ' | \ tr -d '\n' ) sed -i ' /^\S\+sums=(/{ :a N /)/!ba s/^\S\+sums=(.*)/'"${checksums}"'/ } ' "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" } # selecting the "update path" case "${pkgname}" in 'devtools') # a package which is in [archlinuxewe] -> mostly upstream, but with # replaced sources, checksums and pkgver (might be identical to # upstream, though) update_path='archlinuxewe' ;; 'eclipse'|'flashplugin') # an upstream package which is updated by solely updating its checksum update_path='checksum' ;; '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 ) if [ "${old_pkgver}" = "${new_pkgver}" ]; then >&2 echo 'nothing to do' exit fi new_pkgver=$( printf '%s\n' "${archlinuxewe_PKGBUILD}" | \ grep '^pkgver=' | \ cut -d'=' -f2 ) 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+=(i686)" >> PKGBUILD makepkg -g ' < "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" \ | sed ' $! s/$/\\n/ ' | \ tr -d '\n' ) echo "'$sums'" sed -i ' /^\S\+sums\(_[^=]\+\)\?=(/{ :a $b N s/^\S\+sums[^=]*=(.*)/'"${sums}"'/ } ' "${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+=(i686)" >> 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" ;; '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 pentium3 / } /make oldconfig/ s/^\s*#// s/^}$/return 1\n\0/ '"'"' PKGBUILD ' < \ "${git_repo_path}/${repo}/${pkgname}/PKGBUILD" ssh arch32-test ' cd "'"${pkgname}"'" eval "$(grep '"'"'^_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