Viewing an internal dependency graph for a dune project

Is there already a good way to view a dependency graph between components of a dune/jbuilder project?

I’m looking for something that would illustrate the dependencies between components of a project. It should help a developer understand a codebase and navigate it quickly. Dependencies between OCaml modules (compilation units) may be too fine-grained for this purpose. We could consider the dependencies between libraries, say all the libraries built in the current project. This seems like it would be great. Other than that, perhaps the dependencies between jbuild files, if such notion exists, would probably work great as well. I can imagine the following:

$ jbuilder internal-deps
component1: component0
component2: component1
component3: component0
component4: component1 component3

where “components” are either paths to jbuild files or libraries built by the project.

Suggestions? Thoughts?

5 Likes

Being able to generate a dot graph and view it with graphviz might also be neat.

2 Likes

odig graph can do that on your opam install base between packages or cmis. See odig graph --help for details.

That’s what odig graph does but I never managed to get good outputs (too many nodes and layout algorithms going wild). An approach that worked better are the techniques from this paper which are implemented in d3. I once applied them to a massaged output of odig cobjs cmi -d --json on a subset of packages:

  1. On some mirage packages.
  2. On the ocaml package (note that given some packages like to install themselves into the lib/ocaml which according to odig conventions means they are part of the ocaml package that graph is a bit busier than it should be, e.g. you’ve got camlp4 and some ocp-* libs).

If you hover a compilation unit names its dependencies are in red and dependents in green. In 2. CamlInternalFormatBasics is an interesting unit.

8 Likes

Can we slightly extend this approach to get access to all OCaml sources for the specific library?

Let’s say all sources except the ones that are in compiler to be more precise. Knowing this information we will have all data to implement some static analysis procedure, like detecting which exceptions can be raised by function, detecting inductive invariants for functions, and other cool stuff.

Done and announced today
:tada: