aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/Makefile14
-rw-r--r--python/README.md4
-rw-r--r--python/notes/deps.pngbin0 -> 171270 bytes
-rw-r--r--python/refcat/cli.py15
-rw-r--r--python/refcat/deps.py10
5 files changed, 39 insertions, 4 deletions
diff --git a/python/Makefile b/python/Makefile
index 817d366..6564171 100644
--- a/python/Makefile
+++ b/python/Makefile
@@ -9,6 +9,8 @@ endif
SHELL := /bin/bash
PY_FILES := $(shell find . -name \*.py -print)
PKGNAME := refcat
+# A class for which we should render an image.
+TOP_CLASS := BrefCombined
# The "zipapp" we build, cf. PEP441, https://www.python.org/dev/peps/pep-0441/,
# https://shiv.readthedocs.io/
@@ -20,15 +22,17 @@ ZIPAPP := $(PKGNAME).pyz
# make refcat.pyz PYTHON_INTERPRETER='"/usr/bin/env python3.8"'
PYTHON_INTERPRETER := "/usr/bin/env python3.8"
-.PHONY: test
-test:
- pytest -v tests
+.PHONY: all
+all: notes/deps.png
$(ZIPAPP): $(PY_FILES)
# https://shiv.readthedocs.io/en/latest/cli-reference.html
# note: use SHIV_ROOT envvar to override expansion dir (e.g. if home is networked)
shiv --reproducible --compressed --entry-point refcat.cli:main --python $(PYTHON_INTERPRETER) --output-file $(ZIPAPP) .
+notes/deps.png: $(ZIPAPP)
+ ./refcat.pyz dot $(TOP_CLASS) | dot -Tpng > notes/deps.png
+
.PHONY: deploy
deploy: $(ZIPAPP)
ifndef DEPLOY_TARGET
@@ -37,6 +41,10 @@ else
rsync -avP $^ ${DEPLOY_TARGET}
endif
+.PHONY: test
+test:
+ pytest -v tests
+
.PHONY: fmt
fmt:
yapf -p -i -r $(PKGNAME) tests
diff --git a/python/README.md b/python/README.md
index 15e39c1..f449477 100644
--- a/python/README.md
+++ b/python/README.md
@@ -89,3 +89,7 @@ OpenLibraryEditionsToRelease UnmatchedResolveJournalNamesMapped
OpenLibraryReleaseMapped WikipediaCitationsMinimalDataset
OpenLibraryWorks
```
+
+## Dependencies
+
+![](notes/deps.png)
diff --git a/python/notes/deps.png b/python/notes/deps.png
new file mode 100644
index 0000000..faeb8aa
--- /dev/null
+++ b/python/notes/deps.png
Binary files differ
diff --git a/python/refcat/cli.py b/python/refcat/cli.py
index c96b69c..ced85f0 100644
--- a/python/refcat/cli.py
+++ b/python/refcat/cli.py
@@ -29,7 +29,7 @@ from luigi.task import Register
from luigi.task_register import TaskClassNotFoundException
from refcat import __version__
-from refcat.deps import dump_deps
+from refcat.deps import dump_deps, dump_deps_dot
from refcat.settings import LOGGING_CONF_FILE, settings
from refcat.tasks import *
from refcat.utils import columnize
@@ -155,6 +155,18 @@ def deps():
except TaskClassNotFoundException as exc:
print("no such task")
+def dot():
+ """
+ Render task dependencies as dot.
+ """
+ if len(sys.argv) < 2:
+ raise ValueError("task name required")
+ try:
+ parser = CmdlineParser(sys.argv[2:])
+ obj = parser.get_task_obj()
+ dump_deps_dot(obj)
+ except TaskClassNotFoundException as exc:
+ print("no such task")
def config():
"""
@@ -216,6 +228,7 @@ def main():
"completion",
"config",
"deps",
+ "dot",
"files",
"ll",
"ls",
diff --git a/python/refcat/deps.py b/python/refcat/deps.py
index 4d9a49b..de76eba 100644
--- a/python/refcat/deps.py
+++ b/python/refcat/deps.py
@@ -14,6 +14,16 @@ def dump_deps(task=None, indent=0):
for dep in g[task]:
dump_deps(task=dep, indent=indent + 1)
+def dump_deps_dot(task=None):
+ if task is None:
+ return
+ g = build_dep_graph(task)
+ print("digraph deps {")
+ print("node [shape=record];")
+ for k, vs in g.items():
+ for v in vs:
+ print(""" "{}" -> "{}"; """.format(k, v))
+ print("}")
def build_dep_graph(task=None):
"""