2 # pactree : a simple dependency tree viewer
4 # Copyright (C) 2008 Carlo "carlocci" Bersani <carlocci@gmail.com>
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # Original http://carlocci.ngi.it/arch/pactree
20 # Credit to scj for the graphviz idea
23 branch1_color
="\033[0;33m" #Brown
24 branch2_color
="\033[0;37m" #Gray
25 leaf_color
="\033[1;32m" #Light green
26 leaf2_color
="\033[0;32m" #Green
34 # set the graphviz options
35 # http://www.graphviz.org/doc/info/output.html for available output formats
36 # http://www.graphviz.org/doc/info/colors.html for available colors
37 gformat
="png" #output format
38 start_color
="red" #START color
39 nodes_color
="green" #color of the nodes
40 arrow1_color
="chocolate4" #color of the normal arrow
41 arrow2_color
="grey" #color of the "provided by" headless arrow
43 readonly prog_name
="pactree"
44 readonly prog_ver
="0.2"
47 echo "This program generates the dependency tree of an installed package"
48 echo "Usage: $prog_name [OPTIONS] <installed packages>"
51 echo " -c, --color Enable color output"
52 echo " -d, --depth INT Limit the shown dependencies depth"
53 echo " -g, --graph Use graphviz to make an image of the tree"
54 echo " -l, --linear Enable linear output"
55 echo " -s, --silent Shh, let me hear those errors!"
56 echo " -u, --unique Print the dependency list with no duplicates"
58 echo " -h, --help Print this help message"
59 echo " -v, --version Print the program name and version"
61 echo "Example: $prog_name -c -d 2 readline"
65 echo "$prog_name version $prog_ver"
66 echo "Copyright (C) 2008 Carlo \"carlocci\" Bersani <carlocci@gmail.com>"
68 # end of the friendliness
71 # grab a field from the database: $1=path/to/file, $2=field to grab
73 for line
in $
(cat "$1" 2>/dev
/null
); do
74 if [ -z "$line" ]; then
77 if [[ "$line" =~
%[A-Z
]*% ]]; then
81 if [ "$current" = "$2" ]; then
88 # find a dep in the db: $1=dep, $2=field, $3=dbfile, ret=file list
90 for line
in $
(awk 'BEGIN{RS=""}
93 for (i=2 ; i<=NF ; ++i){
94 if ($i ~ /^'"$1"'([<>=]+.*|)$/ ){
98 }' $
(find $pac_db -name $3)); do
104 # Recursive function: does all of the work, pays all of the taxes #
107 pkg_dirs
="$(echo $pac_db/$pkg_name-[0-9]*)"
109 # Is $pkg_name real or provided?
110 [ ! -d "$pkg_dirs" ] && pkg_dirs
="$(_finddep $pkg_name %PROVIDES% depends)"
112 for pkg_dir
in $pkg_dirs ; do
115 branch_tip
="$branch_tip1"
116 branch_color
="$branch1_color"
117 pkg_name
="$(_grabfield "$pkg_dir/desc
" %NAME%)"
118 if [ ! "$pkg_name" = "$1" ]; then
119 provided
="$leaf2_color $provides$leaf_color$1"
120 branch_tip
="$branch_tip2"
121 branch_color
="$branch2_color"
122 if [ $graphviz -eq 1 ] && [[ ! "${dep_list[@]}" =~ _
$1_ ]] && [ $spaces -ne $
((max_depth
+1)) ]; then
123 echo "\"$1\" -> \"$pkg_name\" [arrowhead=none, color=$arrow2_color];"
124 dep_list
=( "${dep_list[@]}" "_$1_" )
125 _tree
"$pkg_name" $
((spaces
+1))
130 # Generate the spacer
132 for each
in $
(seq 1 $spaces); do
133 spacer
="$spacer$separator"
135 spacer
="$spacer$branch_tip"
137 [ $silent -ne 1 ] && echo -e "$branch_color$spacer$leaf_color$pkg_name$provided"
139 [ ! -d "$pkg_dir" ] && echo "No $pkg_name in the database (inconsistent database?)" >&2
141 if [[ ! " ${dep_list[@]} " =~
" $pkg_name " ]] && [ $spaces -ne $max_depth ]; then
142 dep_list
=( "${dep_list[@]}" "$pkg_name" )
143 for dep_pkg
in $
(_grabfield
"$pkg_dir/depends" %DEPENDS
%); do
144 spaces
=$2 #Bash scoping ;_;
145 if [ $graphviz -eq 1 ]; then
146 echo "\"$1\" -> \"${dep_pkg%%[<>=]*}\" [color=$arrow1_color];"
148 _tree
"${dep_pkg%%[<>=]*}" $
((spaces
+1))
155 # Main program: gets all of the money, pays none of the taxes
157 # Command line parameters parser
158 if [ $# -eq 0 ]; then
164 len_options
=${#options[@]}
165 for (( n
=0 ; n
< $len_options ; n
++ )); do
166 if [ "${options[$n]}" = "--" ]; then
170 if [ "${options[$n]}" = "-h" -o "${options[$n]}" = "--help" ]; then
175 if [ "${options[$n]}" = "-v" -o "${options[$n]}" = "--version" ]; then
180 if [ "${options[$n]}" = "-l" -o "${options[$n]}" = "--linear" ]; then
186 if [ "${options[$n]}" = "-s" -o "${options[$n]}" = "--silent" ]; then
192 if [ "${options[$n]}" = "-u" -o "${options[$n]}" = "--unique" ]; then
199 if [ "${options[$n]}" = "-g" -o "${options[$n]}" = "--graph" ]; then
205 if [ "${options[$n]}" = "-c" -o "${options[$n]}" = "--color" ]; then
211 if [[ "${options[$n]}" =~
-d[[:digit
:]]+ ||
"${options[$n]}" == "--depth" ]]; then
212 if [[ "${options[$n]#-d}" =~
[[:digit
:]]+ ]]; then
213 max_depth
="${options[$n]#-d}"
214 elif [[ ${options[$((n+1))]} =~
[[:digit
:]]+ ]]; then
215 max_depth
="${options[$((n+1))]}"
216 unset options
[$
((n
+1))]
223 # End of the dumb command line parser
226 colored
=${colored:-0}
227 max_depth
=${max_depth:--10}
231 graphviz
=${graphviz:-0}
233 if [ $colored -ne 1 ]; then
240 if [ $linear -eq 1 ]; then
247 if [ $graphviz -eq 1 ]; then
250 if [ ! -f /usr
/bin
/dot
]; then
251 echo "ERROR: package graphviz is not installed"
252 echo " Run pacman -S graphviz to install it"
257 if [ ! -r /etc
/pacman.conf
]; then
258 echo "ERROR: unable to read /etc/pacman.conf"
261 eval $
(awk '/DBPath/ {print $1$2$3}' /etc
/pacman.conf
)
264 pac_db
="${DBPath:-/var/lib/pacman}/local"
266 if [ ! -d "$pac_db" ] ; then
267 echo "ERROR: pacman database directory ${pac_db} not found"
275 for pkg_name
in ${options[@]} ; do
276 [ $graphviz -eq 1 ] && echo -e "\"START\" -> \"$pkg_name\" ;"
278 if [ $nodup -eq 1 ]; then
279 for pkg_tree
in ${dep_list[@]} ; do
284 if [ $silent -eq 0 ]; then
285 echo -ne '\033[0m' # return colors to normal?
286 echo -ne '\033[?25h' #return cursor to normal?
291 if [ $graphviz -eq 1 ]; then
292 root_pkgs
="${options[@]}"
293 # Uncomment for the "generated by pactree" node in graphviz
294 #advert="xyz [height=0.07, fontsize=8.0, label=\"GENERATED WITH PACTREE\",shape=box,color="black",style=filled,fontcolor="white"];\n"
296 echo -e "digraph G { START [color=$start_color, style=filled];\n node [style=filled, color=$nodes_color];\n$(_main)\n$advert}" | dot
-T$gformat -o "${root_pkgs// /_}.deps.$gformat"
300 # vim: set ts=2 sw=2 noet: