Hello,
this time I wrote a dependency tree viewer.
Feel free to check it: comments are very welcome.
I especially would like to know how it should behave with packages which 
provide another one: I wrote part of the script thinking you couldn't install 
two packets providing the same one, but Allan proved me wrong.
At the moment the script is untested with multiple providers, but otherwise it 
works quite well.
The design choice of passing the directory instead of the packet name was ugly 
in the end, but I was fighting with the scoping in bash at the time, so I 
preferred to let things be; I might fix it.
Hope you like it.


I just noticed the ascii art failed me :(
-----------------------------SCRIPT----------------------------------
#!/bin/bash

# here you can set the colors
branch_color="\033[0;33m"     #Brown
leaf_color="\033[1;32m"       #Light green
leaf2_color="\033[0;32m"      #Green

# here you can set the separators
separator="   "
branch_tip="|--"
provides="provides "

########----------------END-OF-CONFIGURABLE-PART----------------#######

#   pactree : a simple dependency tree viewer
#
#   Copyright (c) 2008 Carlo "carlocci" Bersani <[EMAIL PROTECTED]>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# Original http://carlocci.ngi.it/arch/pactree


#######################################################################
# User friendly part                                                  #
#######################################################################
readonly prog_name="pactree"
readonly prog_ver="0.1"

_usage(){
        echo "This program generates the dependency tree of a package"
        echo "Usage:   $prog_name [OPTIONS] <installed packages>"
        echo 
        echo " OPTIONS:"
        echo "  -c, --color                Enable color output"
        echo "  -d, --depth INT            Limit the shown dependencies depth"
        echo "  -l, --linear               Enable linear output"
        echo "  -s, --silent               Shh, let me hear those errors!"
        echo "  -u, --unique                Print the dependency list with no 
duplicates"
        echo
        echo "  -h, --help                 Print this help message"
        echo "  -v, --version              Print the program name and version"
        echo
        echo "Example: $prog_name -c -d 2 readline"
}

_version(){
        echo "$prog_name version $prog_ver"
        echo "Copyright (C) 2008 locci"
}
# end of the friendliness


#######################################################################
# grab a field from the database: $1=path/to/file, $2=field to grab   #
#######################################################################
_grabfield(){
        for line in $(cat "$1" 2>/dev/null ); do
                if [ -z "$line" ]; then
                        continue;
                fi;
                if [[ "$line" =~ %[A-Z]*% ]]; then
                        current="$line"
                        continue;
                fi;
                if [ "$current" = "$2" ]; then
                        echo "$line"
                fi;
        done
}


#######################################################################
# Recursive function: does all of the work, pays all of the taxes     #
#######################################################################
_tree(){
        for i in $(_grabfield "$1/depends" %DEPENDS%); do
                pkg_dir="$1"
                spaces="$2"
                unset dep_pkg
                unset dep_pkg_provided

                # Generate the spacer
                spacer=""
                for each in $(seq 1 $spaces); do
                        spacer="$spacer$separator"
                done
                spacer="$spacer$branch_tip"

                dep_pkg="${i%%[<>=]*}"
                dep_dir="$(echo $pac_db/$dep_pkg-[0-9]*)"
                if [ ! -d "$dep_dir" ]; then    # Is $dep_pkg real or provided?

#START DOUBT
#AWK METHOD real 0m9.378s user 0m5.066s sys 0m2.083s
                        #black magic
                        dep_dir=$(awk '{ if ( $1 ~ /^%.*%$/ ) flag=0 ; if 
(flag==1) { if ($1 
~ /^'"$dep_pkg"'[<>=]*.*/ ) print FILENAME }; if ( $1=="%PROVIDES%" ) 
flag=1 ;}' $(find /var/lib/pacman/local -name depends))
                        dep_dir="${dep_dir%/*}"
                        dep_pkg_provided="$(_grabfield "$dep_dir/desc" %NAME%)"

#BASH METHOD real 0m28.461s user 0m10.229s sys 0m12.539s
#                       for file in $(find $pac_db -name depends); do
#                               for line in $(_grabfield "$file" %PROVIDES%); do
#                                       if [ $line = "$dep_pkg" ]; then
#                                               dep_dir="${file%/depends}"
#                                               dep_pkg_provided="$(_grabfield 
"$dep_dir/desc" %NAME%)"
#                                               break
#                                       fi
#                               done
#                               if [ $dep_pkg_provided ]; then
#                                       break
#                               fi
#                       done
#END DOUBT
                fi

                # Draws the tree
                if [ $silent -ne 1 ]; then
                        if [ "$dep_pkg_provided" ]; then
                                echo -e 
"$branch_color$spacer$leaf_color$dep_pkg_provided$leaf2_color 
$provides$leaf_color$dep_pkg"
                        else
                                echo -e 
"$branch_color$spacer$leaf_color$dep_pkg"
                        fi
                fi

                if [ ! -d "$dep_dir" ]; then
                        echo "No $dep_pkg in the database (inconsistent 
database?)" >&2
                fi
                
                # Checks for dups and depth
                if [[ ! "[EMAIL PROTECTED]" =~ $dep_pkg ]] && [ $spaces -ne 
$max_depth ]; then  
                        dep_list=( "[EMAIL PROTECTED]" 
"${dep_pkg_provided:-$dep_pkg}" )
                        _tree "$dep_dir" $((spaces+1))
                fi
        done
}



#######################################################################
# Main program: gets all of the money, pays none of the taxes         #
#######################################################################

# Command line parameters parser --------------------------------------
# ---------------------------------------------------------------------
if [ $# -eq 0 ]; then
        _usage
        exit 1
fi

options=( "$@" )
[EMAIL PROTECTED]
for (( n=0 ; n < $len_options ; n++ )); do
        if [ "${options[$n]}" = "--" ]; then
                unset options[$n]
                break
        fi
        if [ "${options[$n]}" = "-h" -o "${options[$n]}" = "--help" ]; then
                _usage
                exit 0 
        fi

        if [ "${options[$n]}" = "-v" -o "${options[$n]}" = "--version" ]; then
                _version
                exit 0
        fi

        if [ "${options[$n]}" = "-l" -o "${options[$n]}" = "--linear" ]; then
                unset options[$n]
                unset separator
                unset branch_tip
                unset provider
                linear=1
                continue
        fi

        if [ "${options[$n]}" = "-s" -o "${options[$n]}" = "--silent" ]; then
                unset options[$n]
                silent=1
                continue
        fi

        if [ "${options[$n]}" = "-u" -o "${options[$n]}" = "--unique" ]; then
                unset options[$n]
                silent=1
                nodup=1
                continue
        fi

        if [ "${options[$n]}" = "-c" -o "${options[$n]}" = "--color" ]; then
                unset options[$n]
                colored=1
                continue
        fi

        if [ "${options[$n]}" = "-d" -o "${options[$n]}" = "--depth" ]; then
                unset options[$n]
                if [[ ${options[$((n+1))]} =~ [[:digit:]]+ ]]; then
#               if [ ${options[$((n+1))]} -eq ${options[$((n+1))]} 2>/dev/null 
]; then
                        max_depth="${options[$((n+1))]}"
                        unset options[$((n+1))]
                        ((++n))
                fi
                continue
        fi
done
# End of the dumb command line parser ---------------------------------


# Env -----------------------------------------------------------------
# ---------------------------------------------------------------------
max_depth=${max_depth:--1}
linear=${linear:-0}
silent=${silent:-0}
nodup=${nodup:-0}

if [ ${colored:-0} -ne 1 ]; then
        unset branch_color
        unset leaf_color
        unset leaf2_color
fi

if [ ! -r /etc/pacman.conf ]; then
        echo "ERROR: unable to read /etc/pacman.conf"
        exit 1
else
        eval $(awk '/DBPath/ {print $1$2$3}' /etc/pacman.conf)
fi

pac_db="${DBPath:-/var/lib/pacman}/local"

if [ ! -d "$pac_db" ] ; then
        echo "ERROR: pacman database directory ${pac_db} not found"
        exit 1
fi
# Env End -------------------------------------------------------------


# Program starts ------------------------------------------------------
# ---------------------------------------------------------------------
for pkg_name in [EMAIL PROTECTED] ; do
        pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)"

        if [ ! -d "$pkg_dir" ] ; then
                echo "ERROR: package ${pkg_name} not found in pacman database"
                exit 1
        fi

        dep_list=( "$pkg_name" )
        [ $silent -ne 1 ] && echo -e 
"$branch_color$branch_tip$leaf_color$pkg_name"
  [ $max_depth -ne 0 ] && _tree $(echo "$pac_db/$pkg_name-[0-9]*") 1 
        [ $nodup -eq 1 ] && echo "[EMAIL PROTECTED]"
done
# Program Ends --------------------------------------------------------
 
# vim: set ts=2 sw=2 noet:

_______________________________________________
pacman-dev mailing list
[email protected]
http://archlinux.org/mailman/listinfo/pacman-dev

Reply via email to