I've had an idea for a little bit of tooling for a while, but I can't think of a good way to implement it outside of core.
When I
heard about mix xref graph it reoccured to me. I'm wondering what other people think about bridging that concept with :observer's process link graph, to generate a non-runtime view of what a project's OTP behaviour structure looks like.
The end product I envision is an ERD PDF artifact in project root that graphs what different OTP behaviours compiled modules have implemented, and how they relate to each other. An example might plot the project's main OTP Application module as a root node, that branches out to show the names of Supervisors it starts and their Workers, plotted with different shapes if they're GenEvent handlers, GenServers, or Agents; and perhaps connected with different line types depending on their restart type. Modules that start at Application boot like loggers and Ecto repos would optionally show up alongside the rest. Sort of a map of project entities and their responsibilities.
The CLI API I envision is similar to
rails-ERD's rake task, namely flags and options to exclude modules of different names/namespaces, behaviour types, and origins (internal versus external).
Note I'm not talking about a compile-time graph of all processes and links, so much as a high-level overview of project structure. Just being able to see a project's core OTP behaviours at a glance diagrammed and related to each other would help onboarding, whiteboarding, and project design.
Of all the implementations I've brainstormed, the only pleasant one that occurs to me would be core taking possession of some module attribute names for this purpose, and have it such that our Supervisor, Behaviour, GenServer, etc injects proper attributes into using modules. Similarly, the Supervisor.Spec macros could inject the relational information required into the module.
If the structure of the module attributes are designed well, this would enable an extensible API for other projects with their own Behaviour types to insert new entity types into the graph, and let end users identify and annotate project-specific custom behaviours as well.
I don't see a tenable way to have this exist outside of core as a library without asking users to exclusively use wrapper GraphableOTP.Supervisors and so on for everything, so I'm fielding it here rather than pursuing a proof-of-concept library first. :) Thoughts?