Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

depgraph.sh generates the dependency graph of the project (#154) #383

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ libraries/zenon_modulo
*.install
*.gv
*.png
*.dot
.DS_Store
*.map
22 changes: 22 additions & 0 deletions tools/depgraph/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
This is a temporary shell script generating the ocaml dependency graph.

-- How it works ?

1. it gets the dependencies with ``ocamldep ... | grep ...``
2. it generates the \*.mli from the \*.ml and gets the constants and functions with ``ocamlc.opt -i ... | grep -e "^val"``
3. it gets the constants and functions in the dependency by greping the sources
4. it generates the dot files with one colour by module dependency

-- How to use it ?

1. choose a set of interesting modules : change the interesting_modules variable
2. remove the interesting ``open Module`` in sources so that functions are explicitly called by ``Module.function a b c``. If you don't do it, you will get the graph with the modules (the nodes) and their dependencies (the edges) but you will miss the called functions (label on the edges)
3. the script has to be used after building lambdapi with dune (as it uses the the src/core/.core.objs/byte/\*.cmi files)
4. just call the script : ``./depgraph.sh``

-- Why it sucks ?

1. it's really a build-system (dune) job to generate such things
2. it should be written in ocaml (and using the graphviz library)
3. it doesn't work correctly with submodules
4. it's grep-ing the source instead of using the compiler libs to get the list of defined symbols
86 changes: 86 additions & 0 deletions tools/depgraph/depgraph.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/bin/bash
# shellcheck disable=SC2086

set -eu -o pipefail

# UPPERCASE THE FIRST LETTER OF A WORD
function uppercasefirst ()
{
word=$1
first=${word:0:1}
firstupper=${first^^}
wordwithoutfirst=${word:1}
echo "${firstupper}${wordwithoutfirst}"
}

errordirectory="error : non-existing directory"
workingdir=$(pwd)
scriptdir=$(dirname "${BASH_SOURCE[0]}")
lambdapidir=$(cd ${scriptdir}/../.. || { echo $errordirectory ; exit 1; } ; pwd)
graph=graph
graphdot=$workingdir/$graph.dot
graphpng=$workingdir/$graph.png

# CHOOSE THE INTERESTING_MODULES MODULES
concat_modules="$@"
if [ -z "$concat_modules" ] ; then
interesting_modules=( compile handle infer proof sr tactics typing unif )
else
interesting_modules=( $@ )
fi

# cd $lambdapidir/src/core
# interesting_modules=( )
# for mlfile in $(ls *.ml) ; do
# if [ $mlfile != parser.ml ] ; then #remove module with ppx/preprocessor extension
# mlfilenoml=$(basename ${mlfile} .ml)
# interesting_modules+=( "$mlfilenoml" )
# fi
# done

# COLORSCHEME
backgroundcolor="#252525"
paired12=( "#a6cee3" "#1f78b4" "#b2df8a" "#33a02c" "#fb9a99" "#e31a1c" "#fdbf6f" "#ff7f00" "#cab2d6" "#6a3d9a" "#ffff99" "#b15928" )
# brbg11 minus the darkest one
brbg11=( "#8c510a" "#bf812d" "#dfc27d" "#f6e8c3" "#f5f5f5" "#c7eae5" "#80cdc1" "#35978f" "#01665e" "#003c30" )
# piyg11 minus the darkest one
piyg11=( "#762a83" "#9970ab" "#c2a5cf" "#e7d4e8" "#f7f7f7" "#d9f0d3" "#a6dba0" "#5aae61" "#1b7837" "#00441b" )
colorscheme=( "${paired12[@]}" "${piyg11[@]}" "${brbg11[@]}" "${paired12[@]}" "${piyg11[@]}" "${brbg11[@]}" "${paired12[@]}" "${piyg11[@]}" "${brbg11[@]}" )

# GENERATE THE GRAPH TEXT FILE
rm -f $graphdot
echo "digraph g {" > $graphdot
echo "graph [bgcolor=\"$backgroundcolor\"];" >> $graphdot

icolor=0
for mldependency in "${interesting_modules[@]}" ; do
mldependencycolor=${colorscheme[$icolor]}
mldependencywithupper=$(uppercasefirst $mldependency)
echo "$mldependencywithupper [style=filled,fillcolor=\"$mldependencycolor\"];" >> $graphdot
for mlfile in "${interesting_modules[@]}" ; do
mlfilewithupper=$(uppercasefirst $mlfile)
if [ $mlfile != $mldependency ] ; then
cd $lambdapidir || { echo $errordirectory ; exit 1; }
mlfiledependsonmldependency=$(ocamldep -modules src/core/${mlfile}.ml | grep $mldependencywithupper) || true
if [ -n "$mlfiledependsonmldependency" ] ; then
cd $lambdapidir/_build/default || { echo $errordirectory ; exit 1; }
mldependencyfunctions=$(ocamlc -i -I src/core/.core.objs/byte -open Core src/core/${mldependency}.ml 2>&1 | grep -e "^val" | grep -v "type t =" | awk '{print $2}' ) || true
cd $lambdapidir || { echo $errordirectory ; exit 1; }
mldependencyfunctioninmlfile=( )
for function in ${mldependencyfunctions[*]} ; do
present=$(grep $mldependencywithupper.$function src/core/$mlfile.ml) || true
if [ -n "$present" ] ; then
mldependencyfunctioninmlfile+=( "$function\n" )
fi
done
echo " $mlfilewithupper -> $mldependencywithupper [color=\"$mldependencycolor\",fillcolor=\"$mldependencycolor\",fontcolor=\"$mldependencycolor\",label="\"${mldependencyfunctioninmlfile[*]}\""];" >> $graphdot
fi
fi
done
icolor=$((icolor+1))
done
echo "}" >> $graphdot

# GENERATE THE GRAPH
cd $workingdir || { echo $errordirectory ; exit 1; }
dot $graphdot -Tpng -o $graphpng