#!/bin/sh # shellcheck disable=SC2119,SC2120 # shellcheck source=../lib/load-configuration . "${0%/*}/../lib/load-configuration" # shellcheck disable=SC2016 usage() { >&2 echo '' >&2 echo 'harvest-commit-times: harvest the commit times of package' >&2 echo ' sources from git and put them into the database' >&2 echo '' >&2 echo 'possible options:' >&2 echo ' -f|--force: Do not abort on error.' >&2 echo ' -h|--help: Show this help and exit.' >&2 echo ' -w|--wait: If necessary, wait for lock blocking.' [ -z "$1" ] && exit 1 || exit "$1" } eval set -- "$( getopt -o fhw \ --long force \ --long help \ --long wait \ -n "$(basename "$0")" -- "$@" || \ echo usage )" block_flag='-n' force=false; while true; do case "$1" in -f|--force) force=true ;; -h|--help) usage 0 ;; -w|--wait) block_flag='' ;; --) shift break ;; *) >&2 echo 'Whoops, forgot to implement option "'"$1"'" internally.' exit 42 ;; esac shift done if [ $# -ne 0 ]; then >&2 echo 'Too many arguments.' usage fi exec 9> "${harvest_commit_times_lock_file}" # shellcheck disable=SC2086 if ! verbose_flock ${block_flag} 9; then >&2 echo 'come back (shortly) later - Another harvest-commit-times is already running.' exit fi if ! ${i_am_the_master}; then for repo_name in ${repo_names}; do eval repo_path='"${repo_paths__'"${repo_name}"'}"' if [ -d "${repo_path}/.git" ]; then git -C "${repo_path}" remote update else git -C "${repo_path}" fetch origin master:master fi || \ true done fi tmp_file=$(mktemp 'tmp.harvest-commit-times.XXXXXXXXXX' --tmpdir) trap 'rm "${tmp_file}"' EXIT if ! ${i_am_the_master}; then tmp_remote_file=$( ssh -o PasswordAuthentication=No buildmaster "mktemp 'tmp.harvest-commit-times.remotely.XXXXXXXXXX' --tmpdir" ) trap 'rm "${tmp_file}"; ssh -o PasswordAuthentication=No buildmaster rm "${tmp_remote_file}"' EXIT fi while true; do # shellcheck disable=SC2016 { printf 'SELECT' printf ' `package_sources`.`id`,' printf '`package_sources`.`pkgbase`,' printf '`package_sources`.`git_revision`,' printf '`package_sources`.`mod_git_revision`,' printf '`upstream_repositories`.`name`,' printf 'IF(`build_assignments`.`architecture`=%s,"any","x86_64")' "${architecture_ids__any}" printf ' FROM `package_sources`' mysql_join_package_sources_upstream_repositories mysql_join_package_sources_build_assignments printf ' WHERE `package_sources`.`commit_time`="0000-00-00 00:00:00"' printf ' AND `package_sources`.`uses_upstream`' printf ' ORDER BY RAND()' printf ' LIMIT 10' } \ | mysql_run_query 'unimportant' \ | sponge \ | while read -r id pkgbase git_revision mod_git_revision repository architecture; do commit_time=$( # shellcheck disable=SC2154 git -C "${repo_paths__state}" log -n 1 --pretty=format:%ct HEAD -- "${repository}-${architecture}/${pkgbase}" ) if [ -n "${commit_time}" ]; then printf '%s\t%s\n' \ "${id}" \ "${commit_time}" else >&2 printf 'Package source %s is not available in git:\n' \ "${id}" >&2 printf '%s ' \ "${pkgbase}" "${git_revision}" "${mod_git_revision}" "${repository}" "${architecture}" >&2 printf '\n' if ! ${force}; then exit 2 fi fi done > \ "${tmp_file}" >&2 printf '.' if [ -s "${tmp_file}" ]; then if ! ${i_am_the_master}; then ssh -o PasswordAuthentication=No buildmaster 'cat > "'"${tmp_remote_file}"'"' < \ "${tmp_file}" fi # shellcheck disable=SC2016 { printf 'CREATE TEMPORARY TABLE `cts` (`id` BIGINT, `ct` BIGINT);\n' if ${i_am_the_master}; then printf 'LOAD DATA LOCAL INFILE "%s" INTO TABLE `cts`(`id`,`ct`);\n' \ "${tmp_file}" else printf 'LOAD DATA LOCAL INFILE "%s" INTO TABLE `cts`(`id`,`ct`);\n' \ "${tmp_remote_file}" fi printf 'UPDATE `cts`' printf ' JOIN `package_sources`' printf ' ON `package_sources`.`id`=`cts`.`id`' printf ' AND `package_sources`.`commit_time`="0000-00-00 00:00:00"' printf ' SET `package_sources`.`commit_time`=from_unixtime(`cts`.`ct`);\n' } | \ if ${i_am_the_master}; then mysql_run_query 'unimportant' else ssh -o PasswordAuthentication=No buildmaster 'mysql buildmaster -N --raw --batch' fi else >&2 printf '\n' break fi done