Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
diff sbin/fports @ 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 | |
| children | 43cebff4ea0d |
line wrap: on
line diff
--- /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
