Skip to content

Instantly share code, notes, and snippets.

@damphat
Last active December 12, 2024 00:02
Show Gist options
  • Save damphat/6214499 to your computer and use it in GitHub Desktop.
Save damphat/6214499 to your computer and use it in GitHub Desktop.
debian dependency tree
#! /bin/bash
# Description: show dependency tree
# Author: damphat
if [ $# != 1 ]; then
echo 'Usage: apt-rdepends-tree <package>'
echo 'Required packages: apt-rdepends'
exit 1
fi
# tree template
T1=" ├─"
T2=" │ ├─"
T3=" │ └─"
# tree template for last node
T4=" └─"
T5=" ├─"
T6=" └─"
# mark '1' for parent node, '2' for child node
TEXT="$(apt-rdepends $1 | sed -e 's/^/1 /' -e 's/.*: /2 /'; echo '-')"
TOTAL=$(echo "$TEXT" | grep '^1' | wc -l) # total parent
COUNT=0
echo "$TEXT" | while read line; do
tmp=$last
[ "${line:0:1}" != "${last:0:1}" ] && tmp=$(echo $last | sed -e 's/^2/3/')
[ "${tmp:0:1}" == "1" ] && ((COUNT++))
if [ "$TOTAL" != "$COUNT" ]; then
echo $tmp | sed -e "s/^1/$T1/" -e "s/^2/$T2/" -e "s/^3/$T3/"
else
echo $tmp | sed -e "s/^1/$T4/" -e "s/^2/$T5/" -e "s/^3/$T6/"
fi
last=$line
done
@willemw12
Copy link

If you allow for more apt-rdepends options (for example, ' apt-rdepends "$@" '), then you can also, for example, display a reverse dependency tree (' apt-rdepends-tree -r ').

@sr105
Copy link

sr105 commented Dec 17, 2014

@vitiral
Copy link

vitiral commented Mar 17, 2015

this is fantastic! Exactly what I was looking for, thanks a ton :D

@acx2015
Copy link

acx2015 commented Dec 4, 2015

+1 very nice! Thanks for writing this and posting on SO!

@dmak
Copy link

dmak commented Sep 5, 2018

Would be nice to have an option to suppress (filter out) dependencies which are already listed above, e.g.

    ├─ libexpat1
    │    └─ libc6 (>= 2.4)
    └─ libpcre2-8-0
         └─ libc6 (>= 2.4)

turns into:

    ├─ libexpat1
    │    └─ libc6 (>= 2.4)
    └─ libpcre2-8-0

@completementgaga
Copy link

If I understand well, actually we only get the tree up to depth 2. It would be cool to get it up to any arbitrary depth.

@MestreLion
Copy link

If I understand well, actually we only get the tree up to depth 2. It would be cool to get it up to any arbitrary depth.

That limitation stems from apt-rdepends output format, as unfortunately it does not nest packages but rather shows each dependency as a top-level package. Fixing this would be non-trivial for such a simple (but amazing) bash script

@MestreLion
Copy link

What an amazing script!

Inspired by this I've created apt-tree, featuring:

  • Arbitrary depth, as suggested by @completementgaga , taking care to handle circular dependencies (yes, they exist! See libc6)
  • Suppress duplicate sub-trees, as suggested by @dmak . Packages already printed are marked with *
  • Pass through options to apt-rdepends, to allow -r|--reverse as requested by @willemw12 (among many other possibilities)
  • Full command-line argument parsing, including --help

A small example:

$ apt-tree p7zip-full
Reading package lists... Done
Building dependency tree       
Reading state information... Done
p7zip-full
 ├─ libc6
 │   ╰─ libgcc1
 │       ├─ gcc-8-base
 │       ╰─ libc6*
 ├─ libgcc1*
 ├─ libstdc++6
 │   ├─ gcc-8-base*
 │   ├─ libc6*
 │   ╰─ libgcc1*
 ╰─ p7zip
     ├─ libc6*
     ├─ libgcc1*
     ╰─ libstdc++6*

@hiddenman
Copy link

@MestreLion
Hi, Very nice script, thank you. The only missed things we strongly need are:

  1. Include build-depends for packages, not only Depends
  2. Mark somehow those packages which are not available (using apt-cache maybe). For example, if "gcc-8-base" is missed in the local apt repository, then show this something like gcc-8-base (-), those which exist, mark as (+)
  3. Print this graph as a plain-text to be able to iterator over it and build each package from the list

Will try to implement this by myself. May be you consider implementing this :)

@MestreLion
Copy link

MestreLion commented Dec 12, 2024

MestreLion Hi, Very nice script, thank you. The only missed things we strongly need are:

Thanks @hiddenman , glad you liked!
Currently I'm unable to dive into this, but I can share a few thoughts about each, it may help:

  1. Include build-depends for packages, not only Depends

Is there a such an option in apt-rdepends? If so, this is possible.

Also, I believe it should either print the build-depends OR the Depends (controllable by a new --build-depends flag), as there are very few (if any) use-cases for a combined list including both. And whoever needs both can always run it twice, with and without the flag.

  1. Mark somehow those packages which are not available (using apt-cache maybe). For example, if "gcc-8-base" is missed in the local apt repository, then show this something like gcc-8-base (-), those which exist, mark as (+)

This might be feasible, possibly best done in parse_deps(). I suggest the mark be (!) for not available, and no mark if available.

  1. Print this graph as a plain-text to be able to iterator over it and build each package from the list

A new --plain flag can easily do that, perhaps using tr -d to remove the UTF (and whitespace?) characters. Indentation can be replaced with TABs, or completely stripped if --no-indent, which would imply --plain.

Will try to implement this by myself. May be you consider implementing this :)

I will. And if you do, it would be amazing if you could open a PR in my repo!!!
(you can also open a new issue there so we can best discuss the above points instead of polluting the this gist)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment