summaryrefslogtreecommitdiff
path: root/bin/find-obsolete-packages
blob: 1a35ec18fdcf7432889d4cd219a4d7789d3d203b (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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/bin/sh

# shellcheck disable=SC2119,SC2120

# shellcheck source=../lib/load-configuration
. "${0%/*}/../lib/load-configuration"

usage() {
  >&2 echo ''
  >&2 echo 'find-obsolete-packages: find packages which are no longer available upstream.'
  >&2 echo ''
  >&2 echo 'possible options:'
  >&2 echo '  -h|--help:'
  >&2 echo '    Show this help and exit.'
  >&2 echo '  -m|--mirror https://mirror.example.com/archlinux'
  >&2 echo '    Mirror url to take upstream'"'"'s packages from.'
  >&2 echo '  -n|--no-action:'
  >&2 echo '    Do not mark packages as to_be_deleted.'
  >&2 echo '  -w|--wait:'
  >&2 echo '    Wait for lock if necessary.'
  [ -z "$1" ] && exit 1 || exit "$1"
}

eval set -- "$(
  getopt -o hm:nw \
    --long help \
    --long mirror: \
    --long no-action \
    --long wait \
    -n "$(basename "$0")" -- "$@" || \
  echo usage
)"

mirror=''
no_action=false
wait_for_lock='-n'

while true
do
  case "$1" in
    -h|--help)
      usage 0
    ;;
    -m|--mirror)
      if [ -n "${mirror}" ]; then
        >&2 echo 'Already have one -m flag.'
        usage
      fi
      shift
      mirror="$1"
    ;;
    -n|--no-action)
      no_action=true
    ;;
    -w|--wait)
      wait_for_lock=''
    ;;
    --)
      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

if [ -z "${mirror}" ]; then
  >&2 echo 'Flag -m missing'
  usage
fi

if ! ${no_action}; then
  exec 9> "${sanity_check_lock_file}"
  if ! verbose_flock -s ${wait_for_lock} 9; then
    >&2 echo 'Cannot get sanity-check lock.'
    exit 1
  fi

  exec 8> "${build_list_lock_file}"
  if ! verbose_flock ${wait_for_lock} 8; then
    >&2 echo 'Cannot get build-list lock.'
    exit 1
  fi
fi

{
  for repo in core extra community multilib; do
    curl -Ss "${mirror}/${repo}/os/x86_64/${repo}.db.tar.gz" | \
      tar -tz
  done | \
    sed -n '
      s,\(-[^-]*\)\{2\}/desc$,,
      T
      p
      p
    '
  printf '%s\n' \
    'archlinux32-keyring' \
    'archlinux32-keyring-transition' | \
    sed 'p'
  # shellcheck disable=SC2016
  {
    printf 'SELECT DISTINCT `binary_packages`.`pkgname`'
    printf ' FROM `binary_packages`'
    mysql_join_binary_packages_binary_packages_in_repositories
    mysql_join_binary_packages_in_repositories_repositories
    printf ' WHERE `repositories`.`is_on_master_mirror`'
    printf ' AND NOT `binary_packages_in_repositories`.`is_to_be_deleted`'
  } | \
    mysql_run_query
} | \
  sort | \
  uniq -u | \
  if ${no_action}; then
    cat
  else
    # shellcheck disable=SC2016
    base64_encode_each | \
      sed '
        s/^/from_base64("/
        s/$/"),/
        1 s/^/UPDATE `binary_packages_in_repositories` '"$(
          mysql_join_binary_packages_in_repositories_binary_packages
        )"' SET `binary_packages_in_repositories`.`is_to_be_deleted`=1 WHERE `binary_packages`.`pkgname` IN (/
        $ s/,$/);/
      ' | \
      mysql_run_query
  fi