Skip to content

Commit

Permalink
Merge pull request #2 from bagerard/add_svg_support
Browse files Browse the repository at this point in the history
Add svg support
  • Loading branch information
bagerard authored Jan 18, 2025
2 parents 0460d25 + 0815e14 commit 5b59b04
Show file tree
Hide file tree
Showing 13 changed files with 405 additions and 219 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/github-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.9
python-version: 3.11
- run: bash .github/workflows/install_ci_python_dep.sh
- run: pre-commit run -a

Expand All @@ -27,7 +27,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9, "3.10"]
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
Expand Down
9 changes: 5 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
fail_fast: false
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v5.0.0
hooks:
- id: check-ast
- id: check-merge-conflict
Expand All @@ -15,14 +15,15 @@ repos:
types: [python]

- repo: https://github.com/pycqa/flake8
rev: 6.0.0
rev: 7.1.1
hooks:
- id: flake8
name: flake8-blocking
args: [ '--isolated', '--select=P,F401,F821,F901', '--ignore=P101,P102' ]
additional_dependencies:
- flake8-string-format

- repo: https://github.com/psf/black
rev: 22.12.0
rev: 24.10.0
hooks:
- id: black
- id: black
20 changes: 17 additions & 3 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,24 @@
language: python
files: '.dot$'
pass_filenames: true
- id: render-dot
name: render dot
- id: render-dot-png
name: render dot to png
description: render all .dot to .dot.png
entry: render-dot
entry: render-dot-png
language: python
files: '.dot$'
pass_filenames: true
- id: render-dot-svg
name: render dot to svg
description: render all .dot to .dot.svg
entry: render-dot-svg
language: python
files: '.dot$'
pass_filenames: true
- id: render-dot
name: render dot to png (legacy hook - switch to render-dot-png)
description: render all .dot to .dot.png
entry: render-dot-png
language: python
files: '.dot$'
pass_filenames: true
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MAKEFLAGS += --silent

.PHONY: setup-venv test

PYTHON_VERSION = "3.8.6"
PYTHON_VERSION = "3.11.9"
VENV_NAME := $(shell cat .python-version)


Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,25 @@ and we are sure that both version match and developers don't forget to render th
## Hooks available

### `check-dot`
Verify the syntax of .dot files:
Verify the syntax of .dot files


### `render-dot`
Is an alias for `render-dot-png`, kept for backward compatibility


### `render-dot-png`
Render .dot files to png. This command can work in 2 ways

- Called without argument, it will render the .png next to the .dot files (simply appending ".png" to the .dot file path)
- `--only src1,src2` can be used to select the files to be rendered
- `--only src1:target1,src2:target2` can be used to specify custom locations for the PNG (specified per .dot source)


### `render-dot-svg`
Same as `render-dot-png` but renders to svg. Rendering to svg may be more stable as it is less sensitive to fonts and other dependencies.
Discrepancies were observed when using the png hook between ubuntu 22 and ubuntu 24 for instance.

## Pre-commit integration

An example `.pre-commit-config.yaml`:
Expand All @@ -38,7 +46,7 @@ repos:
rev: master
hooks:
- id: check-dot
- id: render-dot
- id: render-dot-png
# args: ["--only=class_diagram.dot:docs/class_diagram.png"]
```

6 changes: 4 additions & 2 deletions graphviz_dot_hooks/check_dot.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
def _verify_dot_rendering(dot_filepath: str) -> Tuple[bool, Optional[str]]:
"""Trying to render it would detect syntax error, there are probably cheaper way to check this
but we aren't really looking after performance here"""
with tempfile.NamedTemporaryFile(suffix=".png") as tmpf:
with tempfile.NamedTemporaryFile(suffix=f".{format}") as tmpf:
try:
render("dot", "png", dot_filepath, outfile=tmpf.name)
# arbitrary render as svg (more generic than png)
# but it doesn't matter much as we are mostly interested in .dot syntax
render("dot", "svg", dot_filepath, outfile=tmpf.name)
except CalledProcessError as ex:
return False, str(ex)

Expand Down
119 changes: 0 additions & 119 deletions graphviz_dot_hooks/render_dot.py

This file was deleted.

51 changes: 51 additions & 0 deletions graphviz_dot_hooks/render_dot_png.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import argparse
import sys
from typing import Dict

from graphviz_dot_hooks.utils import render_dotfiles, _parse_only_convert

parser = argparse.ArgumentParser()
parser.add_argument("instancefiles", nargs="+", help=".dot files to check")
parser.add_argument(
"--only",
action="store",
type=str,
default=None,
required=False,
help="string with coma-separated values, target files can be specified as well in the format '--only src1:target1,src2:target2'"
" Example: --only dotfile1.dot,dotfile2.dot"
" --only dotfile1.dot:doc/dotfile1.png,dotfile2.dot",
)


def main():
args = parser.parse_args()

format = "png"

convert_map: Dict[str, str]
if args.only:
# Take the intersection of the instancefiles and the --only
convert_map = _parse_only_convert(args.only, format=format)
convert_map = {
src: target
for src, target in convert_map.items()
if src in args.instancefiles
}
else:
# Take the instancefiles
convert_map = _parse_only_convert(",".join(args.instancefiles), format=format)

success, messages = render_dotfiles(convert_map, format=format)

for message in messages:
print(message)

if success:
sys.exit(0)
else:
sys.exit(1)


if __name__ == "__main__":
main()
51 changes: 51 additions & 0 deletions graphviz_dot_hooks/render_dot_svg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import argparse
import sys
from typing import Dict

from graphviz_dot_hooks.utils import render_dotfiles, _parse_only_convert

parser = argparse.ArgumentParser()
parser.add_argument("instancefiles", nargs="+", help=".dot files to check")
parser.add_argument(
"--only",
action="store",
type=str,
default=None,
required=False,
help="string with coma-separated values, target files can be specified as well in the format '--only src1:target1,src2:target2'"
" Example: --only dotfile1.dot,dotfile2.dot"
" --only dotfile1.dot:doc/dotfile1.svg,dotfile2.dot",
)


def main():
args = parser.parse_args()

format = "svg"

convert_map: Dict[str, str]
if args.only:
# Take the intersection of the instancefiles and the --only
convert_map = _parse_only_convert(args.only, format=format)
convert_map = {
src: target
for src, target in convert_map.items()
if src in args.instancefiles
}
else:
# Take the instancefiles
convert_map = _parse_only_convert(",".join(args.instancefiles), format=format)

success, messages = render_dotfiles(convert_map, format=format)

for message in messages:
print(message)

if success:
sys.exit(0)
else:
sys.exit(1)


if __name__ == "__main__":
main()
Loading

0 comments on commit 5b59b04

Please sign in to comment.