comparison sbin/check-ports @ 128:3dcae0e91769

Move all admin scripts into the "sbin" folder
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 17 Oct 2019 09:09:13 +0200
parents bin/check-ports@cf9dde7a3a0d
children 54de2955bfa9
comparison
equal deleted inserted replaced
127:37737f225887 128:3dcae0e91769
1 #!/bin/sh
2 # -*- indent-tabs-mode: nil; -*-
3 : 'Check the version status of installed ports and compare them to
4 repository versions.
5
6 :Author: Franz Glasner
7 :Copyright: (c) 2017-2019 Franz Glasner.
8 All rights reserved.
9 :License: BSD 3-Clause "New" or "Revised" License.
10 See LICENSE for details.
11 If you cannot find LICENSE see
12 <https://opensource.org/licenses/BSD-3-Clause>
13 :ID: @(#)@@PKGORIGIN@@ $HGid$
14
15 '
16
17 VERSION="@@VERSION@@"
18
19 #
20 # Configuration directory
21 #
22 : ${CONFIGDIR:=@@ETCDIR@@}
23
24 test -r "${CONFIGDIR}/tools.conf" && . "${CONFIGDIR}/tools.conf"
25
26 #
27 # Mapping configuration: installed package name -> original package name
28 # Note: This is independent of any repo
29 #
30 : ${PACKAGE_MAPPING:=${CONFIGDIR}/package-mapping.conf}
31
32 #
33 # Local repository with non-public packages and/or ports with changed
34 # OPTIONS (i.e. not using the defaults) or forks of official packages with
35 # other package names
36 #
37 : ${LOCAL_REPO:=LocalRepo}
38
39 #
40 # Local repository with ports with default OPTIONS (i.e. unchanged)
41 # but newer than the packages in the "FreeBSD" repository.
42 # Some sort of a fast-track repository.
43 #
44 : ${LOCALBSDPORTS_REPO:=LocalBSDPorts}
45
46 #
47 # The official FreeBSD binary repository
48 #
49 : ${FREEBSD_REPO:=FreeBSD}
50
51 #
52 # Directly installed from ports
53 #
54 : ${PORTS_DIRECT_INSTALLED_REPO:=unknown-repository}
55
56 #
57 # For the workaround of the bug in pkg rquery -I
58 #
59 : ${PORTSDIR:=/usr/ports}
60 : ${INDEXDIR:=${PORTSDIR}}
61 : ${INDEXFILE:=@@INDEXFILE@@}
62
63
64 get_remote_repo_versions() {
65 : 'Determine the remote repository versions of all packages in
66 repository `_repo`.
67
68 Args:
69 _repo: the name of the repote repository
70
71 Returns:
72 status 0 on success, 1 on errors
73
74 Output (Globals):
75 remote_versions_${_repo}: the versions of all packages in `_repo` and
76 their extended version status with respect to
77 locally installed packages
78
79 '
80 local _repo _data _rv
81
82 _repo=$1
83
84 _data=$(pkg version -U -R -r ${_repo} -v)
85 _rv=$?
86 eval remote_versions_${_repo}=\"\${_data}\"
87 return ${_rv}
88 }
89
90 get_remote_repo_data() {
91 : 'Get the extended package version information from the remote repository
92 `_repo` for package `_name`.
93
94 Args:
95 _repo: the name of the remote repository
96 _name: the package name
97
98 Input (Globals):
99 remote_versions_${_repo}: the extended version info for *all* packages
100 in repo `_repo`.
101
102 Returns:
103 status 0 on success, 1 on errors or if the package is not found
104 in the remote repository
105
106 Output (Globals):
107 remote_label_${_repo}:
108 remote_descr_${_repo}:
109
110 '
111 local _repo _name _rversions _rfqp _rl _rdescr
112
113 _repo=$1
114 _name=$2
115
116 eval _rversions=\"\${remote_versions_${_repo}}\"
117 while read _rfqp _rl _rdescr ; do
118 if [ ${_rfqp%-*} = ${_name} ] ; then
119 eval remote_label_${_repo}=\"\${_rl}\"
120 eval remote_descr_${_repo}=\"\${_rdescr}\"
121 return 0
122 fi
123 done <<EOF884657
124 ${_rversions}
125 EOF884657
126 eval remote_label_${_repo}=""
127 eval remote_descr_${_repo}=""
128 return 1
129 }
130
131 get_local_index_versions() {
132 : 'Determine the extendes versions of all packages in the local index
133 (ports).
134
135 Returns:
136 status 0 on success or 1 on errors
137
138 Output (Globals):
139 local_index_versions:
140
141 '
142 local_index_versions=$(pkg version -I -v)
143 }
144
145 get_repo_for_installed_package() {
146 : 'Determine for a package `_name` from which repository is has been
147 installed.
148
149 Args:
150 _name: the name of the package to search for
151
152 Input (Globals):
153 installed_data the output of ``pkg query "%n %v %R"`` of all
154 installed packages
155
156 Returns:
157 0 on success, 1 on errors or if the package is not installed
158
159 Output (Globals):
160 repository: the repository from which the installed packages `_name`
161 has been installed
162
163 '
164 local _name _n _v _r
165
166 _name=$1
167
168 while read _n _v _r ; do
169 if [ ${_name} = ${_n} ] ; then
170 repository=${_r}
171 return 0
172 fi
173 done <<EOF223777
174 ${installed_data}
175 EOF223777
176 return 1
177 }
178
179 get_immediate_index_version() {
180 : 'Determine for package `_package` the version of the package in the
181 local ports index.
182
183 Args:
184 _package: the package name to search for
185
186 Input (Globals):
187 INDEXDIR: the directory where to search the index file
188 INDEXFILE: the name of the index file
189
190 Returns:
191 0 on success, 1 on errors or if the package is not in the index
192
193 Output (Globals):
194 immediate_index_version: the version number of `_package` in the
195 index
196
197 '
198 local _package _line _fqpn _n _lines
199
200 _package=$1
201
202 # _val=$(pkg rquery -I "${_package}" | cut -f 1 -d '|')
203 # _rv=$?
204 # immediate_index_version=${_val##*-}
205 # return ${_rv}
206
207 if [ -r "${INDEXDIR}/${INDEXFILE}" ] ; then
208 #
209 # Note: Direct piping does not set immediate_index_version at return correctly
210 # "_line" is set correctly and parsing works, but the return 0 seems to kill
211 # some of the previous effects.
212 #
213 # "grep" does a fast pre-selection, reading, parsing and comparing is done for
214 # exact matching.
215 #
216 _lines=$(egrep '^'"${_package}" "${INDEXDIR}/${INDEXFILE}")
217 while read _line ; do
218 _fqpn="${_line%%|*}"
219 _n=${_fqpn%-*}
220 if [ "${_package}" = "${_n}" ] ; then
221 immediate_index_version="${_fqpn##*-}"
222 return 0
223 fi
224 done <<EOF1334TGH1
225 ${_lines}
226 EOF1334TGH1
227 fi
228
229 immediate_index_version=""
230 return 1
231 }
232
233 get_immediate_remote_repo_version() {
234 : 'Ask a remote repository for the version of a package.
235
236 Args:
237 _repo: the repository name
238 _name: the name of the package
239
240 Returns:
241 0 on success and other status codes otherwise
242
243 Output (Globals):
244 immediate_remote_repo_version_${_repo}: the version of package `_name`
245 in repo `_repo`
246
247 '
248 local _repo _name _version _rv
249
250 _repo=$1
251 _name=$2
252
253 _version=$(pkg rquery -U -r "${_repo}" '%v' "${_name}")
254 _rv=$?
255 eval immediate_remote_repo_version_${_repo}=\"\${_version}\"
256 return ${_rv}
257 }
258
259 assert_local_version() {
260 : 'Check whether an installed package `_name` has given
261 version `_version`.
262
263 Args:
264 _name: the package name
265 _version: the version to check for
266
267 Input (Globals):
268 installed_data: the output of ``pkg query "%n %v %R"`` of all
269 installed packages
270
271 Returns:
272 - 0 if the installed version of package `_name` is equal to `_version`
273 - 1 if the installed version of package `_name` differs from `_version`
274 - 2 on other errors
275
276 '
277 local _name _version _n _v _r
278
279 _name=$1
280 _version=$2
281
282 while read _n _v _r ; do
283 if [ ${_name} = ${_n} ] ; then
284 if [ ${_version} != ${_v} ] ; then
285 return 1
286 else
287 return 0
288 fi
289 fi
290 done <<EOF223
291 ${installed_data}
292 EOF223
293 return 2
294 }
295
296 get_mapping() {
297 : 'Determine whether a package `_package` is essentially the same as
298 another package.
299
300 Args:
301 _package: the new name of the package
302
303 Returns:
304 0 when a package mapping has been found, 1 otherwise
305
306 Output (Globals):
307 mapped_package_name: the name of the package on which `_package` is
308 based on
309
310 This command reads from the mapping database in in file
311 `/usr/local/etc/local-bsdtools/package-mapping.conf`.
312 Example::
313
314 #
315 # _package mapped_package_name
316 #
317 fmg-nextcloud-php71 nextcloud-php71
318 fmg-nextcloud-twofactor_totp-php71 nextcloud-twofactor_totp-php71
319
320 '
321 local _package _n _mapped
322
323 _package=$1
324
325 if [ -r "${PACKAGE_MAPPING}" ] ; then
326 while read _n _mapped ; do
327 if [ "${_n}" = "${_package}" ] ; then
328 mapped_package_name="${_mapped}"
329 return 0
330 fi
331 done < ${PACKAGE_MAPPING}
332 fi
333 mapped_package_name=""
334 return 1
335 }
336
337 print_title() {
338 : 'Print the output title line for a package
339
340 Args:
341 _package: the package name
342 _repo: the repository name
343
344 Input (Globals).
345 title_printed: a global that determines if the title really needs
346 to be printed.
347
348 If it is an empty string the the title is
349 really printed and the variable is set to
350 "yes".
351
352 Output (Globals):
353 title_printed: set to "yes" if the title has been printed
354
355 '
356 local _package _repo
357
358 _package=$1
359 _repo=$2
360 if [ -z "${title_printed}" ] ; then
361 echo "${_package} (${_repo})"
362 title_printed=yes
363 fi
364 }
365
366
367 alldata_flag=""
368 alldata_flag_LocalBSDPorts=""
369 alldata_flag_LocalRepo=""
370 short_flag=""
371 verbose_flag=""
372
373 while getopts "VAasv" _opt ; do
374 case ${_opt} in
375 V)
376 echo "check-ports v${VERSION} (rv:@@HGREVISION@@)"
377 exit 0
378 ;;
379 A)
380 # print for every package the status of all repositories
381 alldata_flag=1
382 alldata_flag_LocalBSDPorts=1
383 alldata_flag_LocalRepo=1
384 ;;
385 a)
386 # print the data of all repos that have the package
387 alldata_flag=1
388 ;;
389 s)
390 # "short" output: if installed from FreeBSD repo: don't
391 # report if only the index is newer
392 short_flag=1
393 ;;
394 v)
395 # print all titles and repo of every installed always
396 verbose_flag=1
397 ;;
398 \?)
399 exit 2
400 ;;
401 *)
402 echo "option handling failed" >&2
403 exit 2
404 ;;
405 esac
406 done
407
408 if [ -n "${short_flag}" -a -n "${alldata_flag}" ]; then
409 echo "the -s option cannot be combined with -A or -a" >&2
410 exit 2
411 fi
412
413 installed_packages=$(pkg query '%n')
414 installed_data="$(pkg query '%n %v %R' $installed_packages)"
415
416 get_remote_repo_versions ${LOCAL_REPO}
417 get_remote_repo_versions ${LOCALBSDPORTS_REPO}
418 get_remote_repo_versions ${FREEBSD_REPO}
419 get_local_index_versions
420
421 while read lfqp llabel ldescr ; do
422 _installed_name=${lfqp%-*}
423 _installed_version=${lfqp##*-}
424 title_printed=""
425 get_repo_for_installed_package ${_installed_name}
426 get_mapping ${_installed_name}
427 if [ -n "${verbose_flag}" ] ; then
428 print_title "${lfqp}" "${repository}"
429 fi
430 if ! assert_local_version ${_installed_name} ${_installed_version} ; then
431 echo "Assertion failed: $lfqp ${_installed_name} ${_installed_version} ${llabel}" >&2
432 exit 1
433 fi
434 get_remote_repo_data ${LOCAL_REPO} ${_installed_name}
435 get_remote_repo_data ${LOCALBSDPORTS_REPO} ${_installed_name}
436 get_remote_repo_data ${FREEBSD_REPO} ${_installed_name}
437 _print_detail=""
438 if [ -n "${mapped_package_name}" ] ; then
439 _print_detail=1
440 fi
441 if [ \( -n "${alldata_flag}" \) ]; then
442 _print_detail=1
443 else
444 if [ -n "${short_flag}" ]; then
445 #
446 # NOTE: -s and -A/-a are incompatible: so "alldata_XXX" needs not
447 # to be checked!
448 #
449 case "${repository}" in
450 "${FREEBSD_REPO}")
451 if [ \( "${llabel}" != '<' -a "${llabel}" != '=' \) -o "${remote_label_FreeBSD}" != '=' -o "${remote_label_LocalRepo}" != '?' -o "${remote_label_LocalBSDPorts}" != '?' ]; then
452 _print_detail=1
453 fi
454 ;;
455 "${LOCAL_REPO}")
456 _print_detail=1
457 ;;
458 "${LOCALBSDPORTS_REPO}")
459 if [ "${llabel}" != '=' -o "${remote_label_FreeBSD}" != '>' -o "${remote_label_LocalRepo}" != '?' -o "${remote_label_LocalBSDPorts}" = '?' -o "${remote_label_LocalBSDPorts}" = '<' ]; then
460 _print_detail=1
461 fi
462 ;;
463 "${PORTS_DIRECT_INSTALLED_REPO}")
464 _print_detail=1
465 ;;
466 *)
467 echo "ERROR: unhandled repository: ${repository}" >&2
468 exit 1
469 ;;
470 esac
471 else
472 if [ \( \( "${llabel}" != '?' -a "${llabel}" != '=' \) -o \( "${remote_label_FreeBSD}" != '?' -a "${remote_label_FreeBSD}" != '=' \) -o \( "${remote_label_LocalBSDPorts}" != '?' -a "${remote_label_LocalBSDPorts}" != '=' \) -o \( "${remote_label_LocalRepo}" != '?' -a "${remote_label_LocalRepo}" != '=' \) \) -o \( "${repository}" = "${PORTS_DIRECT_INSTALLED_REPO}" \) ]; then
473 _print_detail=1
474 fi
475 fi
476 fi
477 if [ -n "${_print_detail}" ]; then
478 print_title "${lfqp}" "${repository}"
479 echo " INDEX : ${llabel} ${ldescr}"
480 echo " FreeBSD : ${remote_label_FreeBSD} ${remote_descr_FreeBSD}"
481 if [ \( -n "${alldata_flag_LocalBSDPorts}" \) -o \( "${remote_label_LocalBSDPorts}" != '?' \) ] ; then
482 echo " LocalBSDPorts: ${remote_label_LocalBSDPorts} ${remote_descr_LocalBSDPorts}"
483 fi
484 if [ \( -n "${alldata_flag_LocalRepo}" \) -o \( "${remote_label_LocalRepo}" != '?' \) ] ; then
485 echo " LocalRepo : ${remote_label_LocalRepo} ${remote_descr_LocalRepo}"
486 fi
487 if [ -n "${mapped_package_name}" ] ; then
488 echo " ---> ${mapped_package_name}"
489 get_immediate_index_version "${mapped_package_name}"
490 get_immediate_remote_repo_version ${LOCAL_REPO} ${mapped_package_name}
491 get_immediate_remote_repo_version ${LOCALBSDPORTS_REPO} ${mapped_package_name}
492 get_immediate_remote_repo_version ${FREEBSD_REPO} ${mapped_package_name}
493 echo " INDEX : ${immediate_index_version}"
494 echo " FreeBSD : ${immediate_remote_repo_version_FreeBSD}"
495 echo " LocalBSDPorts: ${immediate_remote_repo_version_LocalBSDPorts}"
496 echo " LocalRepo : ${immediate_remote_repo_version_LocalRepo}"
497 fi
498 fi
499 done <<EOF856661111299999
500 ${local_index_versions}
501 EOF856661111299999