diff options
-rw-r--r-- | python/Makefile | 14 | ||||
-rw-r--r-- | python/README.md | 4 | ||||
-rw-r--r-- | python/notes/deps.png | bin | 0 -> 171270 bytes | |||
-rw-r--r-- | python/refcat/cli.py | 15 | ||||
-rw-r--r-- | python/refcat/deps.py | 10 |
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 Binary files differnew file mode 100644 index 0000000..faeb8aa --- /dev/null +++ b/python/notes/deps.png 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): """ |