updates from MirBSD CVS
[shellsnippets/shellsnippets.git] / mksh / debian-dev / quinn-ls.sh
1 #!/bin/mksh
2 rcsid='$MirOS: contrib/hosted/tg/deb/quinn-ls.sh,v 1.12 2013/01/14 22:16:42 tg Exp $'
3 #-
4 # Copyright © 2011, 2012, 2013
5 #       Thorsten Glaser <tg@debian.org>
6 #
7 # Provided that these terms and disclaimer and all copyright notices
8 # are retained or reproduced in an accompanying document, permission
9 # is granted to deal in this work without restriction, including un‐
10 # limited rights to use, publicly perform, distribute, sell, modify,
11 # merge, give away, or sublicence.
12 #
13 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
14 # the utmost extent permitted by applicable law, neither express nor
15 # implied; without malicious intent or gross negligence. In no event
16 # may a licensor, author or contributor be held liable for indirect,
17 # direct, other damage, loss, or other issues arising in any way out
18 # of dealing in the work, even if advised of the possibility of such
19 # damage or existence of a defect, except proven that it results out
20 # of said person’s immediate fault when using the work as intended.
21
22 gather=cwd fromfile=
23 mydir=$(realpath "$(dirname "$0")")
24 PATH="$mydir:$mydir/..:$PATH" . assockit.ksh
25
26 while getopts "L:l" ch; do
27         case $ch {
28         (L)     gather=installed fromfile=$OPTARG ;;
29         (l)     gather=installed fromfile= ;;
30         (*)     exit 1 ;;
31         }
32 done
33 shift $((OPTIND - 1))
34
35 # Debian Policy 3.9.2.0, §5.6.1
36 function isdebpkg {
37         [[ $1 = [a-z0-9]+([a-z0-9+.-]) ]]
38 }
39
40 # Debian Policy 3.9.2.0, §5.6.12
41 function isdebver {
42         local epochglob uvglob dvglob
43
44         # strict (must start with a digit)
45         #uvglob='[0-9]*'
46         # loose (should, but it's ok if not)
47         uvglob='+'
48
49         uvglob=$uvglob'([A-Za-z0-9.+~'
50
51         # colon is allowed if we have an epoch
52         if [[ $1 = +([0-9])':'* ]]; then
53                 epochglob='+([0-9])'\'':'\'
54                 uvglob=$uvglob':'
55         fi
56
57         # hyphen is allowed if we have a debian revision
58         if [[ $1 = *'-'+([A-Za-z0-9+.~]) ]]; then
59                 dvglob=\'-\''+([A-Za-z0-9+.~])'
60                 uvglob=$uvglob'-'
61         fi
62
63         uvglob=$uvglob'])'
64
65         eval [[ \$1 = $epochglob$uvglob$dvglob ]]
66 }
67
68 # packages to never ask rmadison for
69 asso_setv 1 nomadison arngc
70 asso_setv 1 nomadison atari-bootstrap
71 asso_setv 1 nomadison atari-fdisk
72 asso_setv 1 nomadison ca-bundle
73 asso_setv 1 nomadison defoma
74 asso_setv 1 nomadison evolvis-anonsvnsh
75 asso_setv 1 nomadison evolvis-meta
76 asso_setv 1 nomadison m68k-gcc-defaults
77 asso_setv 1 nomadison m68k-vme-tftplilo
78 asso_setv 1 nomadison m68kboot
79 asso_setv 1 nomadison mircpio
80 asso_setv 1 nomadison mirhost
81 asso_setv 1 nomadison mirmake
82 asso_setv 1 nomadison mirsirc
83 asso_setv 1 nomadison pbuilder-satisfydepends-dummy
84 asso_setv 1 nomadison sbuild-build-depends-core-dummy
85 asso_setv 1 nomadison ssfe
86 asso_setv 1 nomadison vmelilo
87 asso_setv 1 nomadison vmelilo-installer
88 asso_setv 1 nomadison wtf
89 asso_setv 1 nomadison wtf-debian-keyring
90 asso_setv 1 nomadison xfree86
91
92 i=0
93 function do_gather {
94         if ! isdebpkg "$Source"; then
95                 print -ru2 "skipping invalid Source '$Source', file $name"
96                 return 2
97         fi
98         if ! isdebver "$Version"; then
99                 print -ru2 "skipping invalid Version '$Version', file $name"
100                 return 2
101         fi
102         lver=$(asso_getv pkgs "$Source" lver)
103         if [[ -z $lver ]]; then
104                 print -ru2 "local $Source $Version"
105                 asso_sets "$Version" pkgs "$Source" lver
106                 return 0
107         fi
108         lver=$(asso_getv pkgs "$Source" lver)
109         for x in $lver; do
110                 # skip dups (from .changes = .dsc probably) silently
111                 [[ $x = "$Version" ]] && return 1
112         done
113         # put the newest local version leftmost
114         set -A xa -- $lver
115         if dpkg --compare-versions "$Version" gt "${xa[0]}"; then
116                 print -ru2 "newer $Source $Version"
117                 lver="$Version $lver"
118         else
119                 print -ru2 "older $Source $Version"
120                 lver="$lver $Version"
121         fi
122         asso_sets "$lver" pkgs "$Source" lver
123         return 0
124 }
125
126 if [[ $gather = cwd ]]; then
127         find . -name \*.changes -o -name \*.dsc |&
128         while IFS= read -pr name; do
129                 Source=
130                 Version=
131                 eval $(sed -n \
132                     -e '/^\(Source\): \([^ ]*\)\( .*\)*$/s//\1='\''\2'\''/p' \
133                     -e '/^\(Version\): \([^ ]*\)$/s//\1='\''\2'\''/p' \
134                     "$name")
135                 do_gather
136         done
137 elif [[ $gather = installed ]]; then
138         if [[ -n $fromfile ]]; then
139                 # e.g. from running the following command:
140                 # chroot --userspec=65534:65534 /var/cache/pbuilder/build/cow.27937 \
141                 #     /usr/bin/dpkg-query -Wf '${Package} ${Version} ${Source} ${Package}\n' \
142                 #     >thefile
143                 if [[ ! -s $fromfile ]]; then
144                         print -u2 "Cannot read $fromfile."
145                         exit 1
146                 fi
147                 cat "$fromfile"
148         else
149                 dpkg-query -Wf '${Package} ${Version} ${Source} ${Package}\n'
150         fi |&
151         while read -p name Version Source x rest; do
152                 if [[ $Source = *'('*')' ]]; then
153                         # this is not customary…
154                         rest=${Source##*'('}
155                         rest=${rest%')'}
156                         isdebver "$rest" && Version=$rest
157                 elif [[ $x = '('*')' ]]; then
158                         # Source:Version ≠ Version
159                         x=${x#'('}
160                         x=${x%')'}
161                         isdebver "$x" && Version=$x
162                 fi
163                 do_gather
164         done
165 else
166         exit 1
167 fi
168
169 print -u2 '\nrunning rmadison…'
170 asso_loadk pkgs
171 i=${#asso_y[*]}
172 while (( i-- )); do
173         asso_isset nomadison "${asso_y[i]}" && unset asso_y[i]
174 done
175 rmadison -s sid "${asso_y[@]}" |&
176 while read -pr pkg pipe vsn pipe sid pipe arches; do
177         #print -u2 "D: pkg<$pkg> vsn<$vsn> sid<$sid> arches<$arches>"
178         arches=${arches//,/ }
179         [[ " $arches " = *' source '* ]] || continue
180         if ! asso_isset pkgs "$pkg" lver; then
181                 print -ru2 "bogus $pkg $vsn ignored"
182                 continue
183         fi
184         x=$(asso_getv pkgs "$pkg" uver)
185         if [[ -z $x ]]; then
186                 print -ru2 "found $pkg $vsn"
187                 asso_sets "$vsn" pkgs "$pkg" uver
188         elif [[ $x = "$vsn" ]]; then
189                 print -ru2 "equal $pkg $vsn ignored"
190         elif dpkg --compare-versions "$x" lt "$vsn"; then
191                 print -ru2 "newer $pkg $vsn (dropping $x)"
192                 asso_sets "$vsn" pkgs "$pkg" uver
193         else
194                 print -ru2 "older $pkg $vsn ignored"
195         fi
196 done
197
198 print -u2 '\nreading override files [bad bld ign]…'
199 # bad: mark RIGHT versions lower or equal as "bad"
200 # bld: mark RIGHT version equal as "building"
201 # ign: mark LEFT version equal as "ignored" and ignore not-in-upstream
202 for type in bad bld ign; do
203         [[ -s $mydir/quinn-ls.$type ]] || continue
204         while read pkg vsn; do
205                 [[ $pkg = '#'* ]] && continue
206                 if [[ $pkg = *_* && -z $vsn ]]; then
207                         # buildd syntax
208                         vsn=${pkg#*_}
209                         pkg=${pkg%%_*}
210                 fi
211                 if ! isdebpkg "$pkg"; then
212                         print -ru2 "skipping invalid package '$pkg'," \
213                             override $type
214                         continue
215                 fi
216                 if ! isdebver "$vsn"; then
217                         print -ru2 "skipping invalid version '$vsn'," \
218                              override $type
219                         continue
220                 fi
221                 print -ru2 "o:$type $pkg $vsn"
222                 asso_sets "$vsn" over "$type" "$pkg"
223         done <$mydir/quinn-ls.$type
224 done
225
226 c0=$'\033[0m'
227 c1=$'\033[1;31m'
228 c2=$'\033[1;32m'
229 c3=$'\033[1;33m'
230 c4=$'\033[1;34m'
231 c5=$'\033[1;35m'
232 c6=$'\033[1;36m'
233 print -ru2 "$c0"
234 print -ru2
235
236 asso_loadk pkgs
237 for pkg in "${asso_y[@]}"; do
238         lvs=$(asso_getv pkgs "$pkg" lver)
239         lv=${lvs%% *}
240         uv=$(asso_getv pkgs "$pkg" uver)
241
242         if [[ -z $uv ]]; then
243                 uv=0~RM
244                 lc=$c1
245                 uc=$c1
246         elif [[ $lv = "$uv"?('+b'+([0-9])) ]]; then
247                 lc=$c2
248                 uc=$c2
249         elif dpkg --compare-versions "$lv" lt "$uv"; then
250                 lc=$c1
251                 uc=$c3
252         else
253                 lc=$c3
254                 uc=$c4
255         fi
256
257         over_bad=$(asso_getv over bad "$pkg")
258         over_bld=$(asso_getv over bld "$pkg")
259         over_ign=$(asso_getv over ign "$pkg")
260         if [[ -n $over_ign && $lv = "$over_ign" ]]; then
261                 lc=$c6
262                 [[ $uv = '0~RM' ]] && uc=$c6
263         fi
264         [[ -n $over_bad ]] && dpkg --compare-versions "$uv" le "$over_bad" && \
265             uc=$c5
266         [[ -n $over_bld && $uv = "$over_bld" ]] && uc=$c6
267
268         print -r -- "$c0$pkg $lc$lv$c0 $uc$uv$c0"
269         [[ $lvs = $lv ]] && continue
270         for lv in ${lvs#* }; do
271                 [[ $lv = "$uv"?('+b'+([0-9])) ]] && continue
272                 lc=$c4
273                 [[ -n $over_ign && $lv = "$over_ign" ]] && lc=$c6
274                 print -r -- "$c0$pkg $lc$lv$c0 -"
275         done
276 done | sort | column -t