Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
view sbin/check-ports @ 772:e942b091b762
farray.sh: Wording
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Wed, 23 Oct 2024 16:44:12 +0200 |
| parents | 907cbedee676 |
| children | e2f262ec2bf4 |
line wrap: on
line source
#!/bin/sh # -*- indent-tabs-mode: nil; -*- : 'Check the version status of installed ports and compare them to version in remote repositories and the local ports index. :Author: Franz Glasner :Copyright: (c) 2017-2024 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: @(#)@@SIMPLEVERSIONTAG@@ ' # shellcheck disable=SC2034 # VERSION appears unused VERSION='@@VERSION@@' USAGE=' USAGE: check-ports [options] [args...] Options: -V Print the program name and version number to stdout and exit -h Print this help message to stdout and exit -A Print for every package the status of all repositories -a Print the data of all repos that have the package -n Print the status of given packages in `args` in all details. No other options are respected. -s Print the status of all packages that need some attention -v Print the title and repository of every installed package always Per Default (without any option) the status of every package is printed with respect to repositories that have the package and have differing versions. ' # # Configuration directory # : ${CONFIGDIR:="@@ETCDIR@@"} [ -r "${CONFIGDIR}/pkgtools.conf" ] && . "${CONFIGDIR}/pkgtools.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. # This repo is strictly *local* to the host and/or jail. # : ${LOCAL_REPO:=LocalRepo} # # Shared local repository with non-public packages and/or ports with # changed OPTIONS (i.e. not using the defaults). # Contrary to LOCAL_REPO this repository may be shared. # : ${SHARED_LOCAL_REPO:=SharedLocalRepo} # # (Shared) repository with ports with default OPTIONS (i.e. unchanged) # but newer than the packages in the "FreeBSD" repository. # Can also contain non-FreeBSD *public* packages. # May be shared. # 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} test_exists_local_index() { : 'Determine whether there exists a ports directory with an index file. Returns: status 0 iff the local index exists ' pkg version -I -n DUMMY >/dev/null 2>/dev/null } get_ports_index_directory() { : 'Ask the packager configuration for the `INDEXDIR` and/or `PORTSDIR` configuration value: either `INDEXDIR` or -- if `INDEXDIR` is empty -- `PORTSDIR` is used. Output (stdout) the directory where the index database file lives ' local _dir _dir="$(pkg config INDEXDIR)" if [ -z "${_dir}" ]; then _dir="$(pkg config PORTSDIR)" fi printf '%s' "${_dir}" } get_ports_index_version() { : 'Determine for package `_package` the version of the package in the local ports index. Args: _package: the package name to search for Returns: 0 on success, 1 on errors or if the package is not in the local ports index Output (stdout): the version number of `_package` in the local ports index ' local _package _line _fqpn _n _lines local _indexdir _indexfile _package="$1" # _val=$(pkg rquery -I "${_package}" | cut -f 1 -d '|') # _rv=$? # immediate_index_version=${_val##*-} # return ${_rv} _indexdir="$(get_ports_index_directory)" _indexfile="$(pkg config INDEXFILE)" 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. # # Use BREs because a `+' char needs to be handled as an ordinary # character (e.g. for the "lucene++" package). # Note that `^' at the start of an RE is not an ordinary # character. See re_format(7). # _lines=$(/usr/bin/grep -G '^'"${_package}" "${_indexdir}/${_indexfile}") while read -r _line ; do _fqpn="${_line%%|*}" _n=${_fqpn%-*} if [ "${_package}" = "${_n}" ] ; then printf '%s' "${_fqpn##*-}" return 0 fi done <<EOF1334TGH1 ${_lines} EOF1334TGH1 fi return 1 } 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 (stdout): 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 local - set -x _package="$1" if [ -r "${PACKAGE_MAPPING}" ] ; then while IFS=$' \t' read -r _n _mapped ; do case "${_n}" in '') # empty line continue;; \#*) # comment continue;; *) if [ "${_n}" = "${_package}" ] ; then printf '%s' "${_mapped}" return 0 fi ;; esac done < "${PACKAGE_MAPPING}" fi return 1 } print_title() { : 'Print the output title line for a package Args: _package: the package name _version: the package version _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 _version _repo _package="$1" _version="$2" _repo="$3" if [ -z "${title_printed}" ]; then printf '%-36s %-17s (%s)\n' "${_package}" "${_version}" "${_repo}" title_printed=yes fi } print_detail_item() { : 'Print a detail item to stdout. The description `_descr` will not be printed if the label `_label` is ``?``. Args: _repo: the repository name _version: the version number to print to _label: the label (aka comparison character) to print to _descr: the description to print to _indent: (optional) extra indentation number (default 0) Output (stdout): the formatted detail line ' local _repo _version _label _descr _indent local _real_descr _repo="$1" _version="$2" _label="$3" _descr="$4" _indent="$5" if [ -z "${_indent}" ]; then _indent="0" fi if [ "${_label}" = '?' ]; then _real_descr='' else _real_descr="${_descr}" fi printf '%-*s %-15s: %-17s %s %s\n' $((_indent)) '' "${_repo}" "${_version}" "${_label}" "${_real_descr}" } check_ports() { : 'Implementation of all command variants besides of `-n` ' local _ipackage _iversion _irepo _mapped_package_name _dummy local _print_detail _local_index_exists local _index_version _index_label _index_descr local _remote_version_FreeBSD _remote_label_FreeBSD _remote_descr_FreeBSD local _remote_version_LocalBSDPorts _remote_label_LocalBSDPorts _remote_descr_LocalBSDPorts local _remote_version_SharedLocalRepo _remote_label_SharedLocalRepo _remote_descr_SharedLocalRepo local _remote_version_LocalRepo _remote_label_LocalRepo _remote_descr_LocalRepo if test_exists_local_index; then _local_index_exists="1" fi pkg query '%n %v %R' | while read -r _ipackage _iversion _irepo; do title_printed="" _print_detail="" if [ -n "${_local_index_exists}" ]; then read -r _dummy _index_label _index_descr <<EOF_INDEX $(pkg version -U -I -n "${_ipackage}" -v) EOF_INDEX fi read -r _dummy _remote_label_FreeBSD _remote_descr_FreeBSD <<EOF_FreeBSD $(pkg version -U -R -r "${FREEBSD_REPO}" -n "${_ipackage}" -v) EOF_FreeBSD read -r _dummy _remote_label_LocalBSDPorts _remote_descr_LocalBSDPorts <<EOF_LocalBSDPorts $(pkg version -U -R -r "${LOCALBSDPORTS_REPO}" -n "${_ipackage}" -v) EOF_LocalBSDPorts read -r _remote_fpname_SharedLocalRepo _remote_label_SharedLocalRepo _remote_descr_SharedLocalRepo <<EOF_SharedLocalRepo $(pkg version -U -R -r "${SHARED_LOCAL_REPO}" -n "${_ipackage}" -v) EOF_SharedLocalRepo read -r _remote_fpname_LocalRepo _remote_label_LocalRepo _remote_descr_LocalRepo <<EOF_LocalRepo $(pkg version -U -R -r "${LOCAL_REPO}" -n "${_ipackage}" -v) EOF_LocalRepo if [ -n "${option_verbose}" ]; then print_title "${_ipackage}" "${_iversion}" "${_irepo}" fi if get_mapping "${_ipackage}" >/dev/null; then _print_detail="1" fi if [ -n "${option_alldata}" ]; then _print_detail="1" else if [ -n "${option_short}" ]; then case "${_irepo}" in "${FREEBSD_REPO}") if [ -n "${_local_index_exists}" ]; then if [ "${_index_label}" != '<' -a "${_index_label}" != '=' ]; then _print_detail=1 fi fi if [ "${_remote_label_FreeBSD}" != '=' -o "${_remote_label_SharedLocalRepo}" != '?' -o "${_remote_label_LocalRepo}" != '?' -o "${_remote_label_LocalBSDPorts}" != '?' ]; then _print_detail=1 fi ;; "${LOCALBSDPORTS_REPO}") if [ -n "${_local_index_exists}" ]; then if [ "${_index_label}" != '=' ]; then _print_detail=1 fi fi if [ "${_remote_label_FreeBSD}" != '>' -o "${_remote_label_LocalRepo}" != '?' -o "${_remote_label_SharedLocalRepo}" != '?' -o "${_remote_label_LocalBSDPorts}" = '?' -o "${_remote_label_LocalBSDPorts}" = '<' ]; then _print_detail=1 fi ;; "${SHARED_LOCAL_REPO}") _print_detail=1 ;; "${LOCAL_REPO}") _print_detail=1 ;; "${PORTS_DIRECT_INSTALLED_REPO}") _print_detail=1 ;; *) echo "ERROR: unhandled repository: ${_irepo}" >&2 exit 1 ;; esac else if [ -n "${_local_index_exists}" ]; then if [ "${_index_label}" != '?' -a "${_index_label}" != '=' ]; then _print_detail=1 fi fi if [ "${_remote_label_FreeBSD}" != '?' -a "${_remote_label_FreeBSD}" != '=' ]; then _print_detail=1 fi if [ "${_remote_label_LocalBSDPorts}" != '?' -a "${_remote_label_LocalBSDPorts}" != '=' ]; then _print_detail=1 fi if [ "${_remote_label_SharedLocalRepo}" != '?' -a "${_remote_label_SharedLocalRepo}" != '=' ]; then _print_detail=1 fi if [ "${_remote_label_LocalRepo}" != '?' -a "${_remote_label_LocalRepo}" != '=' ]; then _print_detail=1 fi fi fi if [ -n "${_print_detail}" ]; then print_title "${_ipackage}" "${_iversion}" "${_irepo}" if [ -n "${_local_index_exists}" ]; then _index_version="$(get_ports_index_version "${_ipackage}")" print_detail_item "INDEX" "${_index_version}" "${_index_label}" "${_index_descr}" fi if [ -n "${option_alldata_FreeBSD}" -o "${_remote_label_FreeBSD}" != '?' ]; then _remote_version_FreeBSD="$(pkg rquery -U -r "${FREEBSD_REPO}" '%v' "${_ipackage}")" print_detail_item "${FREEBSD_REPO}" "${_remote_version_FreeBSD}" "${_remote_label_FreeBSD}" "${_remote_descr_FreeBSD}" fi if [ -n "${option_alldata_LocalBSDPorts}" -o "${_remote_label_LocalBSDPorts}" != '?' ]; then _remote_version_LocalBSDPorts="$(pkg rquery -U -r "${LOCALBSDPORTS_REPO}" '%v' "${_ipackage}")" print_detail_item "${LOCALBSDPORTS_REPO}" "${_remote_version_LocalBSDPorts}" "${_remote_label_LocalBSDPorts}" "${_remote_descr_LocalBSDPorts}" fi if [ -n "${option_alldata_SharedLocalRepo}" -o "${_remote_label_SharedLocalRepo}" != '?' ]; then _remote_version_SharedLocalRepo="$(pkg rquery -U -r "${SHARED_LOCAL_REPO}" '%v' "${_ipackage}")" print_detail_item "${SHARED_LOCAL_REPO}" "${_remote_version_SharedLocalRepo}" "${_remote_label_SharedLocalRepo}" "${_remote_descr_SharedLocalRepo}" fi if [ -n "${option_alldata_LocalRepo}" -o "${_remote_label_LocalRepo}" != '?' ]; then _remote_version_LocalRepo="$(pkg rquery -U -r "${LOCAL_REPO}" '%v' "${_ipackage}")" print_detail_item "${LOCAL_REPO}" "${_remote_version_LocalRepo}" "${_remote_label_LocalRepo}" "${_remote_descr_LocalRepo}" fi _mapped_package_name="$(get_mapping "${_ipackage}")" if [ -n "${_mapped_package_name}" ] ; then printf '%18s %s %s (%s)\n' "--------------->" "${_mapped_package_name}" "$(pkg rquery -U '%v' "${_mapped_package_name}")" "$(pkg rquery -U '%R' "${_mapped_package_name}")" if [ -n "${_local_index_exists}" ]; then print_detail_item "INDEX" "$(get_ports_index_version "${_mapped_package_name}")" "" "" fi print_detail_item "${FREEBSD_REPO}" "$(pkg rquery -U -r "${FREEBSD_REPO}" '%v' "${_mapped_package_name}")" "" "" print_detail_item "${LOCALBSDPORTS_REPO}" "$(pkg rquery -U -r "${LOCALBSDPORTS_REPO}" '%v' "${_mapped_package_name}")" "" "" print_detail_item "${SHARED_LOCAL_REPO}" "$(pkg rquery -U -r "${SHARED_LOCAL_REPO}" '%v' "${_mapped_package_name}")" "" "" print_detail_item "${LOCAL_REPO}" "$(pkg rquery -U -r "${LOCAL_REPO}" '%v' "${_mapped_package_name}")" "" "" fi fi done } check_given_packages() { : 'Check the status of all given packages in the most detail possible Args: $@: the name of packages to handle to ' local _package _version _label _repo _descr _dummy local _local_index_exists _mapped_package_name if test_exists_local_index; then _local_index_exists="1" fi while [ $# -gt 0 ]; do _package="$1" shift read -r _version _repo <<EOF_INSTALLED $(pkg query '%v %R' "${_package}") EOF_INSTALLED if [ -n "${_version}" ]; then title_printed="" print_title "${_package}" "${_version}" "${_repo}" if [ -n "${_local_index_exists}" ]; then read -r _dummy _label _descr <<EOF_INDEX $(pkg version -U -I -n "${_package}" -v) EOF_INDEX _version="$(get_ports_index_version "${_package}")" print_detail_item "INDEX" "${_version}" "${_label}" "${_descr}" fi for _repo in "${FREEBSD_REPO}" "${LOCALBSDPORTS_REPO}" "${SHARED_LOCAL_REPO}" "${LOCAL_REPO}"; do read -r _dummy _label _descr <<EOF_REPO $(pkg version -U -R -r "${_repo}" -n "${_package}" -v) EOF_REPO _version="$(pkg rquery -U -r "${_repo}" '%v' "${_package}")" print_detail_item "${_repo}" "${_version}" "${_label}" "${_descr}" done _mapped_package_name="$(get_mapping "${_package}")" if [ -n "${_mapped_package_name}" ] ; then printf '%18s %s %s (%s)\n' "--------------->" "${_mapped_package_name}" "$(pkg rquery -U '%v' "${_mapped_package_name}")" "$(pkg rquery -U '%R' "${_mapped_package_name}")" if [ -n "${_local_index_exists}" ]; then print_detail_item "INDEX" "$(get_ports_index_version "${_mapped_package_name}")" "" "" fi for _repo in "${FREEBSD_REPO}" "${LOCALBSDPORTS_REPO}" "${SHARED_LOCAL_REPO}" "${LOCAL_REPO}"; do print_detail_item "${_repo}" "$(pkg rquery -U -r "${_repo}" '%v' "${_mapped_package_name}")" "" "" done fi fi done } option_alldata="" option_alldata_FreeBSD="" option_alldata_LocalBSDPorts="" option_alldata_SharedLocalRepo="" option_alldata_LocalRepo="" option_short="" option_verbose="" option_packages="" while getopts "VhAansv" _opt ; do case ${_opt} in V) printf 'check-ports %s\n' '@@SIMPLEVERSIONSTR@@' exit 0 ;; h) echo "${USAGE}" exit 0 ;; A) # Print for every package the status of all repositories option_alldata="1" option_alldata_FreeBSD="1" option_alldata_LocalBSDPorts="1" option_alldata_SharedLocalRepo="1" option_alldata_LocalRepo="1" ;; a) # Print the data of all repos that have the package option_alldata="1" ;; n) # # Print status of given packages in all details. # No other options are respected. # option_packages="1" ;; s) # "short" output: if installed from FreeBSD repo: don't # report if only the index is newer option_short="1" ;; v) # # Print all titles and repo of every installed package always. # The output of the other repo status nevertheless depends on the # other flag settings. # option_verbose="1" ;; \?) exit 2 ;; *) echo "option handling failed" >&2 exit 2 ;; esac done # # Reset the Shell's option handling system to prepare for handling # command-local options. # shift $((OPTIND-1)) OPTIND=1 if [ -n "${option_short}" -a -n "${option_alldata}" ]; then echo "the -s option cannot be combined with -A or -a" >&2 exit 2 fi if [ -n "${option_packages}" ]; then check_given_packages "$@" else check_ports fi
