Class dependency graph generation - Westhoffswelt - Welcome to the real world

Class dependency generation

I have written a small script to generate class dependency graphs out of a bunch of php files last week. I needed this for a project I am currently working on.

First of all I want to publish this script, free to use for anybody to whom this might be useful. You can get the complete script at the end of this post.

I have been told that doxygen can create something similar to my graphs. This graphs didn't completey satisfy me, but you can take a look there, if you aren't happy with the representation my script generates.

After the script did what I wanted it to, I decided to create classgraphs of the ez Components just for fun. After looking on some of these I realized that they might be useful or at least quite interesting to other people around the net.

Classgraph example run over the eZ components (Cutout)Classgraph example run over the eZ components (Cutout)

Classgraphs of the current ez Components trunk can be found here.

If you are interested in the scripts that generate this graphs just checkout its svn repository: svn://svn.pureenergy.cc/ezc_class_graph

There you will find a slightly modified version of the mentioned script, which will create the shown graphs for you based on the current ezc trunk.

Download

Trackbacks

  • Class dependency graph generation - Update on Fri, 30 Jan 2009 01:47:01 +0100 in Westhoffswelt - Welcome to the real world

    Just a little update to the class dependency generation script to fix some incompatabilities. Now everything should work flawlessly

Comments

  • Andrew Cobby on Thu, 17 Feb 2011 23:38:37 +0100

    My graphs only have Exception class and nothing else.

    Does it work with PHP 5.3 (and Namespaces)?

  • Piccolino81 on Wed, 20 Jul 2011 14:06:26 +0200

    On my iMac (Mac OS X 10.6.8) I had to change the 'sed' commands a little...

    ...good luck :-)


    #==============================================================================
    #!/bin/bash
    #
    # Usage: script.sh <name> <classprefix> <directory>
    #
    # Mandatory graph configuration
    #
    GRAPHTYPE=svg
    GRAPH=$1.svg
    CLASSES=$3
    CLASS_PREFIX=$2
    TMPFILE=classgraph.dot

    #
    # Optional graph configuration
    #
    CLASS_FONTSIZE=14
    CLASS_FONTCOLOR=dodgerblue4
    CLASS_BORDERCOLOR=dodgerblue1
    CLASS_SHAPE=ellipse
    CLASS_FONTNAME=Times-Roman

    INTERFACE_FONTSIZE=14
    INTERFACE_FONTCOLOR=darkorange3
    INTERFACE_BORDERCOLOR=darkorange1
    INTERFACE_SHAPE=box
    INTERFACE_FONTNAME=Times-Roman

    CLASS_INHERITANCE_COLOR=steelblue4
    INTERFACE_INHERITANCE_COLOR=firebrick3
    IMPLEMENTS_COLOR=tan2

    RANK_DISTANCE=1.0


    #
    # Graph generation
    #
    rm $TMPFILE 2>/dev/null

    # Check for svg output and correct some font bugs
    if [ "$GRAPHTYPE" = "svg" ]; then
    ORIG_CLASS_FONTSIZE=$CLASS_FONTSIZE
    ORIG_INTERFACE_FONTSIZE=$INTERFACE_FONTSIZE
    let CLASS_FONTSIZE=$CLASS_FONTSIZE+10
    let INTERFACE_FONTSIZE=$INTERFACE_FONTSIZE+10
    fi

    # Start the graph
    echo "digraph class_structure {" >>$TMPFILE

    # Set the rank distance
    echo "ranksep=$RANK_DISTANCE" >>$TMPFILE

    # Set standard node look and feel
    echo "node [fontsize=\"$CLASS_FONTSIZE\"]" >>$TMPFILE

    # Create a configured node for every class
    echo "Creating node for every class."
    for i in `find $CLASSES -iname "*.php"`; do grep "class $CLASS_PREFIX" "$i" | sed -e "s@^.*class \\($CLASS_PREFIX[a-zA-Z0-9_]*\\).*\$@\\1 [fontsize=\"$CLASS_FONTSIZE\", fontcolor=\"$CLASS_FONTCOLOR\", color=\"$CLASS_BORDERCOLOR\", shape=\"$CLASS_SHAPE\", fontname=\"$CLASS_FONTNAME\"]@" >>$TMPFILE; done

    # Create a configured node for the "Exception" class
    echo "Exception [fontsize="$CLASS_FONTSIZE", fontcolor=\"$CLASS_FONTCOLOR\", color=\"$CLASS_BORDERCOLOR\", shape=\"$CLASS_SHAPE\", fontname=\"$CLASS_FONTNAME\"]" >>$TMPFILE

    # Create a configured node for every interface
    echo "Creating node for every interface."
    for i in `find $CLASSES -iname "*.php"`; do grep "interface $CLASS_PREFIX" "$i" | sed -e "s@^.*interface \\($CLASS_PREFIX[a-zA-Z0-9_]*\\).*\$@\1 [fontsize="$INTERFACE_FONTSIZE", fontcolor=\"$INTERFACE_FONTCOLOR\", color=\"$INTERFACE_BORDERCOLOR\", shape=\"$INTERFACE_SHAPE\", fontname=\"$INTERFACE_FONTNAME\"]@" >>$TMPFILE; done

    # Create edges for class inheritance
    echo "Creating class inheritance edges."
    for i in `find $CLASSES -iname "*.php"`;
    do
    grep "class $CLASS_PREFIX" "$i" |
    grep "extends" |
    ### sed -e "s@^.*class \\($CLASS_PREFIX[a-zA-Z0-9_]*\\).*extends \\([a-zA-Z0-9_]\\+\\).*\$@\\2->\\1 [dir=back, color=\"$CLASS_INHERITANCE_COLOR\"]@" >>$TMPFILE;
    sed -e "s/class \($CLASS_PREFIX[a-zA-Z0-9_]*\).*extends \($CLASS_PREFIX[a-zA-Z0-9_]*\)/\2 -> \1 [dir=back, color=\"$CLASS_INHERITANCE_COLOR\"]/" >>$TMPFILE;
    done

    # Create edges for interface inheritance
    echo "Creating interface inheritance edges."
    for i in `find $CLASSES -iname "*.php"`;
    do
    grep "interface $CLASS_PREFIX" "$i" |
    grep "extends" |
    ### sed -e "s@^.*interface \\($CLASS_PREFIX[a-zA-Z0-9_]*\\).*extends \\([a-zA-Z0-9_]\\+\\).*\$@\\2->\\1 [dir=back, color=\"$INTERFACE_INHERITANCE_COLOR\"]@" >>$TMPFILE;
    sed -e "s/interface \($CLASS_PREFIX[a-zA-Z0-9_]*\).*extends \($CLASS_PREFIX[a-zA-Z0-9_]*\).*/\2 -> \1 [dir=back, color=\"$INTERFACE_INHERITANCE_COLOR\"]/" >>$TMPFILE;
    done

    # Create edges for interface implementation
    echo "Creating interface implementation edges."
    for i in `find $CLASSES -iname "*.php"`; do
    grep "class $CLASS_PREFIX" "$i" |
    grep "implements" |
    ### sed -e "s@^.*class \\($CLASS_PREFIX[a-zA-Z0-9_]*\\).*implements \\([a-zA-Z0-9_, ]\\+\\).*\$@{\\2}->\\1 [dir=back, color=\"$IMPLEMENTS_COLOR\"]@"|sed -e 's@ @@g'|sed -e 's@,@ @g' >>$TMPFILE;
    sed -e "s/class \($CLASS_PREFIX[a-zA-Z0-9_]*\).*implements \($CLASS_PREFIX[a-zA-Z0-9_]*\).*/{\2} -> \1 [dir=back, color=\"$IMPLEMENTS_COLOR\"]/" >>$TMPFILE;
    done

    # Close the graph
    echo "}" >>$TMPFILE

    # Backup dot file
    cp $TMPFILE $TMPFILE."tmp"

    echo "Generating graph."
    dot $TMPFILE -T$GRAPHTYPE -o $GRAPH

    # Has the graph been successfully generated?
    if [ $? -ne 0 ]; then
    exit $?
    fi

    # Correct the fonts if svg output driver is used
    if [ "$GRAPHTYPE" = "svg" ]; then
    mv $GRAPH $TMPFILE
    cat $TMPFILE|sed -e "s@font-size:$CLASS_FONTSIZE.00pt@font-size:$ORIG_CLASS_FONTSIZE.00pt@"|sed -e "s@font-size:$INTERFACE_FONTSIZE.00pt@font-size:$ORIG_INTERFACE_FONTSIZE.00pt@" >$GRAPH
    fi

    echo "Deleting temporary files."
    rm $TMPFILE

    echo "All done."

Add new comment

Fields with bold names are mandatory.