Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
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 |
