comparison 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
comparison
equal deleted inserted replaced
769:03350d2a2af6 770:56ab5c012d5f
1 #!/bin/sh
2 # -*- indent-tabs-mode: nil; -*-
3 #:
4 #: Check the version status of installed ports and compare them to
5 #: version in remote repositories and the local ports index.
6 #:
7 #: :Author: Franz Glasner
8 #: :Copyright: (c) 2017-2024 Franz Glasner.
9 #: All rights reserved.
10 #: :License: BSD 3-Clause "New" or "Revised" License.
11 #: See LICENSE for details.
12 #: If you cannot find LICENSE see
13 #: <https://opensource.org/licenses/BSD-3-Clause>
14 #: :ID: @(#)@@SIMPLEVERSIONTAG@@
15 #:
16
17 : # separator for shellcheck: no module-level directives below
18
19 # shellcheck disable=SC2034 # VERSION appears unused
20 VERSION='@@VERSION@@'
21
22 # shellcheck disable=SC2016 # no expansion
23 USAGE='
24 USAGE: fports [ GLOBAL-OPTIONS ] COMMAND [ COMMAND-OPTIONS ]
25
26 GLOBAL OPTIONS:
27
28 -V Print the program name and version number to stdout and exit
29
30 -h Print this help message to stdout and exit
31
32 '
33
34
35 _p_datadir='@@DATADIR@@'
36 [ "${_p_datadir#@@DATADIR}" = '@@' ] && _p_datadir="$(dirname "$0")"/../share/local-bsdtools
37 . "${_p_datadir}/common.subr"
38 . "${_p_datadir}/farray.sh"
39 . "${_p_datadir}/ports.subr"
40
41
42 #:
43 #: Configuration directory.
44 #:
45 : "${CONFIGDIR:=@@ETCDIR@@}"
46
47 #:
48 #: Mapping configuration: installed package name -> original package name.
49 #:
50 #: Note:
51 #: This is independent of any repo
52 #
53 : "${PACKAGE_MAPPING:=${CONFIGDIR}/package-mapping.conf}"
54
55 # shellcheck disable=SC1091 # does not exist -- cannot read
56 [ -r "${CONFIGDIR}/pkgtools.conf" ] && . "${CONFIGDIR}/pkgtools.conf"
57
58
59 # no unset variables
60 set -u
61
62
63 #:
64 #: Implementation of the "deptree" command.
65 #:
66 command_deptree() {
67 local opt opt_reversed opt_maxlevel
68 # $@
69
70 opt_maxlevel=0
71 opt_reversed=no
72 while getopts "l:r" opt; do
73 case "${opt}" in
74 l)
75 opt_maxlevel=$(($OPTARG + 0));;
76 r)
77 opt_reversed=yes;;
78 \?)
79 exit 2;;
80 *)
81 fatal 2 "option handling failed";;
82 esac
83 done
84 shift $((OPTIND-1))
85 OPTIND=1
86
87 if checkyesno opt_reversed; then
88 _command_deptree_reversed "${opt_maxlevel}" "$@"
89 else
90 _command_deptree_normal "${opt_maxlevel}" "$@"
91 fi
92 }
93
94
95 #:
96 #: Implementation of printing a "normal" dependency tree
97 #:
98 _command_deptree_normal() {
99 local maxlevel # $@
100
101 local pkgdeps pkgqueue curdeps pkg n v
102
103 maxlevel="${1}"
104 shift
105
106 # shellcheck disable=SC2034 # pkgqueue seems unused
107 pkgqueue=''
108 farray_create pkgqueue # queue (array) of packages that are queued for
109 # resolution
110
111 for pkg in "$@"; do
112 if ! pkg query '%n' "${pkg}" 1>/dev/null 2>/dev/null ; then
113 farray_release pkgqueue
114 fatal "${EX_DATAERR}" "Package not found: ${pkg}"
115 fi
116 farray_append pkgqueue "${pkg}"
117 done
118 pkgdeps=''
119 falist_create pkgdeps # alist of packagges with its direct dependencies
120 while farray_pop pkg pkgqueue 1; do
121 if ! falist_contains pkgdeps "${pkg}"; then
122 curdeps=''
123 farray_create curdeps
124 while IFS=$' \t\n' read -r n v; do
125 [ -z "${n}" ] || [ -z "${v}" ] && continue
126 farray_append curdeps "${n}=${v}"
127 farray_append pkgqueue "${n}"
128 done <<EOF_01a8cebe-8659-4e32-87a4-bbce117e386b
129 $(LC_ALL=C.UTF-8 pkg query '%dn %dv' "${pkg}")
130 EOF_01a8cebe-8659-4e32-87a4-bbce117e386b
131 falist_set pkgdeps "${pkg}" "${curdeps}"
132 farray_release curdeps
133 curdeps=''
134 fi
135 done
136 farray_release pkgqueue
137 # falist_debug pkgdeps
138 for pkg in "$@"; do
139 _print_dependency_tree 0 "${maxlevel}" '-->' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${pkgdeps}"
140 done
141 falist_release pkgdeps
142 }
143
144
145 #:
146 #: Implementation of printing a reversed dependency tree
147 #:
148 _command_deptree_reversed() {
149 local maxlevel # $@
150
151 local pkgdeps pkgqueue curdeps pkg n v
152
153 maxlevel="${1}"
154 shift
155
156 # shellcheck disable=SC2034 # pkgqueue seems unused
157 pkgqueue=''
158 farray_create pkgqueue # queue (array) of packages that are queued for
159 # resolution
160
161 for pkg in "$@"; do
162 if ! pkg query '%n' "${pkg}" 1>/dev/null 2>/dev/null ; then
163 farray_release pkgqueue
164 fatal "${EX_DATAERR}" "Package not found: ${pkg}"
165 fi
166 farray_append pkgqueue "${pkg}"
167 done
168 pkgdeps=''
169 falist_create pkgdeps # alist of packagges with its direct dependencies
170 while farray_pop pkg pkgqueue 1; do
171 if ! falist_contains pkgdeps "${pkg}"; then
172 curdeps=''
173 farray_create curdeps
174 while IFS=$' \t\n' read -r n v; do
175 [ -z "${n}" ] || [ -z "${v}" ] && continue
176 farray_append curdeps "${n}=${v}"
177 farray_append pkgqueue "${n}"
178 done <<EOF_5079e996-c6d2-4e6d-825d-53183a64ab06
179 $(LC_ALL=C.UTF-8 pkg query '%rn %rv' "${pkg}")
180 EOF_5079e996-c6d2-4e6d-825d-53183a64ab06
181 falist_set pkgdeps "${pkg}" "${curdeps}"
182 farray_release curdeps
183 curdeps=''
184 fi
185 done
186 farray_release pkgqueue
187 # falist_debug pkgdeps
188 for pkg in "$@"; do
189 _print_dependency_tree 0 "${maxlevel}" '<--' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${pkgdeps}"
190 done
191 falist_release pkgdeps
192 }
193
194
195 #:
196 #: Internal helper to print an indented dependency list for a package.
197 #:
198 #: Args:
199 #: $1 (int): The (indentation) level where a level of `0` is the root level
200 #: $2 (int): The maximum level (`$1`) to print to
201 #: $3 (str): The package tag to use to for non-root-levels
202 #: $4 (str): The package name
203 #: $5 (str): The package version
204 #: $6 (alist): The llist of resolved packages and their dependencies
205 #:
206 _print_dependency_tree() {
207 # $1 $2 $3 $4 $5 $6
208
209 local i pkg ver curdeps
210
211 if [ "${2}" -ge 1 ]; then
212 [ "${1}" -gt "${2}" ] && return 0
213 fi
214
215 i="${1}"
216 while [ "${i}" -gt 1 ]; do
217 printf '%s' ' '
218 i=$((i - 1))
219 done
220 [ "${1}" -ne 0 ] && printf '%s ' "${3}"
221 printf '%s v%s\n' "${4}" "${5}"
222 falist_get curdeps "${6}" "${pkg}"
223 i=1
224 while farray_tryget pkg "${curdeps}" "${i}"; do
225 ver="${pkg#*=}"
226 pkg="${pkg%%=*}"
227 _print_dependency_tree $(($1 + 1)) "${2}" "${3}" "${pkg}" "${ver}" "${6}"
228 i=$((i + 1))
229 done
230 farray_release curdeps
231 }
232
233
234 #
235 # Global option handling
236 #
237 while getopts "Vh" _opt ; do
238 case "${_opt}" in
239 V)
240 printf 'fports %s\n' '@@SIMPLEVERSIONSTR@@'
241 exit 0
242 ;;
243 h)
244 echo "${USAGE}"
245 exit 0
246 ;;
247 \?)
248 exit 2;
249 ;;
250 *)
251 fatal 2 "option handling failed"
252 ;;
253 esac
254 done
255
256 #
257 # Reset the Shell's option handling system to prepare for handling
258 # command-local options.
259 #
260 shift $((OPTIND-1))
261 OPTIND=1
262
263 command="${1-}"
264 shift
265
266 case "${command}" in
267 '') fatal 2 "no command given";;
268 deptree)
269 command_deptree "$@";;
270 *)
271 fatal 2 "unknown command \`${command}'";;
272 esac