#!/bin/sh # usage: why_dont_you $action $package1 $package2 ... # shellcheck disable=SC2119,SC2120 # investigate, why a certain operation is not done with certain packages # shellcheck source=../lib/load-configuration . "${0%/*}/../lib/load-configuration" # TODO: reintrocude "keep", "stubbornly_keep", "stabilize" and "unstage" # using information from the database. action="$1" shift tmp_dir=$(mktemp -d 'tmp.why-dont-you.XXXXXXXXXX' --tmpdir) trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT case "${action}" in 'build') # shellcheck disable=SC2016 { 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_binary_packages_in_repositories 'tb_bin' 'tb_bir' mysql_join_binary_packages_in_repositories_repositories 'tb_bir' '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_binary_packages_in_repositories 'dep_bin' 'dep_bir' mysql_join_binary_packages_in_repositories_repositories 'dep_bir' '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' } | \ mysql_run_query | \ tr '\t' ' ' | \ sort -k7,7 -k6,6 -k5,5 | \ sed ' / 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 ' | \ sed ' s/NULL,//g ' | \ 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 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 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 ;; 'stabilize'|'unstage') printf 'Sry, "why-dont-you %s" is unavailable, until someone recodes it to look into the database.\n' "${action}" ;; 'keep'|'stubbornly_keep') printf 'Sry, "why-dont-you %s" is unavailable, until someone recodes it to look into the database.\n' "${action}" ;; *) >&2 printf 'unknown action "%s"\n' "${action}" exit 1 esac