Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
view share/local-bsdtools/ports.subr @ 815:e2f262ec2bf4
Extend copyright year to 2025.
Because a new version will be released.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sat, 18 Jan 2025 16:34:56 +0100 |
| parents | 2310764e5c4e |
| children |
line wrap: on
line source
#!/bin/sh # -*- mode: shell-script; indent-tabs-mode: nil; -*- #: #: Helper functions for :command:`fports` and friends. #: #: :Author: Franz Glasner #: :Copyright: (c) 2017-2025 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 #: $2 (str, null): The jail from which to retrieve the package mapping #: configuration #: #: 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 _jail local _iname _mapped_package falist_create "$1" || return _mapping="$1" _jail="$2" if call_command "${_jail}" /bin/test -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 <<EOF_6969d915-b864-47bb-a0f9-70519b1be0e2 $(call_command "${_jail}" /bin/cat "${PACKAGE_MAPPING}") EOF_6969d915-b864-47bb-a0f9-70519b1be0e2 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. #: #: Args: #: $1 (str, null, optional): The jail from where to read the repositoriy #: configuration #: #: Output (stdout): #: Each configured and enabled repository name is printed on a single #: line. #: get_configured_pkg_repository_names() { # $1 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 <<EOF_73d43dccec1a496f98cb519be160f549 ${_line} EOF_73d43dccec1a496f98cb519be160f549 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 <<EOF_7c6ea1b0ce544021a7813757c7003392 $(call_pkg "${1-}" -vv) EOF_7c6ea1b0ce544021a7813757c7003392 } #: #: Create an array with all configured and active repository names. #: #: Args: #: $1 (str): The variable name where to store the array with the #: repository names. It must be released by the caller. #: $2 (str, null): The jail from where to read the repository #: configurations #: get_active_repositories() { # $1 $2 local repo farray_create "${1}" || return while IFS='' read -r repo; do farray_append "${1}" "${repo}" done <<EOF_b4e5385c-4c37-413b-b6f2-7909ac9eaa86 $(get_configured_pkg_repository_names "${2}") EOF_b4e5385c-4c37-413b-b6f2-7909ac9eaa86 } _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}" } #: #: Check whether a local index is available. #: #: The check follows largely the conventions of :manpage:`pkg-version(8)` #: where to check for a local index. #: #: Args: #: $1 (str, null): The jail in which to determine a local index file #: #: Returns: #: int: 0 if the index is available, 1 otherwise #: is_local_index_file_available() { # $1 local versrc indexdir indexfile versrc="$(call_pkg "${1}" config VERSION_SOURCE)" || fatal "${EX_UNAVAILABLE}" "cannot get VERSION_SOURCE configuration value" indexfile="$(call_pkg "${1}" config INDEXFILE)" || fatal "${EX_UNAVAILABLE}" "cannot get INDEXFILE configuration value" case "${versrc}" in ''|R) # XXX FIXME: handle R ("remote") really like default? indexdir="$(call_pkg "${1}" config INDEXDIR)" || fatal "${EX_UNAVAILABLE}" "cannot get INDEXDIR configuration value" call_command "${1}" /bin/test -r "${indexdir}/${indexfile}" && return 0 indexdir="$(call_pkg "${1}" config PORTSDIR)" || fatal "${EX_UNAVAILABLE}" "cannot get PORTSDIR configuration value" call_command "${1}" /bin/test -r "${indexdir}/${indexfile}" ;; I) indexdir="$(call_pkg "${1}" config INDEXDIR)" || fatal "${EX_UNAVAILABLE}" "cannot get INDEXDIR configuration value" call_command "${1}" /bin/test -r "${indexdir}/${indexfile}" ;; P) indexdir="$(call_pkg "${1}" config PORTSDIR)" || fatal "${EX_UNAVAILABLE}" "cannot get PORTSDIR configuration value" call_command "${1}" /bin/test -r "${indexdir}/${indexfile}" ;; *) fatal "${EX_SOFTWARE}" "unhandled value in VERSION_SOURCE: ${versrc}";; esac } #: #: Like `is_local_index_file_available` but also print the found index file. #: #: Args: #: $1 (str, null): The jail in which to determine a local index file #: #: Output (stdout): #: The found index file #: get_local_index_file() { # $1 local versrc indexdir indexfile versrc="$(call_pkg "${1}" config VERSION_SOURCE)" || fatal "${EX_UNAVAILABLE}" "cannot get VERSION_SOURCE configuration value" indexfile="$(call_pkg "${1}" config INDEXFILE)" || fatal "${EX_UNAVAILABLE}" "cannot get INDEXFILE configuration value" case "${versrc}" in ''|R) # XXX FIXME: handle R ("remote") really like default? indexdir="$(call_pkg "${1}" config INDEXDIR)" || fatal "${EX_UNAVAILABLE}" "cannot get INDEXDIR configuration value" if call_command "${1}" /bin/test -r "${indexdir}/${indexfile}" ; then printf '%s' "${indexdir}/${indexfile}" return 0 fi indexdir="$(call_pkg "${1}" config PORTSDIR)" || fatal "${EX_UNAVAILABLE}" "cannot get PORTSDIR configuration value" if call_command "${1}" /bin/test -r "${indexdir}/${indexfile}" ; then printf '%s' "${indexdir}/${indexfile}" return 0 fi ;; I) indexdir="$(call_pkg "${1}" config INDEXDIR)" || fatal "${EX_UNAVAILABLE}" "cannot get INDEXDIR configuration value" if call_command "${1}" /bin/test -r "${indexdir}/${indexfile}" ; then printf '%s' "${indexdir}/${indexfile}" return 0 fi ;; P) indexdir="$(call_pkg "${1}" config PORTSDIR)" || fatal "${EX_UNAVAILABLE}" "cannot get PORTSDIR configuration value" if call_command "${1}" /bin/test -r "${indexdir}/${indexfile}" ; then printf '%s' "${indexdir}/${indexfile}" return 0 fi ;; *) fatal "${EX_SOFTWARE}" "unhandled value in VERSION_SOURCE: ${versrc}" ;; esac return 1 } #: #: Parse a given index file for a package and yield its version. #: #: Args: #: $1 (str): An existing index file #: $2 (str): The package to search for #: $3 (str, null): The jail where `$1` lives #: #: Output (stdout): #: The package version if found, or a null string #: #: Returns: #: int: 0 if a matching package is found, 1 otherwise #: parse_index_file_for_package_version() { # $1 $2 $3 local pkgspec _rest _pathprefix _pathprefix='' if [ -n "${3}" ] ; then _pathprefix="$(LC_ALL=C.UTF-8 /usr/sbin/jls -j "${3}" path)" fi [ -r "${_pathprefix}${1}" ] || fatal "${EX_SOFTWARE}" "given index file \`${1}' is not readable (or does not exist)" # Using grep to pre-select with BREs is at least one magnitude slower while IFS='|' read -r pkgspec _rest; do if [ "${pkgspec%-*}" = "${2}" ]; then printf '%s' "${pkgspec##*-}" return 0 fi done <"${_pathprefix}${1}" return 1 }
