depends: find-like output

when dealing with package dependency woes, such as

http://cygwin.com/ml/cygwin/2014-10/msg00563.html

The current "depends" tree method fails, because it only shows the packages, not
the dependency paths. These paths are necessary to solve the "shortest path
problem"

http://wikipedia.org/wiki/Shortest_path_problem

Now, every possible dependency path will print from the chosen package. Combined
with category search you can run searches such as

    apt-cyg category Base |
    apt-cyg depends |
    awk '/perl$/ {print length,$0}' |
    sort -n

Solving the path problem in seconds.
This commit is contained in:
Steven Penny 2014-11-11 03:15:24 -06:00
parent 2138f54544
commit e9bea37b95
1 changed files with 21 additions and 33 deletions

54
apt-cyg
View File

@ -150,8 +150,7 @@ function apt-category {
pck = $2 pck = $2
} }
$1 == "category:" && $0 ~ query { $1 == "category:" && $0 ~ query {
$1 = "" print pck
printf "%-25s%s\n", pck, $0
} }
' query="$pks" setup.ini ' query="$pks" setup.ini
done done
@ -213,46 +212,33 @@ function apt-depends {
check-packages check-packages
for pkg in "${pks[@]}" for pkg in "${pks[@]}"
do do
(( sq++ )) && echo
awk ' awk '
@include "join"
$1 == "@" { $1 == "@" {
pkg = $2 apg = $2
} }
$1 == "requires:" { $1 == "requires:" {
for (i=2; i<=NF; i++) for (z=2; z<=NF; z++)
reqs[pkg][i-1]=$i reqs[apg][z-1] = $z
} }
END { END {
setMinDepth(query) prpg(ENVIRON["pkg"])
prtPkg(query)
} }
function prtPkg(pkg, req, i) { function smartmatch(small, large, values) {
depth++ for (each in large)
if ( depth == mn[pkg] && !seen[pkg]++ ) { values[large[each]]
printf "%*s%s\n", indent, "", pkg return small in values
indent += 2
if (pkg in reqs)
for (i=1; i in reqs[pkg]; i++) {
req = reqs[pkg][i]
prtPkg(req)
}
indent -= 2
}
depth--
} }
function setMinDepth(pkg, req, i) { function prpg(fpg) {
depth++ if (smartmatch(fpg, spath)) return
mn[pkg] = !(pkg in mn) || depth < mn[pkg] ? depth : mn[pkg] spath[length(spath)+1] = fpg
if (depth == mn[pkg]) { print join(spath, 1, length(spath))
if (pkg in reqs) if (isarray(reqs[fpg]))
for (i=1; i in reqs[pkg]; i++) { for (each in reqs[fpg])
req = reqs[pkg][i] prpg(reqs[fpg][each])
setMinDepth(req) delete spath[length(spath)]
}
}
depth--
} }
' query="$pkg" setup.ini ' setup.ini
done done
} }
@ -595,6 +581,8 @@ do
esac esac
done done
set -a
if type -t apt-$command | grep -q function if type -t apt-$command | grep -q function
then then
apt-$command apt-$command