Oh, my first english post ... so amazing (isn't it ?). Well, I present a little (and awful) bash dependency graph generator for Java projects.
One goal of my job is to maintain the Quercus project. It is currently highly dependent of Resin, another Caucho's project, and a removal is needed. To know what I need to remove first, I wanted a graphical representation of all links between projects. We can consider that dependencies could be computed with 'import' Java keyword. Yes I know, it's not a perfect dependencies representation but it's currently the best way I found (and faster). Finally, we need a graph generation tool ... I found GraphViz which can be directly used in CLI and we use DOT format file to make the graph specifications. One day after ... Jdep-grapher is released.
How does it work ?
It will first get the list of files to parse (with find) and extract all lines beginning with 'import' and 'package' (we use temp files with mktemp
) :
find $DIR -type f -name "*.java" > $FILES
grep -E "^package|^import" $(< $FILES) | awk -F':' '{print $2}' > $GREP
Next it creates links between packages and uses DOT format :
while read type name
do
name=`echo $name | tr -d ";"`
pkg=`echo $name | tr -d "."`
if [[ "$type" == "package" ]]; then
echo "$pkg [label=\"$name\", style = filled, shape = box];"
CPKG=$pkg
else
ALL=`echo $pkg | grep "\*" | wc -l`
SUP=""
LNK=""
if [[ $ALL -eq 1 ]]; then
pkg=`echo $pkg | sed s/"*"/"allpkg"/`
SUP=", color=red, style = filled"
LNK=" [color=red]"
fi
echo "$pkg [label=\"$name\"$SUP];"
echo "$CPKG -> $pkg $LNK;"
fi
done < $GREP | sort -u > $COMPUTE
sort -u
at the end of loop will automatically remove duplicates and send the result to a new temp file. All-inclusion packages (with *) are filled in red.
We can exclude useless links (eg. internal dependencies) with :
grep -vE "$EXCLUDE" $COMPUTE > $TMPDOT
To reduce the weight of graph, it removes single nodes :
CT=`grep -E "$rpkg( |;)" $TMPDOT | wc -l`
if [[ $CT -gt 1 ]]; then
echo $rpkg $rop $rchild >> $TMPDOT2
fi
Finally, the script closes the DOT file and launches graphviz ...
echo "digraph G {" > $DOT
cat $TMPDOT2 >> $DOT
echo "}" >> $DOT
fdp -Tpng < $DOT > $GRAPH
Enjoy
Example : Resin Dependency Graph of Quercus
Note : the script currently uses 'fdp' from graphviz which is not fully optimized for this kind of graph. Tell me if you have any other solution ;-)
More information on GitHub.