Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/bin/harvest-commit-times
blob: 38d84c47bbd1d9493f421cb030f8151b045e4254 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/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 '  -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 hw \
    --long help \
    --long wait \
    -n "$(basename "$0")" -- "$@" || \
  echo usage
)"

block_flag='-n'

while true; do
  case "$1" in
    -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}"
if ! verbose_flock ${block_flag} 9; then
  >&2 echo 'come back (shortly) later - Another harvest-commit-times is already running.'
  exit
fi

tmp_file=$(mktemp 'tmp.harvest-commit-times.XXXXXXXXXX' --tmpdir)
trap 'rm "${tmp_file}"' EXIT

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 '`git_repositories`.`name`'
    printf ' FROM `package_sources`'
    mysql_join_package_sources_upstream_repositories
    mysql_join_upstream_repositories_git_repositories
    printf ' WHERE `package_sources`.`commit_time`="0000-00-00 00:00:00"'
    printf ' AND `package_sources`.`uses_upstream`'
    printf ' LIMIT 10'
  } | \
    mysql_run_query 'unimportant' | \
    sponge | \
    while read -r id pkgbase git_revision mod_git_revision repository git_repository; do
      eval 'git_directory="${repo_paths__'"${git_repository}"'}"'
      find_pkgbuilds "${pkgbase}" "${repository}" "${git_repository}" "${git_revision}" "${mod_git_revision}"
      commit_time=$(
        # shellcheck disable=SC2154
        git -C "${git_directory}" log -n 1 --pretty=format:%ct "${git_revision}" -- "${PKGBUILD}"
      )
      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}"
        exit 2
      fi
    done > \
    "${tmp_file}"

  if [ -s "${tmp_file}" ]; then
    # shellcheck disable=SC2016
    {
      printf 'CREATE TEMPORARY TABLE `cts` (`id` BIGINT, `ct` BIGINT);\n'
      printf 'LOAD DATA LOCAL INFILE "%s" INTO TABLE `cts`(`id`,`ct`);\n' \
        "${tmp_file}"
      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'
    } | \
      mysql_run_query 'unimportant'
  else
    break
  fi

done