This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Python script to generate a DOT dependency graph of webthree-umbrella…

…, to replace the hand-authored one.
  • Loading branch information...
bobsummerwill committed Dec 3, 2015
1 parent 1c9b798 commit c62c935503490bdf8a2bec5161cd4e845e3d9121
Showing with 116 additions and 68 deletions.
  1. +0 −68 dependency_graph.dot
  2. +115 −0 dependency_graph/generate.py
  3. +1 −0 dependency_graph/generate.sh
View
@@ -1,68 +0,0 @@
-digraph G {
- subgraph cluster_libdev {
- devcore->devcrypto;
- devcrypto->p2p;
- label="libdev";
- graph[style=filled,color=lightgrey];
- }
-
- p2p->whisper;
- subgraph cluster_whisper {
- whisper->webthree;
- label = "libwhisper";
- graph[style=filled,color=lightgrey];
- }
-
- ethereum -> webthree;
-
- subgraph cluster_webthree {
- webthree->web3jsonrpc;
- web3jsonrpc->eth;
- label = "webthree";
- graph[style=filled,color=lightgrey];
- }
-
- subgraph cluster_solidity {
- solidity->solc;
- solidity->web3jsonrpc;
- label = "solidity";
- graph[style=filled,color=lightgrey];
- }
-
- evm->ethereum;
- lll->ethereum;
- devcrypto->ethcore;
- devcore->evmcore;
- p2p->ethereum;
- evmcore->evmasm;
- evmcore->evmjitcpp;
- evmcore->ethcore;
- evmjitcpp->evm;
- ethcore->evm;
- evmasm->lll;
- evmasm->solidity;
-
- subgraph cluster_evmjitcpp {
- evmjitcpp;
- graph[style=filled,color=lightgrey];
- }
-
- web3jsonrpc->alethzero;
- natspec->alethzero;
- solidity->alethzero;
-
- subgraph cluster_alethzero {
- alethzero;
- graph[style=filled,color=lightgrey];
- }
-
- web3jsonrpc->mix;
- solidity->mix;
-
- subgraph cluster_mix {
- mix;
- graph[style=filled,color=lightgrey];
- }
-
-
-}
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+#
+# generate.py
+#
+# Python script to generate a DOT graph showing the dependency graph of
+# the components within the Ethereum webthree-umbrella project.
+#
+# See http://github.com/ethereum/webthree-umbrella for more info on webthree
+# See http://ethereum.org for more info on Ethereum
+#
+# Contributed by Bob Summerwill (bob@summerwill.net)
+
+import os
+import re
+
+assignmentPattern = "(set|eth_name)\((EXECUTABLE|LIBRARY) (.*)\)"
+dependencyPattern = "eth_use\((.*)\s+(OPTIONAL|REQUIRED)\s+(.*)\)"
+
+
+# Returns a string which lists all the dependency edges for a given
+# library or application, based on the declared OPTIONAL and REQUIRED
+# dependencies within the CMake file for that library or application.
+def getDependencyEdges(submodulePath, library):
+ cmakeListsPath = os.path.join(os.path.join(submodulePath, library), "CMakeLists.txt")
+ outputString = ""
+
+ if os.path.exists(cmakeListsPath):
+ executable = ""
+ with open(cmakeListsPath) as fileHandle:
+ for line in fileHandle.readlines():
+ result = re.search(assignmentPattern, line)
+ if result:
+ executable = result.group(3)
+ result = re.search(dependencyPattern, line)
+ if result:
+ fromNode = result.group(1)
+ if fromNode == "${EXECUTABLE}":
+ fromNode = executable
+ toNodes = result.group(3).split()
+ for toNode in toNodes:
+ if ("::" in toNode) and not (toNode.startswith("Qt::")) and not (toNode.startswith("JsonRpc::")):
+ toNode = toNode.split("::")[1]
+ edgeText = '"' + fromNode + '" -> "' + toNode + '"'
+ if "OPTIONAL" in line:
+ edgeText = edgeText + " [style=dotted]"
+ outputString = outputString + edgeText + "\n"
+
+ return outputString
+
+# Return a string which is a list of all the library and application
+# names within a given git sub-module directory.
+def getLibraryAndApplicationNames(submodulePath):
+ outputString = ""
+ for subDirectoryName in os.listdir(submodulePath):
+ absSubDirectoryPath = os.path.join(submodulePath, subDirectoryName)
+ if os.path.isdir(absSubDirectoryPath):
+ cmakeListsPath = os.path.join(absSubDirectoryPath, "CMakeLists.txt")
+ if os.path.exists(cmakeListsPath):
+ moduleName = ""
+ with open(cmakeListsPath) as fileHandle:
+ for line in fileHandle.readlines():
+ result = re.search(assignmentPattern, line)
+ if result:
+ moduleName = result.group(3)
+ if (moduleName == ""):
+ moduleName = subDirectoryName
+ outputString = outputString + ' "' + moduleName + '"'
+ if not subDirectoryName.startswith("lib"):
+ outputString = outputString + ' [shape="box", style="bold"]'
+ outputString = outputString + "\n"
+ return outputString
+
+# Generate a sub-graph for each sub-module in the umbrella.
+def processSubmodule(root, submodule):
+ submodulePath = os.path.join(root, submodule)
+
+ print " subgraph cluster_" + submodule.replace(".","_").replace("-","_") + " {"
+ print " label = <" + submodule + " dependencies>"
+
+ print getLibraryAndApplicationNames(submodulePath)
+
+ if (submodule == "libethereum"):
+ print " bgcolor = LavenderBlush"
+ elif (submodule == "webthree"):
+ print " bgcolor = Honeydew"
+ elif (submodule == "libweb3core"):
+ print " bgcolor = AliceBlue"
+ elif (submodule == "solidity"):
+ print " bgcolor = WhiteSmoke"
+ else:
+ print " bgcolor = LightGray"
+ print " }"
+
+ for library in os.listdir(submodulePath):
+ absLibPath = os.path.join(submodulePath, library)
+ if os.path.isdir(absLibPath):
+ print getDependencyEdges(submodulePath, library)
+
+# Walk the sub-modules under the umbrella
+def processUmbrella(root):
+ for submodule in os.listdir(root):
+ absPath = os.path.join(root, submodule)
+ if os.path.isdir(absPath):
+ if not (".git" in absPath) and not ("dependency_graph" in absPath) and not ("webthree-helpers" in absPath):
+ processSubmodule(root, submodule)
+
+
+print 'digraph webthree {'
+print ' graph [ label = "webthree dependencies" ]'
+print ' node [ fontname = "Courier", fontsize = 10 ]'
+print ''
+print ' compound = true'
+
+processUmbrella('..')
+print "}"
@@ -0,0 +1 @@
+python ./generate.py | tred | dot -Tpng > dependency_graph.png

0 comments on commit c62c935

Please sign in to comment.