comparison sbin/fports @ 786:b78815b47d5e

fports: deptree has now an option to print a flattened tree. The flattened tree is the transitive closure of all dependencies.
author Franz Glasner <fzglas.hg@dom66.de>
date Tue, 29 Oct 2024 11:03:22 +0100
parents 43cebff4ea0d
children 004c676c3415
comparison
equal deleted inserted replaced
785:43cebff4ea0d 786:b78815b47d5e
62 62
63 #: 63 #:
64 #: Implementation of the "deptree" command. 64 #: Implementation of the "deptree" command.
65 #: 65 #:
66 command_deptree() { 66 command_deptree() {
67 local opt opt_reversed opt_maxlevel 67 local opt opt_reversed opt_maxlevel opt_flat
68 # $@ 68 # $@
69 69
70 opt_maxlevel=0 70 opt_maxlevel=0
71 opt_reversed=no 71 opt_reversed=no
72 while getopts "l:r" opt; do 72 opt_flat=no
73 while getopts "l:rt" opt; do
73 case "${opt}" in 74 case "${opt}" in
74 l) 75 l)
75 opt_maxlevel=$(($OPTARG + 0));; 76 opt_maxlevel=$(($OPTARG + 0));;
76 r) 77 r)
78 # shellcheck disable=SC2034
77 opt_reversed=yes;; 79 opt_reversed=yes;;
80 t)
81 opt_flat=yes;;
78 \?) 82 \?)
79 exit 2;; 83 exit 2;;
80 *) 84 *)
81 fatal 2 "option handling failed";; 85 fatal 2 "option handling failed";;
82 esac 86 esac
83 done 87 done
84 shift $((OPTIND-1)) 88 shift $((OPTIND-1))
85 OPTIND=1 89 OPTIND=1
86 90
87 if checkyesno opt_reversed; then 91 if checkyesno opt_reversed; then
88 _command_deptree_reversed "${opt_maxlevel}" "$@" 92 _command_deptree_reversed "${opt_maxlevel}" "${opt_flat}" "$@"
89 else 93 else
90 _command_deptree_normal "${opt_maxlevel}" "$@" 94 _command_deptree_normal "${opt_maxlevel}" "${opt_flat}" "$@"
91 fi 95 fi
92 } 96 }
93 97
94 98
95 #: 99 #:
96 #: Implementation of printing a "normal" dependency tree 100 #: Implementation of printing a "normal" dependency tree
97 #: 101 #:
98 _command_deptree_normal() { 102 _command_deptree_normal() {
99 local maxlevel # $@ 103 local maxlevel flat # $@
100 104
101 local pkgdeps pkgqueue curdeps pkg n v 105 local pkgdeps pkgqueue curdeps pkg n v flatdeps
102 106
103 maxlevel="${1}" 107 maxlevel="${1}"
104 shift 108 flat="${2}"
105 109 shift 2
110
106 # shellcheck disable=SC2034 # pkgqueue seems unused 111 # shellcheck disable=SC2034 # pkgqueue seems unused
107 pkgqueue='' 112 pkgqueue=''
108 farray_create pkgqueue # queue (array) of packages that are queued for 113 farray_create pkgqueue # queue (array) of packages that are queued for
109 # resolution 114 # resolution
110 115
111 for pkg in "$@"; do 116 for pkg in "$@"; do
112 if ! pkg query '%n' "${pkg}" 1>/dev/null 2>/dev/null ; then 117 if ! pkg query '%n' "${pkg}" 1>/dev/null 2>/dev/null ; then
113 farray_release pkgqueue 118 farray_release pkgqueue
114 fatal "${EX_DATAERR}" "Package not found: ${pkg}" 119 fatal "${EX_DATAERR}" "Package not found: ${pkg}"
115 fi 120 fi
124 while IFS=$' \t\n' read -r n v; do 129 while IFS=$' \t\n' read -r n v; do
125 [ -z "${n}" ] || [ -z "${v}" ] && continue 130 [ -z "${n}" ] || [ -z "${v}" ] && continue
126 farray_append curdeps "${n}=${v}" 131 farray_append curdeps "${n}=${v}"
127 farray_append pkgqueue "${n}" 132 farray_append pkgqueue "${n}"
128 done <<EOF_01a8cebe-8659-4e32-87a4-bbce117e386b 133 done <<EOF_01a8cebe-8659-4e32-87a4-bbce117e386b
129 $(LC_ALL=C.UTF-8 pkg query '%dn %dv' "${pkg}") 134 $(LC_ALL=C.UTF-8 pkg query '%dn %dv' "${pkg}")
130 EOF_01a8cebe-8659-4e32-87a4-bbce117e386b 135 EOF_01a8cebe-8659-4e32-87a4-bbce117e386b
131 falist_set pkgdeps "${pkg}" "${curdeps}" 136 falist_set pkgdeps "${pkg}" "${curdeps}"
132 farray_release curdeps 137 farray_release curdeps
133 curdeps='' 138 curdeps=''
134 fi 139 fi
135 done 140 done
136 farray_release pkgqueue 141 farray_release pkgqueue
137 # falist_debug pkgdeps 142 # falist_debug pkgdeps
138 for pkg in "$@"; do 143 if checkyesno flat; then
139 _print_dependency_tree 0 "${maxlevel}" '-->' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${pkgdeps}" 144 for pkg in "$@"; do
140 done 145 _flatten_pkgdeps flatdeps "${pkgdeps}" "${pkg}"
146 _print_flatdeps '-->' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${flatdeps}"
147 falist_release "${flatdeps}"
148 done
149 else
150 for pkg in "$@"; do
151 _print_dependency_tree 0 "${maxlevel}" '-->' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${pkgdeps}"
152 done
153 fi
141 falist_release pkgdeps 154 falist_release pkgdeps
142 } 155 }
143 156
144 157
145 #: 158 #:
146 #: Implementation of printing a reversed dependency tree 159 #: Implementation of printing a reversed dependency tree
147 #: 160 #:
148 _command_deptree_reversed() { 161 _command_deptree_reversed() {
149 local maxlevel # $@ 162 local maxlevel flat # $@
150 163
151 local pkgdeps pkgqueue curdeps pkg n v 164 local pkgdeps pkgqueue curdeps pkg n v flatdeps
152 165
153 maxlevel="${1}" 166 maxlevel="${1}"
154 shift 167 # shellcheck disable=SC2034 # appears unused
155 168 flat="${2}"
169 shift 2
170
156 # shellcheck disable=SC2034 # pkgqueue seems unused 171 # shellcheck disable=SC2034 # pkgqueue seems unused
157 pkgqueue='' 172 pkgqueue=''
158 farray_create pkgqueue # queue (array) of packages that are queued for 173 farray_create pkgqueue # queue (array) of packages that are queued for
159 # resolution 174 # resolution
160 175
161 for pkg in "$@"; do 176 for pkg in "$@"; do
162 if ! pkg query '%n' "${pkg}" 1>/dev/null 2>/dev/null ; then 177 if ! pkg query '%n' "${pkg}" 1>/dev/null 2>/dev/null ; then
163 farray_release pkgqueue 178 farray_release pkgqueue
164 fatal "${EX_DATAERR}" "Package not found: ${pkg}" 179 fatal "${EX_DATAERR}" "Package not found: ${pkg}"
165 fi 180 fi
174 while IFS=$' \t\n' read -r n v; do 189 while IFS=$' \t\n' read -r n v; do
175 [ -z "${n}" ] || [ -z "${v}" ] && continue 190 [ -z "${n}" ] || [ -z "${v}" ] && continue
176 farray_append curdeps "${n}=${v}" 191 farray_append curdeps "${n}=${v}"
177 farray_append pkgqueue "${n}" 192 farray_append pkgqueue "${n}"
178 done <<EOF_5079e996-c6d2-4e6d-825d-53183a64ab06 193 done <<EOF_5079e996-c6d2-4e6d-825d-53183a64ab06
179 $(LC_ALL=C.UTF-8 pkg query '%rn %rv' "${pkg}") 194 $(LC_ALL=C.UTF-8 pkg query '%rn %rv' "${pkg}")
180 EOF_5079e996-c6d2-4e6d-825d-53183a64ab06 195 EOF_5079e996-c6d2-4e6d-825d-53183a64ab06
181 falist_set pkgdeps "${pkg}" "${curdeps}" 196 falist_set pkgdeps "${pkg}" "${curdeps}"
182 farray_release curdeps 197 farray_release curdeps
183 curdeps='' 198 curdeps=''
184 fi 199 fi
185 done 200 done
186 farray_release pkgqueue 201 farray_release pkgqueue
187 # falist_debug pkgdeps 202 # falist_debug pkgdeps
188 for pkg in "$@"; do 203 if checkyesno flat; then
189 _print_dependency_tree 0 "${maxlevel}" '<--' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${pkgdeps}" 204 for pkg in "$@"; do
190 done 205 _flatten_pkgdeps flatdeps "${pkgdeps}" "${pkg}"
206 _print_flatdeps '<--' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${flatdeps}"
207 falist_release "${flatdeps}"
208 done
209 else
210 for pkg in "$@"; do
211 _print_dependency_tree 0 "${maxlevel}" '<--' "${pkg}" "$(LC_ALL=C.UTF-8 pkg query '%v' "${pkg}")" "${pkgdeps}"
212 done
213 fi
191 falist_release pkgdeps 214 falist_release pkgdeps
192 } 215 }
193 216
194 217
195 #: 218 #:
209 local i pkg ver curdeps 232 local i pkg ver curdeps
210 233
211 if [ "${2}" -ge 1 ]; then 234 if [ "${2}" -ge 1 ]; then
212 [ "${1}" -gt "${2}" ] && return 0 235 [ "${1}" -gt "${2}" ] && return 0
213 fi 236 fi
214 237
215 i="${1}" 238 i="${1}"
216 while [ "${i}" -gt 1 ]; do 239 while [ "${i}" -gt 1 ]; do
217 printf '%s' ' ' 240 printf '%s' ' '
218 i=$((i - 1)) 241 i=$((i - 1))
219 done 242 done
226 pkg="${pkg%%=*}" 249 pkg="${pkg%%=*}"
227 _print_dependency_tree $(($1 + 1)) "${2}" "${3}" "${pkg}" "${ver}" "${6}" 250 _print_dependency_tree $(($1 + 1)) "${2}" "${3}" "${pkg}" "${ver}" "${6}"
228 i=$((i + 1)) 251 i=$((i + 1))
229 done 252 done
230 farray_release curdeps 253 farray_release curdeps
254 }
255
256
257 #:
258 #: Args:
259 #: $1 (str): The package tag to use
260 #: $2 (str): The root package name
261 #: $3 (str): The package version of the root package in `$3`
262 #: $4 (alist): The alist of the flattened dependencies
263 #:
264 _print_flatdeps() {
265 # $1 $2 $3 $4
266
267 local pkgnames i n v
268
269 printf '%s v%s\n' "${2}" "${3}"
270
271 pkgnames=''
272 farray_create pkgnames
273 falist_keys pkgnames "$4"
274 farray_sort pkgnames
275 i=1
276 while farray_tryget n pkgnames "${i}"; do
277 falist_get v "${4}" "${n}"
278 printf '%s %s v%s\n' "${1}" "${n}" "${v}"
279 i=$((i + 1))
280 done
281
282 farray_release pkgnames
283 }
284
285
286 #:
287 #: Flatten a package dependency alist.
288 #:
289 #: Args:
290 #: $1 (str): The variable name where to store the flattened dependencies
291 #: into. This object (alist) must be released by the caller.
292 #: $2 (str): The alist with all packages and its dependencies
293 #: $3 (str): The package for which to flatten its dependencies
294 #:
295 _flatten_pkgdeps() {
296 local pkgdeps rootpkg # and $1
297
298 local alldeps queue pkg curdeps i depname depver
299
300 pkgdeps="${2}"
301 rootpkg="${3}"
302
303 falist_contains pkgdeps "${rootpkg}" || fatal "${EX_SOFTWARE}" "given package \`${rootpkg}' not in the given package dependency map"
304
305 # shellcheck disable=SC2034 # appears unused
306 queue=''
307 farray_create queue # array with package names to be flattened
308
309 farray_append queue "${rootpkg}"
310
311 alldeps=''
312 falist_create alldeps # alist with pkgname -> version
313 while farray_pop pkg queue 1; do
314 if ! falist_contains alldeps "${pkg}"; then
315 curdeps=''
316 falist_get curdeps pkgdeps "${pkg}"
317 i=1
318 while farray_tryget depname curdeps "${i}"; do
319 depver="${depname#*=}"
320 depname="${depname%%=*}"
321 if ! falist_contains alldeps "${depname}"; then
322 falist_set alldeps "${depname}" "${depver}"
323 fi
324 farray_append queue "${depname}"
325 i=$((i + 1))
326 done
327 farray_release curdeps
328 fi
329 done
330
331 farray_release queue
332
333 setvar "${1}" "${alldeps}"
231 } 334 }
232 335
233 336
234 # 337 #
235 # Global option handling 338 # Global option handling