# HG changeset patch # User Franz Glasner # Date 1729684612 -7200 # Node ID 56ab5c012d5f4ea52f1af65e5aebd65a0a64875a # Parent 03350d2a2af6a1ff5a0679ed71ddfc6b857e83a2 fports: Begin a new command "fports" and fully implemented its subcommand "fports deptree". fports is supposed to be the successor to check-ports. diff -r 03350d2a2af6 -r 56ab5c012d5f Makefile --- a/Makefile Wed Oct 23 01:00:33 2024 +0200 +++ b/Makefile Wed Oct 23 13:56:52 2024 +0200 @@ -80,7 +80,7 @@ ${MKDIR} ${WRKSRC}/bin ${MKDIR} ${WRKSRC}/sbin ${CP} Makefile ${WRKSRC}/Makefile -.for _rp in sbin/check-ports sbin/fjail sbin/ftjail sbin/fzfs sbin/fpkg sbin/bsmtp2dma +.for _rp in sbin/check-ports sbin/fjail sbin/ftjail sbin/fzfs sbin/fpkg sbin/fports sbin/bsmtp2dma ${CP} -v ${SRC}/${_rp} ${WRKSRC}/${_rp} ${SED} -i "" -e "s|@@VERSION@@|${PORTVERSION}|" -e "s|@@ETCDIR@@|${ETCDIR}|" -e "s|@@DATADIR@@|${DATADIR}|" -e "s|@@SIMPLEVERSIONTAG@@|${SIMPLEVERSIONTAG}|" -e "s|@@SIMPLEVERSIONSTR@@|${SIMPLEVERSIONSTR}|" ${WRKSRC}/${_rp} .endfor @@ -90,7 +90,7 @@ ${SED} -i "" -e "s|@@SIMPLEVERSIONTAG@@|${SIMPLEVERSIONTAG}|" ${WRKSRC}/${_ef} .endfor ${MKDIR} ${WRKSRC}/share/${PORTNAME} -.for _df in share/local-bsdtools/farray.sh share/local-bsdtools/common.subr +.for _df in share/local-bsdtools/farray.sh share/local-bsdtools/common.subr share/local-bsdtools/ports.subr ${CP} -v ${SRC}/${_df} ${WRKSRC}/${_df} ${SED} -i "" -e "s|@@SIMPLEVERSIONTAG@@|${SIMPLEVERSIONTAG}|" ${WRKSRC}/${_df} .endfor @@ -114,7 +114,7 @@ .endif do-install: -.for _rp in sbin/check-ports sbin/fjail sbin/ftjail sbin/fzfs sbin/fpkg sbin/bsmtp2dma +.for _rp in sbin/check-ports sbin/fjail sbin/ftjail sbin/fzfs sbin/fpkg sbin/fports sbin/bsmtp2dma ${INSTALL_SCRIPT} ${WRKSRC}/${_rp} ${STAGEDIR}${PREFIX}/${_rp} .endfor ${MKDIR} ${STAGEDIR}${ETCDIR} @@ -126,7 +126,7 @@ ${INSTALL_SCRIPT} ${WRKSRC}/etc/periodic/daily/${_ps} ${STAGEDIR}${PREFIX}/etc/periodic/daily .endfor ${MKDIR} ${STAGEDIR}${DATADIR} -.for _df in farray.sh common.subr +.for _df in farray.sh common.subr ports.subr ${INSTALL_DATA} ${WRKSRC}/share/${PORTNAME}/${_df} ${STAGEDIR}${DATADIR} .endfor ${MKDIR} ${STAGEDIR}${EXAMPLESDIR} diff -r 03350d2a2af6 -r 56ab5c012d5f docs/conf.py --- a/docs/conf.py Wed Oct 23 01:00:33 2024 +0200 +++ b/docs/conf.py Wed Oct 23 13:56:52 2024 +0200 @@ -92,6 +92,7 @@ #("man/man8/fjail-privs", "fjail-privs", "Adjust some privileges within a mounted jail", [author], 8), #("man/man8/fjail-umount", "fjail-umount", "Recursively unmount a ZFS datasets and its children", [author], 8), ("man/man8/fpkg", "fpkg", "A frontend for some pkg(8) commands that also operate on running jails", [author], 8), + ("man/man8/fports", "fports", "Report the version status of installed packages and check for them also in repositories", [author], 8), ("man/man8/ftjail", "ftjail", "Management of Thin Jails", [author], 8), ("man/man8/ftjail-build-etcupdate-current-tmpl", "ftjail-build-etcupdate-current-tmpl", "Build a \"current\" tree suitable for the default and extract mode of \"etcupdate\"", [author], 8), ("man/man8/ftjail-check-freebsd-update", "ftjail-check-freebsd-update", "Check preconditions to run freebsd-update for a Thin Jail successfully", [author], 8), diff -r 03350d2a2af6 -r 56ab5c012d5f docs/man/index.rst --- a/docs/man/index.rst Wed Oct 23 01:00:33 2024 +0200 +++ b/docs/man/index.rst Wed Oct 23 13:56:52 2024 +0200 @@ -17,6 +17,7 @@ man8/fjail-freebsd-update man8/fjail-hostid man8/fpkg + man8/fports man8/fwireguard man8/ftjail man8/ftjail-build-etcupdate-current-tmpl diff -r 03350d2a2af6 -r 56ab5c012d5f docs/man/man5/package-mapping.conf.rst --- a/docs/man/man5/package-mapping.conf.rst Wed Oct 23 01:00:33 2024 +0200 +++ b/docs/man/man5/package-mapping.conf.rst Wed Oct 23 13:56:52 2024 +0200 @@ -6,7 +6,7 @@ Description ----------- -Used by :manpage:`check-ports(8)`. +Used by :manpage:`check-ports(8)` and :manpage:`fports(8)`. This is a textfile where every line contains two fields -- separated by white space (TAB or SPACE). Each field is a package name:: @@ -39,3 +39,4 @@ See Also -------- +:manpage:`fports`, :manpage:`check-ports(8)` diff -r 03350d2a2af6 -r 56ab5c012d5f docs/man/man5/pkgtools.conf.rst --- a/docs/man/man5/pkgtools.conf.rst Wed Oct 23 01:00:33 2024 +0200 +++ b/docs/man/man5/pkgtools.conf.rst Wed Oct 23 13:56:52 2024 +0200 @@ -6,10 +6,11 @@ Description ----------- -Sourced in by :manpage:`fpkg(8)` and :manpage:`check-ports(8)`. +Sourced in by :manpage:`fpkg(8)`, :manpage:`check-ports(8)` and +:manpage:`fports(8)`. See Also -------- -:manpage:`check-ports(8)`, :manpage:`fpkg(8)` +:manpage:`fports(8)`, :manpage:`check-ports(8)`, :manpage:`fpkg(8)` diff -r 03350d2a2af6 -r 56ab5c012d5f docs/man/man8/check-ports.rst --- a/docs/man/man8/check-ports.rst Wed Oct 23 01:00:33 2024 +0200 +++ b/docs/man/man8/check-ports.rst Wed Oct 23 13:56:52 2024 +0200 @@ -21,6 +21,9 @@ printed with respect to repositories that have the package and have differing versions. This includes the ports INDEX. +The new tool :manpage:`fports(8)` is a more modernized successor to this +tool. + .. program:: check-ports .. option:: -h @@ -231,4 +234,4 @@ See Also -------- -:manpage:`fpkg(8)` +:manpage:`fpkg(8)`, :manpage:`fports(8)` diff -r 03350d2a2af6 -r 56ab5c012d5f docs/man/man8/fports.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/man/man8/fports.rst Wed Oct 23 13:56:52 2024 +0200 @@ -0,0 +1,245 @@ +.. -*- coding: utf-8; indent-tabs-mode: nil; -*- + +fports +====== + +.. program:: fports + + +Synopsis +-------- + +**fports -h** + +**fports -V** + +**fports subcommand** + + +Description +----------- + +Report and check the version status of installed packages and compare +them to version in remote repositories and the local ports index. + +By default (without any option) the status of every package is +printed with respect to repositories that have the package and have +differing versions. This includes the ports INDEX. + +:command:`fpkg` provides some subcommands. + +This tools is the successor of :manpage:`check-ports(8)`. + + +Subcommands +----------- + +These global options are implemented: + +.. option:: -h + + Print a short usage message to stdout and exit. + +.. option:: -V + + Print the program name and version number to stdout and exit. + + +**fports deptree** `package`... + + Print a dependency tree for every given `package`. A package tree is + a hierarchical list of packages that `packages` depends on. + + .. program:: fports deptree + + .. option:: -l + + Limit the output to sub-levels up to `maxlevel`. To print only + direct dependencies use a `maxlevel` of `1`. + Default is 0 (i.e. no limit). + + .. option:: -r + + Use reversed dependencies and print the package tree for all packages + that depend on a given `package`. + + +Environment +----------- + +.. envvar:: INDEXDIR + + If set, the directory to search for `INDEXFILE`. If unset, + :envvar:`PORTSDIR` will be used instead. + +.. envvar:: INDEXFILE + + The filename of the ports index, search for in :envvar:`INDEXDIR` or + :envvar:`PORTSDIR`. + Default: `INDEX-` where `N` is the OS major version number. + +.. envvar:: PORTSDIR + + Specifies the location to the Ports directory. + Default: :file:`/usr/ports`. + + +Files +----- + +:file:`/usr/local/etc/local-bsdtools/package-mapping.conf` + +:file:`/usr/local/etc/local-bsdtools/pkgtools.conf` + + +Examples +-------- + +Report the status of all installed packages with respect to all configured +repositories and the ports index (if available):: + + # check-ports -A + tdb 1.4.3,1 (FreeBSD) + INDEX : 1.4.7,1 < needs updating (index has 1.4.7,1) + FreeBSD : 1.4.7,1 < needs updating (remote has 1.4.7,1) + LocalBSDPorts : ? + SharedLocalRepo: ? + LocalRepo : ? + teckit 2.5.11 (FreeBSD) + INDEX : 2.5.11 = up-to-date with index + FreeBSD : 2.5.11 = up-to-date with remote + LocalBSDPorts : ? + SharedLocalRepo: ? + LocalRepo : ? + tevent 0.10.2_1 (FreeBSD) + INDEX : 0.13.0_1 < needs updating (index has 0.13.0_1) + FreeBSD : 0.13.0 < needs updating (remote has 0.13.0) + LocalBSDPorts : ? + SharedLocalRepo: ? + LocalRepo : ? + tex-basic-engines 20210325 (FreeBSD) + INDEX : 20210325 = up-to-date with index + FreeBSD : 20210325 = up-to-date with remote + LocalBSDPorts : ? + SharedLocalRepo: ? + LocalRepo : ? + # + +Report the status of all installed packages with respect to all configured +repositories that provide the package:: + + # check-ports -a + tdb 1.4.3,1 (FreeBSD) + INDEX : 1.4.7,1 < needs updating (index has 1.4.7,1) + FreeBSD : 1.4.7,1 < needs updating (remote has 1.4.7,1) + teckit 2.5.11 (FreeBSD) + INDEX : 2.5.11 = up-to-date with index + FreeBSD : 2.5.11 = up-to-date with remote + tevent 0.10.2_1 (FreeBSD) + INDEX : 0.13.0_1 < needs updating (index has 0.13.0_1) + FreeBSD : 0.13.0 < needs updating (remote has 0.13.0) + tex-basic-engines 20210325 (FreeBSD) + INDEX : 20210325 = up-to-date with index + FreeBSD : 20210325 = up-to-date with remote + # + +The standard output considers installed packages with versions that differ in any of +the configured repositories *including* a ports INDEX:: + + # check-ports + tdb 1.4.3,1 (FreeBSD) + INDEX : 1.4.7,1 < needs updating (index has 1.4.7,1) + FreeBSD : 1.4.7,1 < needs updating (remote has 1.4.7,1) + tevent 0.10.2_1 (FreeBSD) + INDEX : 0.13.0_1 < needs updating (index has 0.13.0_1) + FreeBSD : 0.13.0 < needs updating (remote has 0.13.0) + tex-xetex 0.99993_1 (FreeBSD) + INDEX : 0.99993_2 < needs updating (index has 0.99993_2) + FreeBSD : 0.99993_1 = up-to-date with remote + texlive-base 20210325_5 (FreeBSD) + INDEX : 20210325_10 < needs updating (index has 20210325_10) + FreeBSD : 20210325_8 < needs updating (remote has 20210325_8) + # + +The effect of an additional :option:`-v` on :command:`check-ports` is:: + + # check-ports -v + tdb 1.4.3,1 (FreeBSD) + INDEX : 1.4.7,1 < needs updating (index has 1.4.7,1) + FreeBSD : 1.4.7,1 < needs updating (remote has 1.4.7,1) + teckit 2.5.11 (FreeBSD) + tevent 0.10.2_1 (FreeBSD) + INDEX : 0.13.0_1 < needs updating (index has 0.13.0_1) + FreeBSD : 0.13.0 < needs updating (remote has 0.13.0) + tex-basic-engines 20210325 (FreeBSD) + tex-dvipdfmx 20210325 (FreeBSD) + tex-dvipsk 2021.1 (FreeBSD) + tex-formats 20210325_1 (FreeBSD) + tex-jadetex 3.13_4 (FreeBSD) + tex-kpathsea 6.3.3 (FreeBSD) + tex-libtexlua 5.3.6 (FreeBSD) + tex-libtexluajit 2.1.0 (FreeBSD) + tex-luatex 1.12.0 (FreeBSD) + tex-ptexenc 1.3.9 (FreeBSD) + tex-synctex 2.0.0_1 (FreeBSD) + tex-web2c 20210325 (FreeBSD) + tex-xdvik 22.87.06 (FreeBSD) + tex-xetex 0.99993_1 (FreeBSD) + INDEX : 0.99993_2 < needs updating (index has 0.99993_2) + FreeBSD : 0.99993_1 = up-to-date with remote + tex-xmltex 1.9_3 (FreeBSD) + texlive-base 20210325_5 (FreeBSD) + INDEX : 20210325_10 < needs updating (index has 20210325_10) + FreeBSD : 20210325_8 < needs updating (remote has 20210325_8) + # + +The :option:`-s` suppresses the output if only the version of a ports INDEX differs:: + + # check-ports -s + tdb 1.4.3,1 (FreeBSD) + INDEX : 1.4.7,1 < needs updating (index has 1.4.7,1) + FreeBSD : 1.4.7,1 < needs updating (remote has 1.4.7,1) + tevent 0.10.2_1 (FreeBSD) + INDEX : 0.13.0_1 < needs updating (index has 0.13.0_1) + FreeBSD : 0.13.0 < needs updating (remote has 0.13.0) + texlive-base 20210325_5 (FreeBSD) + INDEX : 20210325_10 < needs updating (index has 20210325_10) + FreeBSD : 20210325_8 < needs updating (remote has 20210325_8) + # + +The effect of an additional :option:`-v` on :command:`checkports -s` is:: + + # check-ports -sv + tdb 1.4.3,1 (FreeBSD) + INDEX : 1.4.7,1 < needs updating (index has 1.4.7,1) + FreeBSD : 1.4.7,1 < needs updating (remote has 1.4.7,1) + teckit 2.5.11 (FreeBSD) + tevent 0.10.2_1 (FreeBSD) + INDEX : 0.13.0_1 < needs updating (index has 0.13.0_1) + FreeBSD : 0.13.0 < needs updating (remote has 0.13.0) + tex-basic-engines 20210325 (FreeBSD) + tex-dvipdfmx 20210325 (FreeBSD) + tex-dvipsk 2021.1 (FreeBSD) + tex-formats 20210325_1 (FreeBSD) + tex-jadetex 3.13_4 (FreeBSD) + tex-kpathsea 6.3.3 (FreeBSD) + tex-libtexlua 5.3.6 (FreeBSD) + tex-libtexluajit 2.1.0 (FreeBSD) + tex-luatex 1.12.0 (FreeBSD) + tex-ptexenc 1.3.9 (FreeBSD) + tex-synctex 2.0.0_1 (FreeBSD) + tex-web2c 20210325 (FreeBSD) + tex-xdvik 22.87.06 (FreeBSD) + tex-xetex 0.99993_1 (FreeBSD) + tex-xmltex 1.9_3 (FreeBSD) + texlive-base 20210325_5 (FreeBSD) + INDEX : 20210325_10 < needs updating (index has 20210325_10) + FreeBSD : 20210325_8 < needs updating (remote has 20210325_8) + # + + +See Also +-------- + +:manpage:`fpkg(8)`, :manpage:`check-ports(8)`, +:manpage:`pkgtools.conf(5)`, :manpage:`package-mapping.conf(5)` diff -r 03350d2a2af6 -r 56ab5c012d5f docs/man/man8/local-bsdtools.rst --- a/docs/man/man8/local-bsdtools.rst Wed Oct 23 01:00:33 2024 +0200 +++ b/docs/man/man8/local-bsdtools.rst Wed Oct 23 13:56:52 2024 +0200 @@ -67,6 +67,8 @@ - :manpage:`fpkg(8)` +- :manpage:`fports(8)` + - :manpage:`fbhyve(8)` - :manpage:`fwireguard(8)` diff -r 03350d2a2af6 -r 56ab5c012d5f pkg-plist --- a/pkg-plist Wed Oct 23 01:00:33 2024 +0200 +++ b/pkg-plist Wed Oct 23 13:56:52 2024 +0200 @@ -7,9 +7,11 @@ sbin/fjail sbin/ftjail sbin/fpkg +sbin/fports sbin/fzfs %%DATADIR%%/common.subr %%DATADIR%%/farray.sh +%%DATADIR%%/ports.subr %%EXAMPLESDIR%%/freebsd-update-ftjail-template.sh %%EXAMPLESDIR%%/freebsd-update-ftjail.sh %%DOCS%%share/man/man5/bsmtp2dma.conf.5.gz @@ -25,6 +27,7 @@ %%DOCS%%share/man/man8/fjail-freebsd-update.8.gz %%DOCS%%share/man/man8/fjail-hostid.8.gz %%DOCS%%share/man/man8/fpkg.8.gz +%%DOCS%%share/man/man8/fports.8.gz %%DOCS%%share/man/man8/ftjail.8.gz %%DOCS%%share/man/man8/ftjail-build-etcupdate-current-tmpl.8.gz %%DOCS%%share/man/man8/ftjail-check-freebsd-update.8.gz diff -r 03350d2a2af6 -r 56ab5c012d5f sbin/fports --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbin/fports Wed Oct 23 13:56:52 2024 +0200 @@ -0,0 +1,272 @@ +#!/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 +#: +#: :ID: @(#)@@SIMPLEVERSIONTAG@@ +#: + +: # separator for shellcheck: no module-level directives below + +# shellcheck disable=SC2034 # VERSION appears unused +VERSION='@@VERSION@@' + +# shellcheck disable=SC2016 # no expansion +USAGE=' +USAGE: fports [ GLOBAL-OPTIONS ] COMMAND [ COMMAND-OPTIONS ] + +GLOBAL OPTIONS: + + -V Print the program name and version number to stdout and exit + + -h Print this help message to stdout and exit + +' + + +_p_datadir='@@DATADIR@@' +[ "${_p_datadir#@@DATADIR}" = '@@' ] && _p_datadir="$(dirname "$0")"/../share/local-bsdtools +. "${_p_datadir}/common.subr" +. "${_p_datadir}/farray.sh" +. "${_p_datadir}/ports.subr" + + +#: +#: Configuration directory. +#: +: "${CONFIGDIR:=@@ETCDIR@@}" + +#: +#: Mapping configuration: installed package name -> original package name. +#: +#: Note: +#: This is independent of any repo +# +: "${PACKAGE_MAPPING:=${CONFIGDIR}/package-mapping.conf}" + +# shellcheck disable=SC1091 # does not exist -- cannot read +[ -r "${CONFIGDIR}/pkgtools.conf" ] && . "${CONFIGDIR}/pkgtools.conf" + + +# no unset variables +set -u + + +#: +#: Implementation of the "deptree" command. +#: +command_deptree() { + local opt opt_reversed opt_maxlevel + # $@ + + opt_maxlevel=0 + opt_reversed=no + while getopts "l:r" opt; do + case "${opt}" in + l) + opt_maxlevel=$(($OPTARG + 0));; + r) + opt_reversed=yes;; + \?) + exit 2;; + *) + fatal 2 "option handling failed";; + esac + done + shift $((OPTIND-1)) + OPTIND=1 + + if checkyesno opt_reversed; then + _command_deptree_reversed "${opt_maxlevel}" "$@" + else + _command_deptree_normal "${opt_maxlevel}" "$@" + fi +} + + +#: +#: Implementation of printing a "normal" dependency tree +#: +_command_deptree_normal() { + local maxlevel # $@ + + local pkgdeps pkgqueue curdeps pkg n v + + maxlevel="${1}" + shift + + # shellcheck disable=SC2034 # pkgqueue seems unused + pkgqueue='' + farray_create pkgqueue # queue (array) of packages that are queued for + # resolution + + for pkg in "$@"; do + if ! pkg query '%n' "${pkg}" 1>/dev/null 2>/dev/null ; then + farray_release pkgqueue + fatal "${EX_DATAERR}" "Package not found: ${pkg}" + fi + farray_append pkgqueue "${pkg}" + done + pkgdeps='' + falist_create pkgdeps # alist of packagges with its direct dependencies + while farray_pop pkg pkgqueue 1; do + if ! falist_contains pkgdeps "${pkg}"; then + curdeps='' + farray_create curdeps + while IFS=$' \t\n' read -r n v; do + [ -z "${n}" ] || [ -z "${v}" ] && continue + farray_append curdeps "${n}=${v}" + farray_append pkgqueue "${n}" + done <' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${pkgdeps}" + done + falist_release pkgdeps +} + + +#: +#: Implementation of printing a reversed dependency tree +#: +_command_deptree_reversed() { + local maxlevel # $@ + + local pkgdeps pkgqueue curdeps pkg n v + + maxlevel="${1}" + shift + + # shellcheck disable=SC2034 # pkgqueue seems unused + pkgqueue='' + farray_create pkgqueue # queue (array) of packages that are queued for + # resolution + + for pkg in "$@"; do + if ! pkg query '%n' "${pkg}" 1>/dev/null 2>/dev/null ; then + farray_release pkgqueue + fatal "${EX_DATAERR}" "Package not found: ${pkg}" + fi + farray_append pkgqueue "${pkg}" + done + pkgdeps='' + falist_create pkgdeps # alist of packagges with its direct dependencies + while farray_pop pkg pkgqueue 1; do + if ! falist_contains pkgdeps "${pkg}"; then + curdeps='' + farray_create curdeps + while IFS=$' \t\n' read -r n v; do + [ -z "${n}" ] || [ -z "${v}" ] && continue + farray_append curdeps "${n}=${v}" + farray_append pkgqueue "${n}" + done < +#: :ID: @(#)@@SIMPLEVERSIONTAG@@ +#: + + +: # Dummy separator for shellcheck: no module-wide settings below this line + + +# Need definitions from farray.subr +type falist_create 1>/dev/null 2>/dev/null || { echo "ERROR: source \`farray.sh' first"; exit 70; } +# Need definitions from common.subr +type fatal 1>/dev/null 2>/dev/null || { echo "ERROR: source \`common.subr' first"; exit 70; } + + +#: +#: Determine whether a package `_package` is essentially the same as +#: another package. +#: +#: Args: +#: $1 (str): The package mapping database alist. This database must have +#: been initialized by `init_package_mapping`. +#: +#: $2 (str): The name of the installed package +#: +#: Returns: +#: int: 0 (truthy) when a package mapping has been found, +#: 1 (falsy) otherwise (in this case the output to stdout is empty) +#: +#: Output (stdout): +#: The name of the package on which `_package` is/was based on +#: +get_package_mapping() { + local _mapping _installed_package + + local _pos _iname _mapped_package + + _mapping="${1-}" + _installed_package="${2-}" + [ -z "${_installed_package}" ] && fatal "${EX_USAGE}" "missing package name" + + if falist_tryget _mapped_package "${_mapping}" "${_installed_package}"; then + printf '%s' "${_mapped_package}" + return 0 + else + return 1 + fi +} + + +#: +#: Slurp in the configured :file:`package-mapping.conf`. +#: +#: This command reads in the the mapping database in in file which defaults +#: to :file:`/usr/local/etc/local-bsdtools/package-mapping.conf`. +#: It is read into a freshly created alist. Its variable name is given as +#: `$1`. +#: +#: Args: +#: $1 (str): The variable where to create the alist +#: +#: Input (Globals): +#: PACKAGE_MAPPING: See also :manpage:`package-mapping.conf(5)`. +#: +#: Return: +#: int: 0 on success, +#: 65 (aka `EX_DATAERR`) if a duplicate package name was encountered. +#: +#: Note that an unreadable `PACKAGE_MAPPING` database file does not +#: error but yields an empty database. +#: +#: Example of a :file:`package-mapping.conf`:: +#: +#: # +#: # _installed_package mapped_package_name +#: # +#: fmg-nextcloud-php71 nextcloud-php71 +#: fmg-nextcloud-twofactor_totp-php71 nextcloud-twofactor_totp-php71 +#: +init_package_mapping() { + local _mapping + + local _iname _mapped_package + + falist_create "$1" || return + _mapping="$1" + + if [ -r "${PACKAGE_MAPPING}" ] ; then + while IFS=$' \t' read -r _iname _mapped_package ; do + case "${_iname}" in + '') + # empty line + continue;; + \#*) + # comment + continue;; + *) + if ! falist_set_unique "${_mapping}" "${_iname}" "${_mapped_package}" ; then + fatal "${EX_DATAERR}" "duplicate installed package name \`${_iname}'" + return 1 + fi + ;; + esac + done < "${PACKAGE_MAPPING}" + fi + return 0 +} + + +#: +#: Read in the list of configured and enabled package repositories +#: from :manpage:`pkg(8)`. +#: +#: The output of :command:`pkg -vv` is parsed to get all the configured +#: and enabled repositories. +#: +#: Output (stdout): +#: Each configured and enabled repository name is printed on a single +#: line. +#: +get_configured_pkg_repository_names() { + + local _line _status _repository_name _repository_enabled _key _value _rest + + _status='' + while IFS=$' \t' read -r _line; do + case "${_status}" in + '') + if [ "${_line}" = "Repositories:" ]; then + _status="repositories" + fi + ;; + repositories) + case "${_line}" in + *': {') + _status=repository + _repository_name="${_line%:*}" + _repository_enabled=no + ;; + *) + ;; + esac + ;; + repository) + case "${_line}" in + *\}) + if [ "${_repository_enabled}" = 'yes' ] ; then + printf '%s\n' "${_repository_name}" + fi + _repository_name='' + _repository_enabled=no + _status=repositories + ;; + *) + _key='' + _value='' + IFS=$' \t:' read -r _key _value _rest || true <