index : builder | |
Archlinux32 build system | gitolite user |
summaryrefslogtreecommitdiff |
-rwxr-xr-x | bin/why-dont-you | 465 |
diff --git a/bin/why-dont-you b/bin/why-dont-you index 2e3ea86..e873c71 100755 --- a/bin/why-dont-you +++ b/bin/why-dont-you @@ -7,6 +7,9 @@ # shellcheck source=conf/default.conf . "${0%/*}/../conf/default.conf" +# TODO: reintrocude "keep", "stubbornly_keep", "stabilize" and "unstage" +# using information from the database. + action="$1" shift @@ -17,342 +20,164 @@ case "${action}" in 'build') - for pkg in "$@"; do - { - grep "^$(str_to_regex "${pkg}") " "${work_dir}/build-list" || \ - >&2 printf '"%s" is not on the build list.\n' "${pkg}" - } | \ - while read -r package git_revision mod_git_revision repository; do - - if [ -f "${work_dir}/package-states/$1.$2.$3.$4.locked" ]; then - printf '"%s" is locked by ' "$1" - sort -u < \ - "${work_dir}/package-states/$1.$2.$3.$4.locked" \ - sed ' - :a - $!{ - N - s/\n/, / - ba - } - s/$/./ - ' - continue - fi - if [ -f "${work_dir}/package-states/$1.$2.$3.$4.blocked" ]; then - printf '"%s" is blocked: "' "${pkg}" - tr '[:space:]' ' ' < \ - "${work_dir}/package-states/$1.$2.$3.$4.blocked" | \ - sed ' - s| \+| | - s|^ || - s| $|| - ' - printf '"\n' - continue - fi - - unmet_dependencies=$(find_dependencies_on_build_list "${package}" "${git_revision}" "${mod_git_revision}" "${repository}") - if [ -n "${unmet_dependencies}" ]; then - printf '"%s" has unmet dependencies:\n' "${package}" - echo "${unmet_dependencies}" | \ - while read -r dep; do - grep -lxF "${dep}" "${work_dir}/package-infos/"*".builds" | \ - sed ' - s|^.*/|| - s|\(\.[^.]\+\)\{4\}|| - ' - done | \ - sort -u - printf '\n' - - continue - fi - - if [ -f "${work_dir}/package-states/${package}.${git_revision}.${mod_git_revision}.${repository}.broken" ]; then - printf '"%s" is broken (%sx built), but would be built\n' \ - "${pkg}" \ - "$(wc -l < "${work_dir}/package-states/${package}.${git_revision}.${mod_git_revision}.${repository}.broken")" - else - printf '"%s" would be built\n' "${pkg}" - fi - done - - done - - ;; - - 'stabilize'|'unstage') - - if [ "${action}" = 'stabilize' ]; then - suffix='tested' - else - suffix='done' - fi - + # shellcheck disable=SC2016 { - awk '{print $1 "." $2 "." $3 "." $4}' < \ - "${work_dir}/build-list" - if [ "${action}" = 'stabilize' ]; then - find "${work_dir}/package-states" -maxdepth 1 \( \ - -name '*.done' -o \ - -name '*.testing' \ - \) -printf '%f\n' | \ - sed 's|\.[^.]\+$||' - fi + printf 'CREATE TEMPORARY TABLE `pkgbases` (`pkgbase` VARCHAR(64));\n' + printf 'INSERT INTO `pkgbases` VALUES ' + # shellcheck disable=SC2046 + printf '(from_base64("%s")),' \ + $( + printf '%s\n' "$@" | \ + base64_encode_each + ) | \ + sed 's/,$/;\n/' + # we select everything which is possibly of any interest: + # - id (to see if it actually is on the build-list + # - to_build.is_broken + # - failed_builds_count + # - to_build.is_blocked + # - deps.pkgbase (any dependency pending?) + # - build_slaves.name (is anyone building this?) + # - pkgbase + printf 'SELECT DISTINCT `to_build`.`ba_id`,' + printf 'If(`to_build`.`is_broken`,1,0),' + printf '(' + printf 'SELECT count(*) FROM `failed_builds`' + printf 'WHERE `failed_builds`.`build_assignment`=`to_build`.`ba_id`' + printf ')' + printf ',replace(to_base64(`%s`.`%s`),"\\n","")' \ + 'to_build' 'is_blocked' \ + 'deps' 'pkgbase' \ + 'build_slaves' 'name' \ + 'pkgbases' 'pkgbase' + # at least one row for each given `pkgbase` + printf ' FROM `pkgbases`' + printf ' LEFT JOIN ' + printf '(' + # join the tables for the to-be-built packages: + # package_source, build_assignment, binary_package, repostory + printf 'SELECT DISTINCT `tb_ps`.`pkgbase`,`tb_bin`.`id` AS `bin_id`,`tb_ba`.`id` AS `ba_id`,`tb_ba`.`is_blocked`,`tb_ba`.`is_broken`' + printf ' FROM `package_sources` AS `tb_ps`' + mysql_join_package_sources_build_assignments 'tb_ps' 'tb_ba' + mysql_join_build_assignments_binary_packages 'tb_ba' 'tb_bin' + mysql_join_binary_packages_repositories 'tb_bin' 'tb_rep' + printf ' WHERE `tb_rep`.`name`="build-list"' + printf ') AS `to_build`' + printf ' ON `to_build`.`pkgbase`=`pkgbases`.`pkgbase`' + printf ' LEFT JOIN ' + printf '(' + # same join as above, but with different names - for the + # potential dependencies + printf 'SELECT DISTINCT `dep_ps`.`pkgbase`,`dependencies`.`dependent`' + printf ' FROM `package_sources` AS `dep_ps`' + mysql_join_package_sources_build_assignments 'dep_ps' 'dep_ba' + mysql_join_build_assignments_binary_packages 'dep_ba' 'dep_bin' + mysql_join_binary_packages_repositories 'dep_bin' 'dep_rep' + # now we have some (=3) additional joins, + # because we are interested in dependency relations to `to_build` + mysql_join_binary_packages_install_target_providers 'dep_bin' + mysql_join_install_target_providers_dependencies + mysql_join_dependencies_dependency_types + printf ' WHERE `dep_rep`.`name`="build-list"' + printf ' AND `dependency_types`.`relevant_for_building`' + printf ') AS `deps`' + printf ' ON `deps`.`dependent`=`to_build`.`bin_id`' + # now we join with build slaves to see if someone builds this + printf ' LEFT JOIN `build_slaves` ON `build_slaves`.`currently_building`=`to_build`.`ba_id`' + printf ';\n' } | \ - sort -u > \ - "${tmp_dir}/unmoveable-list" - - find "${work_dir}/package-states" -maxdepth 1 -name "*.${suffix}" -printf '%f\n' | \ - sed 's|\.[^.]\+$||' | \ - sort -u > \ - "${tmp_dir}/moveable-list" - - cat "${tmp_dir}/moveable-list" "${tmp_dir}/unmoveable-list" | \ + mysql_run_query | \ + tr '\t' ' ' | \ + sort -k7,7 -k6,6 -k5,5 | \ sed ' - s|^|'"${work_dir}/package-infos/"'| - s|$|.run-depends| + / NULL \S\+$/ b multi-dep + :multi-slave + $!N + s/^\(\(\S\+ \)\{5\}\)\(\S\+\)\( \S\+\)\n\(\S\+ \)\{5\}\(\S\+\)\4/\1\3,\6\4/ + t multi-slave + P + D + :multi-dep + / NULL\( \S\+\)\{3\}$/! b + $!N + s/^\(\(\S\+ \)\{4\}\)\(\S\+\)\(\( \S\+\)\{2\}\)\n\(\S\+ \)\{4\}\(\S\+\)\4/\1\3,\7\4/ + t multi-dep + P + D ' | \ - # base is boring, so we ignore it (might give result "... can be unstaged" although it _will_not_ be unstaged! - xargs -r grep -vHxF 'base' | \ sed ' - s|^[^:]*/|| - s|\.run-depends:| | + s/NULL,//g ' | \ - sort -k2,2 > \ - "${tmp_dir}/all-run-depends" - - cat "${tmp_dir}/moveable-list" "${tmp_dir}/unmoveable-list" | \ - sed ' - s|^|'"${work_dir}/package-infos/"'| - s|$|.builds| - ' | \ - # base is boring, so we ignore it (might give result "... can be unstaged" although it _will_not_ be unstaged! - xargs -r grep -vHxF 'base' | \ - sed ' - s|^[^:]*/|| - s|\.builds:| | - ' | \ - sort -k2,2 > \ - "${tmp_dir}/all-builds" - - for pkg in "$@"; do - - if ! state_file=$( - grep '^'"$(str_to_regex "${pkg}")"'\(\.[^.]\+\)\{3\}$' "${tmp_dir}/moveable-list" - ) || \ - [ ! -f "${work_dir}/package-states/${state_file}.${suffix}" ]; then - printf '"%s" is not %s yet!\n' "${pkg}" "${suffix}" - continue - fi - - echo "${state_file}" > "${tmp_dir}/dependent.new" - touch "${tmp_dir}/dependent" - - while [ -s "${tmp_dir}/dependent.new" ]; do - cat "${tmp_dir}/dependent.new" "${tmp_dir}/dependent" | \ - sort -u | \ - sponge "${tmp_dir}/dependent" - - { - sed ' - s|^|'"${work_dir}"'/package-infos/| - s|$|.builds| - ' "${tmp_dir}/dependent.new" | \ - xargs -r cat | \ - sort -u | \ - join -1 1 -2 2 -o 2.1 - "${tmp_dir}/all-run-depends" - sed ' - s|^|'"${work_dir}"'/package-infos/| - s|$|.run-depends| - ' "${tmp_dir}/dependent.new" | \ - xargs -r cat | \ - sort -u | \ - join -1 1 -2 2 -o 2.1 - "${tmp_dir}/all-builds" - } | \ - sort -u | \ - sponge "${tmp_dir}/dependent.new" - - cat "${tmp_dir}/dependent.new" "${tmp_dir}/dependent" "${tmp_dir}/dependent" | \ - sort | \ - uniq -u | \ - sponge "${tmp_dir}/dependent.new" - done - - dependent_unmoveable=$( - join -1 1 -2 1 -o 2.1 "${tmp_dir}/unmoveable-list" "${tmp_dir}/dependent" - ) - - if [ -n "${dependent_unmoveable}" ]; then - printf 'The following packages are dependent on "%s", but cannot be %sd:\n' "${pkg}" "${action}" - echo "${dependent_unmoveable}" | \ - while read -r sf; do - printf '%s' "${sf}" - if [ -f "${work_dir}/package-states/${sf}.testing" ]; then - printf ' (not tested yet for %s days)' "$(( ($(date '+%s') - $(stat -c '%Y' "${work_dir}/package-states/${sf}.testing")) / 3600 / 24 ))" - elif [ -f "${work_dir}/package-states/${sf}.done" ]; then - printf ' (not unstaged yet for %s days)' "$(( ($(date '+%s') - $(stat -c '%Y' "${work_dir}/package-states/${sf}.done")) / 3600 / 24 ))" - elif tr ' ' '.' < \ - "${work_dir}/build-list" | \ - grep -qxF "${sf}"; then - printf ' (not built yet)' - fi - printf '\n' - done - printf '\n' - continue - fi - - printf 'Package "%s" can be %sd.\n' "${pkg}" "${action}" - - done - - ;; - - 'keep'|'stubbornly_keep') - - find '/var/lib/pacman/sync' -name '*.db' -execdir bsdtar -tf '{}' \; | \ - sed -n ' - s|-[^-]\+-[^-]\+/$|| - T - p - ' | \ - sort -u > \ - "${tmp_dir}/upstream-packages" - - while read -r pkg; do - - if builds_file=$( - find "${work_dir}/package-infos" -maxdepth 1 -printf '%f\n' | \ - grep -m1 '^'"$(str_to_regex "${pkg}")"'\(\.[^.]\+\)\{3\}\.builds$' - ); then - - builds_file="${builds_file%.*}" - prepo="${builds_file##*.}" - builds_file="${builds_file%.*}" - mod_rev="${builds_file##*.}" - builds_file="${builds_file%.*}" - rev="${builds_file##*.}" - - else - - found_PKGBUILD=false - mod_rev=$(cat "${work_dir}/archlinux32.revision") - for repo in ${repo_names}; do - eval 'repo_path="${repo_paths__'"${repo}"'}"' - rev=$(cat "${work_dir}/${repo}.revision") - if [ "${repo}" = 'archlinux32' ]; then - if git -C "${repo_path}" archive "${mod_rev}" | \ - grep -q '^[^/]\+/'"$(str_to_regex "${pkg}")"'/PKGBUILD$'; then - prepo=$( - git -C "${repo_path}" archive "${mod_rev}" | \ - grep '^[^/]\+/'"$(str_to_regex "${pkg}")"'/PKGBUILD$' | \ - cut -d/ -f1 - ) - found_PKGBUILD=true - break - fi - else - prepo=$( - git -C "${repo_path}" archive "${rev}" -- "${pkg}/repos" 2>/dev/null | \ - tar -t 2> /dev/null | \ - grep '^[^/]\+/repos/[^/]\+/PKGBUILD$' | \ - grep -v -- '-i686/PKGBUILD$' | \ - grep -v -- '[-/]\(staging\|testing\|unstable\)-[^/]\+/PKGBUILD$' | \ - sed ' - s|^[^/]\+/repos/\([^/]\+\)-[^/-]\+/PKGBUILD$|\1| - ' | \ - head -n1 - ) - if [ -n "${prepo}" ]; then - found_PKGBUILD=true - break - fi - fi - done - if ! ${found_PKGBUILD}; then + while read -r id is_broken trials is_blocked dependency slave pkgbase; do + pkgbase=$( + printf '%s' "${pkgbase}" | \ + base64 -d + ) + if [ "${id}" = 'NULL' ]; then + >&2 printf '"%s" is not on the build list.\n' \ + "${pkgbase}" continue fi - - generate_package_metadata "${pkg}" "${rev}" "${mod_rev}" "${prepo}" - - fi - - sed "s|^|${pkg} builds |" "${work_dir}/package-infos/${pkg}.${rev}.${mod_rev}.${prepo}.builds" - - done < \ - "${work_dir}/deletion-list" > \ - "${tmp_dir}/deleted.builds" - - sort -k3,3 "${tmp_dir}/deleted.builds" | \ - sponge "${tmp_dir}/deleted.builds" - - for pkg in "$@"; do - - if ! grep -qxF "${pkg}" "${work_dir}/deletion-list"; then - printf 'Package "%s" is not on the deletion list.\n' "${pkg}" - continue - fi - - if ! grep -qxF "${pkg}" "${tmp_dir}/upstream-packages"; then - printf 'Package "%s" is not available upstream.\n' "${pkg}" - if [ "${action}" = 'keep' ]; then + if [ "${slave}" != 'NULL' ]; then + # beware: A slave named "5BË" will look exactly like this! + printf '"%s" is locked by %s.\n' \ + "${pkgbase}" \ + "$( + printf '%s\n' "${slave}" | \ + tr ',' '\n' | \ + while read -r line; do + printf '%s\n' "${line}" | \ + base64 -d + printf ',' + done | \ + sed 's/,$//' + )" continue fi - fi - - if git -C "${repo_paths__archlinux32}" archive "$(cat "${work_dir}/archlinux32.revision")" -- blacklist | \ - tar -Ox 'blacklist' | \ - sed ' - s/\s*#.*$// - /^\s*$/d - ' | \ - grep -qxF "${pkg}"; then - printf 'Package "%s" is explicitely blacklisted.\n' "${pkg}" - continue - fi + if [ "${is_blocked}" != 'NULL' ]; then + # beware: A block-reason "5BË" will look exactly like this! + printf '"%s" is blocked: "%s".\n' \ + "${pkgbase}" \ + "$( + printf '%s' "${is_blocked}" | \ + base64 -d + )" + continue + fi + if [ "${dependency}" != 'NULL' ]; then + printf '"%s" has unmet dependencies:\n' \ + "${pkgbase}" + printf '%s\n' "${dependency}" | \ + tr ',' '\n' | \ + while read -r line; do + printf ' ' + printf '%s\n' "${line}" | \ + base64 -d + printf '\n' + done + continue + fi + if [ "${is_broken}" = '1' ]; then + printf '"%s" is broken (%sx built), but would be built.\n' \ + "${pkgbase}" \ + "${trials}" + continue + fi + printf '"%s" would be built.\n' \ + "${pkgbase}" + done - if [ "lib32-${pkg#lib32-}" = "${pkg}" ]; then - printf 'Package "%s" is a library from multilib.\n' "${pkg}" - continue - fi + ;; - build_depends=$( - find "${work_dir}/package-infos" -maxdepth 1 -name "${pkg}.*.build-depends" -exec cat {} \; - ) - if [ -z "${build_depends}" ]; then - printf 'Package "%s" was deleted in the git repositories.\n' "${pkg}" - continue - fi + 'stabilize'|'unstage') - build_depends=$( - echo "${build_depends}" | \ - sort -u - ) + printf 'Sry, "why-dont-you %s" is unavailable, until someone recodes it to look into the database.\n' "${action}" - errors=$( - { - # shellcheck disable=SC2086 - printf '%s\n' ${build_depends} - awk '{print $3}' "${tmp_dir}/deleted.builds" | \ - sort -u - } | \ - sort | \ - uniq -d | \ - join -1 1 -2 3 -o 2.1,2.2,2.3 - "${tmp_dir}/deleted.builds" - ) - if [ -n "${errors}" ]; then - printf 'Package "%s" has dependencies on the deletion list:\n' "${pkg}" - # shellcheck disable=SC2086,SC2183 - printf '%s %s %s\n' ${errors} - printf '\n' - continue - fi + ;; - printf 'It seems, package "%s" should not be deleted.\n' "${pkg}" + 'keep'|'stubbornly_keep') - done + printf 'Sry, "why-dont-you %s" is unavailable, until someone recodes it to look into the database.\n' "${action}" ;; |