Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
changeset 770:56ab5c012d5f
fports: Begin a new command "fports" and fully implemented its subcommand "fports deptree".
fports is supposed to be the successor to check-ports.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Wed, 23 Oct 2024 13:56:52 +0200 |
| parents | 03350d2a2af6 |
| children | 1c9c1cd4fd47 |
| files | Makefile docs/conf.py docs/man/index.rst docs/man/man5/package-mapping.conf.rst docs/man/man5/pkgtools.conf.rst docs/man/man8/check-ports.rst docs/man/man8/fports.rst docs/man/man8/local-bsdtools.rst pkg-plist sbin/fports share/local-bsdtools/ports.subr tests/etc/package-mapping.conf tests/ports.t |
| diffstat | 13 files changed, 843 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- 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}
--- 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),
--- 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
--- 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)`
--- 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)`
--- 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)`
--- /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 <maxlevel> + + 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-<N>` 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)`
--- 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)`
--- 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
--- /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 +#: <https://opensource.org/licenses/BSD-3-Clause> +#: :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 <<EOF_01a8cebe-8659-4e32-87a4-bbce117e386b +$(LC_ALL=C.UTF-8 pkg query '%dn %dv' "${pkg}") +EOF_01a8cebe-8659-4e32-87a4-bbce117e386b + falist_set pkgdeps "${pkg}" "${curdeps}" + farray_release curdeps + curdeps='' + fi + done + farray_release pkgqueue + # falist_debug pkgdeps + for pkg in "$@"; do + _print_dependency_tree 0 "${maxlevel}" '-->' "${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 <<EOF_5079e996-c6d2-4e6d-825d-53183a64ab06 +$(LC_ALL=C.UTF-8 pkg query '%rn %rv' "${pkg}") +EOF_5079e996-c6d2-4e6d-825d-53183a64ab06 + falist_set pkgdeps "${pkg}" "${curdeps}" + farray_release curdeps + curdeps='' + fi + done + farray_release pkgqueue + # falist_debug pkgdeps + for pkg in "$@"; do + _print_dependency_tree 0 "${maxlevel}" '<--' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${pkgdeps}" + done + falist_release pkgdeps +} + + +#: +#: Internal helper to print an indented dependency list for a package. +#: +#: Args: +#: $1 (int): The (indentation) level where a level of `0` is the root level +#: $2 (int): The maximum level (`$1`) to print to +#: $3 (str): The package tag to use to for non-root-levels +#: $4 (str): The package name +#: $5 (str): The package version +#: $6 (alist): The llist of resolved packages and their dependencies +#: +_print_dependency_tree() { + # $1 $2 $3 $4 $5 $6 + + local i pkg ver curdeps + + if [ "${2}" -ge 1 ]; then + [ "${1}" -gt "${2}" ] && return 0 + fi + + i="${1}" + while [ "${i}" -gt 1 ]; do + printf '%s' ' ' + i=$((i - 1)) + done + [ "${1}" -ne 0 ] && printf '%s ' "${3}" + printf '%s v%s\n' "${4}" "${5}" + falist_get curdeps "${6}" "${pkg}" + i=1 + while farray_tryget pkg "${curdeps}" "${i}"; do + ver="${pkg#*=}" + pkg="${pkg%%=*}" + _print_dependency_tree $(($1 + 1)) "${2}" "${3}" "${pkg}" "${ver}" "${6}" + i=$((i + 1)) + done + farray_release curdeps +} + + +# +# Global option handling +# +while getopts "Vh" _opt ; do + case "${_opt}" in + V) + printf 'fports %s\n' '@@SIMPLEVERSIONSTR@@' + exit 0 + ;; + h) + echo "${USAGE}" + exit 0 + ;; + \?) + exit 2; + ;; + *) + fatal 2 "option handling failed" + ;; + esac +done + +# +# Reset the Shell's option handling system to prepare for handling +# command-local options. +# +shift $((OPTIND-1)) +OPTIND=1 + +command="${1-}" +shift + +case "${command}" in + '') fatal 2 "no command given";; + deptree) + command_deptree "$@";; + *) + fatal 2 "unknown command \`${command}'";; +esac
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/local-bsdtools/ports.subr Wed Oct 23 13:56:52 2024 +0200 @@ -0,0 +1,229 @@ +#!/bin/sh +# -*- mode: shell-script; indent-tabs-mode: nil; -*- +#: +#: Helper functions for :command:`fports` and friends. +#: +#: :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@@ +#: + + +: # 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 <<EOF73d43dccec1a496f98cb519be160f549 +${_line} +EOF73d43dccec1a496f98cb519be160f549 + if [ "${_key}" = "enabled" ]; then + case "${_value}" in + 'yes,'|yes) + _repository_enabled=yes;; + *) + _repository_enabled=no;; + esac + fi + ;; + esac + ;; + *) + fatal "${EX_SOFTWARE}" "unhandled format of \`pkg -vv'" + esac + done <<EOF7c6ea1b0ce544021a7813757c7003392 +$(LC_ALL=C.UTF-8 pkg -vv) +EOF7c6ea1b0ce544021a7813757c7003392 +} + + +_cleanup_init_repositories() { + [ -n "${__repodb}" ] && falist_release "${_repodb}" + [ -n "${__allrepos}" ] && falist_release "${_allrepos}" +} + + +init_repositories() { + local _allrepos + + local _reponame _repodb _pkgname _pkgversion + local _idx + local _test + + falist_create "$1" || return + _allrepos="$1" + + while IFS='' read -r _reponame; do + if ! falist_create _repodb; then + _cleanup_init_repositories + return 1 + fi + farray_create _test + _idx=0 + while IFS=$'\t' read -r _pkgname _pkgversion; do + _idx=$((_idx + 1)) + echo "$_pkgname $_pkgversion" + #_test="$(/sbin/skein256 -q "${_pkgname}")" + falist_add _repodb "${_pkgname}" "${_pkgversion}" + #farray_append _test "${_pkgversion}" + #[ $_idx -gt 5000 ] && break + done <<EOF_pkg_9b5d20d4-805e-484e-9afb-ecc62e75f7cc +$(LC_ALL=C.UTF-8 pkg rquery -U -r "${_reponame}" $'%n\t%v') +EOF_pkg_9b5d20d4-805e-484e-9afb-ecc62e75f7cc + falist_set "${_allrepos}" "${_reponame}" "${_repodb}" + falist_release _repodb + done <<EOF_repos_d6177ceb-b027-4fe2-bc71-e6b5017c0663 +$(get_configured_pkg_repository_names) +EOF_repos_d6177ceb-b027-4fe2-bc71-e6b5017c0663 + falist_debug "${_allrepos}" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/etc/package-mapping.conf Wed Oct 23 13:56:52 2024 +0200 @@ -0,0 +1,4 @@ +install-package parent-package +install-package-v2 parent-package-v2 +# commented out +#install-package-v3 parant-package-v3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/ports.t Wed Oct 23 13:56:52 2024 +0200 @@ -0,0 +1,73 @@ +Basic tests of ports.subr + +Shell is /bin/sh + + +Setup +===== + +We need common.subr and ports.subr + + $ set -u + $ . "${TESTDIR}/testsetup.sh" + $ _p_datadir="${TESTDIR}/../share/local-bsdtools" + $ . "${_p_datadir}/farray.sh" + $ . "${_p_datadir}/common.subr" + $ . "${_p_datadir}/ports.subr" + + +Package Mapping +=============== + +init_package_mapping +-------------------- + + $ init_package_mapping PMAPPING + + +get_package_mapping +------------------- + +An empty database errors fatally + + $ (get_package_mapping '' whatever-package) + ERROR: missing falist name or token value + [70] + +Empty package name errors fatally + + $ (get_package_mapping PMAPPING) + /bin/sh: ERROR: missing package name + [64] + + $ get_package_mapping PMAPPING install-package + parent-package (no-eol) + +This is the target of the mapping + + $ get_package_mapping PMAPPING parent-package + [1] + +Another package + + $ get_package_mapping PMAPPING install-package-v2 + parent-package-v2 (no-eol) + +Commented out + + $ get_package_mapping PMAPPING install-package-v3 + [1] + + +Repositories +============ + +Assume that FreeBSD is always configured and enabled + + $ get_configured_pkg_repository_names | grep -F FreeBSD + FreeBSD + + +# Runtime much too long: need another strategy +# $ REPODB='' +# $ init_repositories REPODB
