Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbin/check-ports Thu Oct 17 09:09:13 2019 +0200 @@ -0,0 +1,501 @@ +#!/bin/sh +# -*- indent-tabs-mode: nil; -*- +: 'Check the version status of installed ports and compare them to +repository versions. + +:Author: Franz Glasner +:Copyright: (c) 2017-2019 Franz Glasner. + All rights reserved. +:License: BSD 3-Clause "New" or "Revised" License. + See LICENSE for details. + If you cannot find LICENSE see + <https://opensource.org/licenses/BSD-3-Clause> +:ID: @(#)@@PKGORIGIN@@ $HGid$ + +' + +VERSION="@@VERSION@@" + +# +# Configuration directory +# +: ${CONFIGDIR:=@@ETCDIR@@} + +test -r "${CONFIGDIR}/tools.conf" && . "${CONFIGDIR}/tools.conf" + +# +# Mapping configuration: installed package name -> original package name +# Note: This is independent of any repo +# +: ${PACKAGE_MAPPING:=${CONFIGDIR}/package-mapping.conf} + +# +# Local repository with non-public packages and/or ports with changed +# OPTIONS (i.e. not using the defaults) or forks of official packages with +# other package names +# +: ${LOCAL_REPO:=LocalRepo} + +# +# Local repository with ports with default OPTIONS (i.e. unchanged) +# but newer than the packages in the "FreeBSD" repository. +# Some sort of a fast-track repository. +# +: ${LOCALBSDPORTS_REPO:=LocalBSDPorts} + +# +# The official FreeBSD binary repository +# +: ${FREEBSD_REPO:=FreeBSD} + +# +# Directly installed from ports +# +: ${PORTS_DIRECT_INSTALLED_REPO:=unknown-repository} + +# +# For the workaround of the bug in pkg rquery -I +# +: ${PORTSDIR:=/usr/ports} +: ${INDEXDIR:=${PORTSDIR}} +: ${INDEXFILE:=@@INDEXFILE@@} + + +get_remote_repo_versions() { + : 'Determine the remote repository versions of all packages in + repository `_repo`. + + Args: + _repo: the name of the repote repository + + Returns: + status 0 on success, 1 on errors + + Output (Globals): + remote_versions_${_repo}: the versions of all packages in `_repo` and + their extended version status with respect to + locally installed packages + + ' + local _repo _data _rv + + _repo=$1 + + _data=$(pkg version -U -R -r ${_repo} -v) + _rv=$? + eval remote_versions_${_repo}=\"\${_data}\" + return ${_rv} +} + +get_remote_repo_data() { + : 'Get the extended package version information from the remote repository + `_repo` for package `_name`. + + Args: + _repo: the name of the remote repository + _name: the package name + + Input (Globals): + remote_versions_${_repo}: the extended version info for *all* packages + in repo `_repo`. + + Returns: + status 0 on success, 1 on errors or if the package is not found + in the remote repository + + Output (Globals): + remote_label_${_repo}: + remote_descr_${_repo}: + + ' + local _repo _name _rversions _rfqp _rl _rdescr + + _repo=$1 + _name=$2 + + eval _rversions=\"\${remote_versions_${_repo}}\" + while read _rfqp _rl _rdescr ; do + if [ ${_rfqp%-*} = ${_name} ] ; then + eval remote_label_${_repo}=\"\${_rl}\" + eval remote_descr_${_repo}=\"\${_rdescr}\" + return 0 + fi + done <<EOF884657 +${_rversions} +EOF884657 + eval remote_label_${_repo}="" + eval remote_descr_${_repo}="" + return 1 +} + +get_local_index_versions() { + : 'Determine the extendes versions of all packages in the local index + (ports). + + Returns: + status 0 on success or 1 on errors + + Output (Globals): + local_index_versions: + + ' + local_index_versions=$(pkg version -I -v) +} + +get_repo_for_installed_package() { + : 'Determine for a package `_name` from which repository is has been + installed. + + Args: + _name: the name of the package to search for + + Input (Globals): + installed_data the output of ``pkg query "%n %v %R"`` of all + installed packages + + Returns: + 0 on success, 1 on errors or if the package is not installed + + Output (Globals): + repository: the repository from which the installed packages `_name` + has been installed + + ' + local _name _n _v _r + + _name=$1 + + while read _n _v _r ; do + if [ ${_name} = ${_n} ] ; then + repository=${_r} + return 0 + fi + done <<EOF223777 +${installed_data} +EOF223777 + return 1 +} + +get_immediate_index_version() { + : 'Determine for package `_package` the version of the package in the + local ports index. + + Args: + _package: the package name to search for + + Input (Globals): + INDEXDIR: the directory where to search the index file + INDEXFILE: the name of the index file + + Returns: + 0 on success, 1 on errors or if the package is not in the index + + Output (Globals): + immediate_index_version: the version number of `_package` in the + index + + ' + local _package _line _fqpn _n _lines + + _package=$1 + +# _val=$(pkg rquery -I "${_package}" | cut -f 1 -d '|') +# _rv=$? +# immediate_index_version=${_val##*-} +# return ${_rv} + + if [ -r "${INDEXDIR}/${INDEXFILE}" ] ; then + # + # Note: Direct piping does not set immediate_index_version at return correctly + # "_line" is set correctly and parsing works, but the return 0 seems to kill + # some of the previous effects. + # + # "grep" does a fast pre-selection, reading, parsing and comparing is done for + # exact matching. + # + _lines=$(egrep '^'"${_package}" "${INDEXDIR}/${INDEXFILE}") + while read _line ; do + _fqpn="${_line%%|*}" + _n=${_fqpn%-*} + if [ "${_package}" = "${_n}" ] ; then + immediate_index_version="${_fqpn##*-}" + return 0 + fi + done <<EOF1334TGH1 +${_lines} +EOF1334TGH1 + fi + + immediate_index_version="" + return 1 +} + +get_immediate_remote_repo_version() { + : 'Ask a remote repository for the version of a package. + + Args: + _repo: the repository name + _name: the name of the package + + Returns: + 0 on success and other status codes otherwise + + Output (Globals): + immediate_remote_repo_version_${_repo}: the version of package `_name` + in repo `_repo` + + ' + local _repo _name _version _rv + + _repo=$1 + _name=$2 + + _version=$(pkg rquery -U -r "${_repo}" '%v' "${_name}") + _rv=$? + eval immediate_remote_repo_version_${_repo}=\"\${_version}\" + return ${_rv} +} + +assert_local_version() { + : 'Check whether an installed package `_name` has given + version `_version`. + + Args: + _name: the package name + _version: the version to check for + + Input (Globals): + installed_data: the output of ``pkg query "%n %v %R"`` of all + installed packages + + Returns: + - 0 if the installed version of package `_name` is equal to `_version` + - 1 if the installed version of package `_name` differs from `_version` + - 2 on other errors + + ' + local _name _version _n _v _r + + _name=$1 + _version=$2 + + while read _n _v _r ; do + if [ ${_name} = ${_n} ] ; then + if [ ${_version} != ${_v} ] ; then + return 1 + else + return 0 + fi + fi + done <<EOF223 +${installed_data} +EOF223 + return 2 +} + +get_mapping() { + : 'Determine whether a package `_package` is essentially the same as + another package. + + Args: + _package: the new name of the package + + Returns: + 0 when a package mapping has been found, 1 otherwise + + Output (Globals): + mapped_package_name: the name of the package on which `_package` is + based on + + This command reads from the mapping database in in file + `/usr/local/etc/local-bsdtools/package-mapping.conf`. + Example:: + + # + # _package mapped_package_name + # + fmg-nextcloud-php71 nextcloud-php71 + fmg-nextcloud-twofactor_totp-php71 nextcloud-twofactor_totp-php71 + + ' + local _package _n _mapped + + _package=$1 + + if [ -r "${PACKAGE_MAPPING}" ] ; then + while read _n _mapped ; do + if [ "${_n}" = "${_package}" ] ; then + mapped_package_name="${_mapped}" + return 0 + fi + done < ${PACKAGE_MAPPING} + fi + mapped_package_name="" + return 1 +} + +print_title() { + : 'Print the output title line for a package + + Args: + _package: the package name + _repo: the repository name + + Input (Globals). + title_printed: a global that determines if the title really needs + to be printed. + + If it is an empty string the the title is + really printed and the variable is set to + "yes". + + Output (Globals): + title_printed: set to "yes" if the title has been printed + + ' + local _package _repo + + _package=$1 + _repo=$2 + if [ -z "${title_printed}" ] ; then + echo "${_package} (${_repo})" + title_printed=yes + fi +} + + +alldata_flag="" +alldata_flag_LocalBSDPorts="" +alldata_flag_LocalRepo="" +short_flag="" +verbose_flag="" + +while getopts "VAasv" _opt ; do + case ${_opt} in + V) + echo "check-ports v${VERSION} (rv:@@HGREVISION@@)" + exit 0 + ;; + A) + # print for every package the status of all repositories + alldata_flag=1 + alldata_flag_LocalBSDPorts=1 + alldata_flag_LocalRepo=1 + ;; + a) + # print the data of all repos that have the package + alldata_flag=1 + ;; + s) + # "short" output: if installed from FreeBSD repo: don't + # report if only the index is newer + short_flag=1 + ;; + v) + # print all titles and repo of every installed always + verbose_flag=1 + ;; + \?) + exit 2 + ;; + *) + echo "option handling failed" >&2 + exit 2 + ;; + esac +done + +if [ -n "${short_flag}" -a -n "${alldata_flag}" ]; then + echo "the -s option cannot be combined with -A or -a" >&2 + exit 2 +fi + +installed_packages=$(pkg query '%n') +installed_data="$(pkg query '%n %v %R' $installed_packages)" + +get_remote_repo_versions ${LOCAL_REPO} +get_remote_repo_versions ${LOCALBSDPORTS_REPO} +get_remote_repo_versions ${FREEBSD_REPO} +get_local_index_versions + +while read lfqp llabel ldescr ; do + _installed_name=${lfqp%-*} + _installed_version=${lfqp##*-} + title_printed="" + get_repo_for_installed_package ${_installed_name} + get_mapping ${_installed_name} + if [ -n "${verbose_flag}" ] ; then + print_title "${lfqp}" "${repository}" + fi + if ! assert_local_version ${_installed_name} ${_installed_version} ; then + echo "Assertion failed: $lfqp ${_installed_name} ${_installed_version} ${llabel}" >&2 + exit 1 + fi + get_remote_repo_data ${LOCAL_REPO} ${_installed_name} + get_remote_repo_data ${LOCALBSDPORTS_REPO} ${_installed_name} + get_remote_repo_data ${FREEBSD_REPO} ${_installed_name} + _print_detail="" + if [ -n "${mapped_package_name}" ] ; then + _print_detail=1 + fi + if [ \( -n "${alldata_flag}" \) ]; then + _print_detail=1 + else + if [ -n "${short_flag}" ]; then + # + # NOTE: -s and -A/-a are incompatible: so "alldata_XXX" needs not + # to be checked! + # + case "${repository}" in + "${FREEBSD_REPO}") + if [ \( "${llabel}" != '<' -a "${llabel}" != '=' \) -o "${remote_label_FreeBSD}" != '=' -o "${remote_label_LocalRepo}" != '?' -o "${remote_label_LocalBSDPorts}" != '?' ]; then + _print_detail=1 + fi + ;; + "${LOCAL_REPO}") + _print_detail=1 + ;; + "${LOCALBSDPORTS_REPO}") + if [ "${llabel}" != '=' -o "${remote_label_FreeBSD}" != '>' -o "${remote_label_LocalRepo}" != '?' -o "${remote_label_LocalBSDPorts}" = '?' -o "${remote_label_LocalBSDPorts}" = '<' ]; then + _print_detail=1 + fi + ;; + "${PORTS_DIRECT_INSTALLED_REPO}") + _print_detail=1 + ;; + *) + echo "ERROR: unhandled repository: ${repository}" >&2 + exit 1 + ;; + esac + else + 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 + _print_detail=1 + fi + fi + fi + if [ -n "${_print_detail}" ]; then + print_title "${lfqp}" "${repository}" + echo " INDEX : ${llabel} ${ldescr}" + echo " FreeBSD : ${remote_label_FreeBSD} ${remote_descr_FreeBSD}" + if [ \( -n "${alldata_flag_LocalBSDPorts}" \) -o \( "${remote_label_LocalBSDPorts}" != '?' \) ] ; then + echo " LocalBSDPorts: ${remote_label_LocalBSDPorts} ${remote_descr_LocalBSDPorts}" + fi + if [ \( -n "${alldata_flag_LocalRepo}" \) -o \( "${remote_label_LocalRepo}" != '?' \) ] ; then + echo " LocalRepo : ${remote_label_LocalRepo} ${remote_descr_LocalRepo}" + fi + if [ -n "${mapped_package_name}" ] ; then + echo " ---> ${mapped_package_name}" + get_immediate_index_version "${mapped_package_name}" + get_immediate_remote_repo_version ${LOCAL_REPO} ${mapped_package_name} + get_immediate_remote_repo_version ${LOCALBSDPORTS_REPO} ${mapped_package_name} + get_immediate_remote_repo_version ${FREEBSD_REPO} ${mapped_package_name} + echo " INDEX : ${immediate_index_version}" + echo " FreeBSD : ${immediate_remote_repo_version_FreeBSD}" + echo " LocalBSDPorts: ${immediate_remote_repo_version_LocalBSDPorts}" + echo " LocalRepo : ${immediate_remote_repo_version_LocalRepo}" + fi + fi +done <<EOF856661111299999 +${local_index_versions} +EOF856661111299999
