summaryrefslogtreecommitdiff
path: root/bin/why-dont-you
diff options
context:
space:
mode:
Diffstat (limited to 'bin/why-dont-you')
-rwxr-xr-xbin/why-dont-you465
1 files changed, 145 insertions, 320 deletions
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}"
;;