#!/bin/sh # contains functions used by more than one script # TODO: # mangle $arch in PKBUILDs to contain i486, i586, i686 # find_pkgbuild package repository # find the PKGBUILD of $package from $repository find_pkgbuild() { local package="$1" local repository="$2" local PKGBUILD='' local repo local file local package_path if [ -f "${repo_paths__archlinux32}/${repository}/${package}/PKGBUILD" ]; then # If this package has some modification, repo="$(find_git_repository_to_package_repository "${repository}")" eval package_path="$(printf '$repo_paths__%s' "${repo}")/${package}" if ! [ -d "${package_path}" ]; then # create some dummy files if it is also new. mkdir -p "${package_path}/repos/${repository}-x86_64" touch "${package_path}/repos/${repository}-x86_64/PKGBUILD" fi fi for repo in ${repo_names}; do if [ "${repo}" = "archlinux32" ]; then # this is not a repository of packages continue fi eval package_path="$(printf '$repo_paths__%s' "${repo}")/${package}" if ! [ -d "${package_path}" ]; then continue fi PKGBUILD="$( ls "${package_path}/repos/${repository}-"*"/PKGBUILD" 2> /dev/null | \ tr ' ' '\n' | \ grep -v -- '-i686/PKGBUILD$' | \ grep -v -- '-\(staging\|testing\)-[^/]\+/PKGBUILD$' | \ sort | \ tail -n1 )" if [ -n "${PKGBUILD}" ]; then echo "${PKGBUILD}" break fi done } # apply customizations to a package # (to be executed in the package's directory) apply_package_customizations() { if [ ! -f 'PKGBUILD' ]; then >&2 echo 'PKGBUILD not found.' pwd exit 1 fi local repo local package repo="$(pwd)" package="${repo%/*/*}" package="${package##*/}" repo="${repo##*/}" repo="${repo%-any}" repo="${repo%-x86_64}" if [ ! -f 'PKGBUILD.changes-applied' ]; then # add i686 to the arch list sed '/^arch=[^#]*any/!s|^\(arch=(\)\([^#]*)\)\s*\(#.*\)\?$|\1'"'i686'"' \2|' -i 'PKGBUILD' if [ -f "${repo_paths__archlinux32}/${repo}/${package}/PKGBUILD" ]; then # If this package has modifications (or is new), apply them now: # append PKGBUILD cat "${repo_paths__archlinux32}/${repo}/${package}/PKGBUILD" >> \ 'PKGBUILD' # copy (and overwrite) other files for file in "${repo_paths__archlinux32}/${repo}/${package}/"*; do if [ -f "${file}" ] && [ "${file##*/}" != 'PKGBUILD' ]; then cp "${file}" ./ fi done fi touch 'PKGBUILD.changes-applied' fi } # find_repository_with_commit commit # find the repository which has $commit find_repository_with_commit() { local repository for repository in ${repo_names}; do if [ "$(eval git -C "$(printf '$repo_paths__%s' "${repository}")" cat-file -t "$1" 2> /dev/null)" = "commit" ]; then echo "${repository}" return 0 fi done >&2 printf 'find_repository_with_commit: Cannot find repository with commit "%s"\n' "$1" exit 1 } # find_git_repository_to_package_repository repository # find the git repository which tracks the package repository $repository find_git_repository_to_package_repository() { local repository for repository in ${repo_names}; do if [ "${repository}" = "archlinux32" ]; then continue fi if [ -n "$( ( eval ls "$(printf '$repo_paths__%s' "${repository}")/"*"/repos" | \ grep -v ':$' | \ sed 's|-[^-]\+$||' | \ sort -u echo "$1" ) | \ sort | \ uniq -d )" ]; then echo "${repository}" return 0 fi done >&2 echo "can't find git repository with package repository '$1'" exit 1 } # package_locked_or_blocked package git_revision mod_git_revision repository # return if package - of given repository and revisions - is [locked or blocked] package_locked_or_blocked() { [ -f "${work_dir}/package-states/$1.$2.$3.$4.locked" ] || \ [ -f "${work_dir}/package-states/$1.$2.$3.$4.blocked" ] } # generate_package_metadata $package $git_revision $mod_git_revision $repository # or # generate_package_metadata $package.$git_revision.$mod_git_revision.$repository # generate the meta data files of a package (dependencies, built packages, ...) generate_package_metadata() { local package="$1" local git_revision="$2" local mod_git_revision="$3" local repository="$4" local file_prefix local file local PKGBUILD if [ $# -eq 1 ]; then # second form repository="${package##*.}" package="${package%.*}" mod_git_revision="${package##*.}" package="${package%.*}" git_revision="${package##*.}" package="${package%.*}" fi file_prefix="${work_dir}/package-infos/${package}.${git_revision}.${mod_git_revision}" if [ -e "${file_prefix}.builds" ] && \ [ -e "${file_prefix}.depends" ] && \ [ -e "${file_prefix}.needs" ] && \ [ -e "${file_prefix}.packages" ]; then return 0 fi eval git -C "$(printf '$repo_paths__%s' "$(find_repository_with_commit "${git_revision}")")" checkout "${git_revision}" eval git -C "$(printf '$repo_paths__%s' "$(find_repository_with_commit "${mod_git_revision}")")" checkout "${mod_git_revision}" PKGBUILD="$(find_pkgbuild "${package}" "${repository}")" if [ ! -r "${PKGBUILD}" ]; then echo "can't find PKGBUILD to package '${package}' from repository '${repository}': '${PKGBUILD}'" exit 1 fi overlays_dir="$(mktemp -d)" sudo mount -t tmpfs none "${overlays_dir}" mkdir \ "${overlays_dir}/upper" \ "${overlays_dir}/work" \ "${overlays_dir}/merged" sudo mount -t overlay overlay -o lowerdir="${PKGBUILD%/*}":"/",upperdir="${overlays_dir}/upper",workdir="${overlays_dir}/work" "${overlays_dir}/merged" ( cd "${overlays_dir}/merged" apply_package_customizations ) sudo systemd-nspawn -q \ -D "${overlays_dir}/merged" \ --register=no \ ${base_dir}/bin/mksrcinfo sudo umount -f "${overlays_dir}/merged" mv \ "${overlays_dir}/upper/.SRCINFO" \ "${file_prefix}.SRCINFO" sudo umount -f "${overlays_dir}" rmdir "${overlays_dir}" # otherwise this just calls for trouble sed -i '/=\s*$/d' "${file_prefix}.SRCINFO" # extract "builds" = provides \cup pkgname grep "$(printf '^\\(\tprovides\\|pkgname\\) = ')" "${file_prefix}.SRCINFO" | \ cut -d= -f2 | \ sed 's|^\s\+||; s|[<>]$||' | \ sort -u > \ "${file_prefix}.builds" # extract "packages" = pkgname grep '^pkgname = ' "${file_prefix}.SRCINFO" | \ cut -d= -f2 | \ sed 's|^\s\+||; s|[<>]$||' | \ sort -u > \ "${file_prefix}.packages" # extract "needs" = depends \setminus "builds" ( grep "$(printf '^\tdepends = ')" "${file_prefix}.SRCINFO" | \ cut -d= -f2 | \ sed 's|^\s\+||; s|[<>]$||' | \ sort -u sed 'p' "${file_prefix}.builds" ) | \ sort | \ uniq -u > \ "${file_prefix}.needs" # extract "depends" = makedepends \cup checkdepends \cup depends ( sed -n "$(printf '/^pkgname = /q;/^\tdepends = /p')" "${file_prefix}.SRCINFO" grep "$(printf '^\t\\(makedepends\\|checkdepends\\) = ')" "${file_prefix}.SRCINFO" ) | \ cut -d= -f2 | \ sed 's|^\s\+||; s|[<>]$||' | \ sort -u > \ "${file_prefix}.depends" rm "${file_prefix}.SRCINFO" } # delete_old_metadata # delete old (=unneeded) meta data of packages delete_old_metadata() { ( ls -1 "${work_dir}/package-infos" | \ sed ' s|\.\([^.]\+\)\.\([^.]\+\)\.[^.]\+$| \1 \2| ' | \ sort -u ls -1 "${work_dir}/package-states" | \ sed ' s|\.\([^.]\+\)\.\([^.]\+\)\(\.[^.]\+\)\{2\}$| \1 \2| ' | \ sort -u | \ sed 'p' cut -d' ' -f1,2,3 "${work_dir}/build-list" | \ sed 'p' ) | \ sort | \ uniq -u | \ while read -r pkg rev mod_rev; do rm -f "${work_dir}/package-infos/${pkg}.${rev}.${mod_rev}".* done } # repository_of_package $package.$repo_revision.$mod_repo_revision.$repository # print which (stable) repository a package belongs to repository_of_package() { local package="$1" local repository="${package##*.}" package="${package%.*}" local a32_rev="${package##*.}" package="${package%.*.*}" case "${repository}" in 'multilib') if git -C "${repo_paths__archlinux32}" archive --format=tar "${a32_rev}" -- 'extra-from-multilib' | \ tar -Ox | \ grep -qFx "${package%.*.*.*}"; then echo 'extra' else echo 'community' fi ;; *) echo "${repository}" esac } # official_or_community $package.$repo_revision.$mod_repo_revision.$repository # print wether the specified package is an official package (print # nothing) or a community package (print 'community-') official_or_community() { if [ "$(repository_of_package "$1")" = 'community' ]; then echo 'community-' fi } # ls_master_mirror $path # list content of $path on the master mirror (via rsync) ls_master_mirror() { local path="$1" ${master_mirror_command} \ "${master_mirror_directory}/${path}/" | \ grep -v '\s\.$' | \ awk '{print $5}' } # remove_old_package_versions $directory $package_file # removes all other versions of $package_file in $directory on the master mirror remove_old_package_versions() { local directory="$1" local package="$2" local pkgname="${package%-*-*-*.pkg.tar.xz}" ${master_mirror_command} \ --recursive \ --delete \ $( \ ls_master_mirror "${directory}" | \ grep "^$(str_to_regex "${pkgname}")\(-[^-]\+\)\{3\}\.pkg\.tar\.xz\(\.sig\)\?\$" | \ grep -v "^$(str_to_regex "${package}")\(\.sig\)\?\$" | \ sed 's|^|--include=|' ) \ '--exclude=*' \ ./ \ "${master_mirror_directory}/${directory}/" } # wait_some_time $minimum $diff # wait between minimum and minimum+diff seconds (diff defaults to 30) wait_some_time() { local minimum=$1 local diff=$2 local random if [ -z "${diff}" ]; then diff=30 fi random="$( dd if='/dev/urandom' count=1 2> /dev/null | \ cksum | \ cut -d' ' -f1 )" sleep $((${minimum} + ${random} % ${diff})) } # str_to_regex $string # escape dots for use in regex str_to_regex() { echo "$1" | \ sed 's|\.|\\.|g' }