#!/bin/sh # shellcheck source=conf/default.conf . "${0%/*}/../conf/default.conf" # shellcheck disable=SC2016 usage() { >&2 echo '' >&2 echo 'modify-package-state [options] packages-file:' >&2 echo ' modify state (file) of package(s).' >&2 echo '' >&2 echo 'possible options:' >&2 echo ' -b|--block: Block package(s).' >&2 echo ' -f|--faulty: Mark testing/tested package(s) as faulty.' >&2 echo ' -h|--help: Show this help and exit.' >&2 echo ' -n|--no-report: Do not report what packages were modified.' >&2 echo ' -t|--tested: Mark package(s) as tested.' >&2 echo ' -u|--unblock: Unblock package(s).' >&2 echo '' >&2 echo 'Exactly one of -b|-t|-u is needed for actual operation.' [ -z "$1" ] && exit 1 || exit "$1" } # TODO: binary packages should not be identified by revisions, but by versions eval set -- "$( getopt -o bfhntu \ --long block \ --long faulty \ --long help \ --long no-report \ --long tested \ --long unblock \ -n "$(basename "$0")" -- "$@" || \ echo usage )" action='' report=true while true do case "$1" in -b|--block) if [ -n "${action}" ]; then >&2 echo 'Conflicting/redundand arguments.' usage fi action='block' ;; -f|--faulty) if [ -n "${action}" ]; then >&2 echo 'Conflicting/redundand arguments.' usage fi action='faulty' ;; -h|--help) usage 0 ;; -n|--no-report) report=false ;; -t|--tested) if [ -n "${action}" ]; then >&2 echo 'Conflicting/redundand arguments.' usage fi action='tested' ;; -u|--unblock) if [ -n "${action}" ]; then >&2 echo 'Conflicting/redundand arguments.' usage fi action='unblock' ;; --) shift break ;; *) >&2 echo 'Whoops, forgot to implement option "'"$1"'" internally.' exit 42 ;; esac shift done if [ -z "${action}" ]; then >&2 echo 'Expected -b|-f|-t|-u.' usage fi if [ $# -ne 1 ]; then >&2 echo 'Too few or too many arguments.' usage fi clean_up() { rm -rf --one-file-system "${tmp_dir}" } tmp_dir=$(mktemp -d 'tmp.modify-package-state.XXXXXXXXXX' --tmpdir) trap clean_up EXIT input_file="$1" if ${report}; then if ! [ -w "${input_file}" ]; then >&2 printf \ 'Cannot open file "%s" for writing.' \ "${input_file}" exit 2 fi move_output() { cat "${output_file}" > "${input_file}" clean_up } output_file="${tmp_dir}/output-file" touch "${output_file}" trap 'move_output' EXIT else output_file='/dev/null' fi if ! [ -r "${input_file}" ]; then >&2 printf \ 'Cannot open file "%s" for reading.' \ "${input_file}" exit 2 fi exec 9> "${sanity_check_lock_file}" if ! flock -s -n 9; then >&2 echo 'Cannot get sanity-check lock.' exit fi if [ "${action}" = 'tested' ]; then receive_buglist 'Testing' > \ "${tmp_dir}/package-bug-titles" fi { err=0 while read -r package reason; do if echo "${package}" | \ grep -q '\.pkg\.tar\.xz$'; then package=$( find "${work_dir}/package-states" -maxdepth 1 \( -name '*.tested' -o -name '*.testing' \) \ -exec grep -qxF "${package}" '{}' \; \ -printf '%f\n' | \ sed 's|\.[^.]\+$||' | \ sort -u ) if [ -z "${package}" ]; then continue fi fi repo=$( printf '%s' "${package##*.}" | \ base64 -w0 ) pkgbase="${package%.*}" mod_git_rev=$( printf '%s' "${package##*.}" | \ base64 -w0 ) pkgbase="${pkgbase%.*}" git_rev=$( printf '%s' "${package##*.}" | \ base64 -w0 ) pkgbase=$( printf '%s' "${package%.*}" | \ base64 -w0 ) if [ "${action}" = 'block' ] || \ [ "${action}" = 'unblock' ]; then # these packages need to be on the build list if ! tr ' ' '.' < \ "${work_dir}/build-list" | \ grep -qxF "${package}"; then >&2 printf 'Package "%s" is not on the build-list.\n' "${package}" err=2 continue fi fi case "${action}" in 'block') if [ -z "${reason}" ]; then >&2 printf 'No reason is given for blocking package "%s".\n' "${package}" err=2 else echo "${reason}" > \ "${work_dir}/package-states/${package}.blocked" # shellcheck disable=SC2016 { printf 'UPDATE `build_assignments`' printf ' JOIN `package_sources` ON `build_assignments`.`package_source`=`package_sources`.`id`' printf ' JOIN `upstream_repositories` ON `package_sources`.`upstream_package_repository`=`upstream_repositories`.`id`' printf ' SET `build_assignments`.`is_blocked`=from_base64("%s")' \ "$(printf '%s' "${reason}" | base64 -w0)" printf ' WHERE' printf ' `package_sources`.`%s`=from_base64("%s") AND' \ 'pkgbase' "${pkgbase}" \ 'git_revision' "${git_rev}" \ 'mod_git_revision' "${mod_git_rev}" printf ' `upstream_repositories`.`name`=from_base64("%s");\n' \ "${repo}" } | \ ${mysql_command} printf '%s %s\n' "${package}" "${reason}" fi ;; 'faulty') if [ -f "${work_dir}/package-states/${package}.tested" ]; then mv \ "${work_dir}/package-states/${package}.tested" \ "${work_dir}/package-states/${package}.testing" # shellcheck disable=SC2016 { printf 'UPDATE `binary_packages`' printf ' JOIN `%s` ON `%s`.`id`=`%s`.`%s`' \ 'build_assignments' 'build_assignments' 'binary_packages' 'build_assignment' \ 'package_sources' 'package_sources' 'build_assignments' 'package_source' \ 'upstream_repositories' 'upstream_repositories' 'package_sources' 'upstream_package_repository' printf ' SET `binary_packages`.`has_issues`=1, `binary_packages`.`is_tested`=0' printf ' WHERE' printf ' `package_sources`.`%s`=from_base64("%s") AND' \ 'pkgbase' "${pkgbase}" \ 'git_revision' "${git_rev}" \ 'mod_git_revision' "${mod_git_rev}" printf ' `upstream_repositories`.`name`=from_base64("%s");\n' \ "${repo}" } | \ ${mysql_command} printf '%s\n' "${package}" fi ;; 'tested') if [ -f "${work_dir}/package-states/${package}.testing" ] && \ ! grep -qF "[${package%.*.*.*}]" "${tmp_dir}/package-bug-titles"; then mv \ "${work_dir}/package-states/${package}.testing" \ "${work_dir}/package-states/${package}.tested" # shellcheck disable=SC2016 { printf 'UPDATE `binary_packages`' printf ' JOIN `%s` ON `%s`.`id`=`%s`.`%s`' \ 'build_assignments' 'build_assignments' 'binary_packages' 'build_assignment' \ 'package_sources' 'package_sources' 'build_assignments' 'package_source' \ 'upstream_repositories' 'upstream_repositories' 'package_sources' 'upstream_package_repository' printf ' SET `binary_packages`.`is_tested`=1' printf ' WHERE' printf ' `package_sources`.`%s`=from_base64("%s") AND' \ 'pkgbase' "${pkgbase}" \ 'git_revision' "${git_rev}" \ 'mod_git_revision' "${mod_git_rev}" printf ' `upstream_repositories`.`name`=from_base64("%s");\n' \ "${repo}" } | \ ${mysql_command} printf '%s\n' "${package}" fi ;; 'unblock') if [ -f "${work_dir}/package-states/${package}.blocked" ]; then rm "${work_dir}/package-states/${package}.blocked" # shellcheck disable=SC2016 { printf 'UPDATE `build_assignments`' printf ' JOIN `package_sources` ON `build_assignments`.`package_source`=`package_sources`.`id`' printf ' JOIN `upstream_repositories` ON `package_sources`.`upstream_package_repository`=`upstream_repositories`.`id`' printf ' SET `build_assignments`.`is_blocked`=NULL' printf ' WHERE' printf ' `package_sources`.`%s`=from_base64("%s") AND' \ 'pkgbase' "${pkgbase}" \ 'git_revision' "${git_rev}" \ 'mod_git_revision' "${mod_git_rev}" printf ' `upstream_repositories`.`name`=from_base64("%s");\n' \ "${repo}" } | \ ${mysql_command} printf '%s\n' "${package}" fi ;; *) >&2 printf 'Whooops, action "%s" not implemented yet.\n' "${action}" exit 42 ;; esac done > \ "${output_file}" exit ${err} } < \ "${input_file}"