Skip to content

Commit 19556ce

Browse files
authored
feat: add --events option to diagram CLI (#593)
1 parent 5a85209 commit 19556ce

File tree

6 files changed

+52
-6
lines changed

6 files changed

+52
-6
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ repos:
3737
uv run python -m statemachine.contrib.diagram
3838
tests.examples.traffic_light_machine.TrafficLightMachine
3939
docs/images/readme_trafficlightmachine.png
40+
--events cycle cycle cycle
4041
language: system
4142
pass_filenames: false
42-
files: >-
43-
(statemachine/contrib/diagram/
44-
|tests/examples/traffic_light_machine\.py)
43+
files: (statemachine/contrib/diagram/|tests/examples/traffic_light_machine\.py)
4544
- id: pytest
4645
name: Pytest
4746
entry: uv run pytest -n auto --cov-fail-under=100

docs/diagram.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ The output format is inferred from the file extension:
103103
python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine diagram.png
104104
```
105105

106+
To highlight the current state, use `--events` to instantiate the machine and
107+
send events before rendering:
108+
109+
```bash
110+
python -m statemachine.contrib.diagram tests.examples.traffic_light_machine.TrafficLightMachine diagram.png --events cycle cycle cycle
111+
```
112+
106113

107114
## Sphinx directive
108115

1.65 KB
Loading

docs/releases/3.1.0.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ machine instance concurrently. This is now documented in the
4949
[#592](https://github.com/fgmacedo/python-statemachine/pull/592).
5050

5151

52+
### Diagram CLI `--events` option
53+
54+
The `python -m statemachine.contrib.diagram` command now accepts `--events` to
55+
instantiate the machine and send events before rendering, highlighting the
56+
current active state — matching the Sphinx directive's `:events:` option.
57+
See {ref}`diagram:Command line` for details.
58+
5259
### Bugfixes in 3.1.0
5360

5461
- Fixes silent misuse of `Event()` with multiple positional arguments. Passing more than one

statemachine/contrib/diagram/__init__.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,28 @@ def import_sm(qualname):
135135
return smclass
136136

137137

138-
def write_image(qualname, out):
138+
def write_image(qualname, out, events=None):
139139
"""
140140
Given a `qualname`, that is the fully qualified dotted path to a StateMachine
141141
classes, imports the class and generates a dot graph using the `pydot` lib.
142142
Writes the graph representation to the filename 'out' that will
143143
open/create and truncate such file and write on it a representation of
144144
the graph defined by the statemachine, in the format specified by
145145
the extension contained in the out path (out.ext).
146+
147+
If `events` is provided, the machine is instantiated and each event is sent
148+
before rendering, so the diagram highlights the current active state.
146149
"""
147150
smclass = import_sm(qualname)
148151

149-
graph = DotGraphMachine(smclass).get_graph()
152+
if events:
153+
machine = smclass()
154+
for event_name in events:
155+
machine.send(event_name)
156+
else:
157+
machine = smclass
158+
159+
graph = DotGraphMachine(machine).get_graph()
150160
out_extension = out.rsplit(".", 1)[1]
151161
graph.write(out, format=out_extension)
152162

@@ -165,6 +175,11 @@ def main(argv=None):
165175
"out",
166176
help="File to generate the image using extension as the output format.",
167177
)
178+
parser.add_argument(
179+
"--events",
180+
nargs="+",
181+
help="Instantiate the machine and send these events before rendering.",
182+
)
168183

169184
args = parser.parse_args(argv)
170-
write_image(qualname=args.class_path, out=args.out)
185+
write_image(qualname=args.class_path, out=args.out, events=args.events)

tests/test_contrib_diagram.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,24 @@ def test_generate_complain_about_bad_sm_path(self, capsys, tmp_path):
136136
]
137137
)
138138

139+
def test_generate_image_with_events(self, tmp_path):
140+
"""CLI --events instantiates the machine and sends events before rendering."""
141+
out = tmp_path / "sm.png"
142+
143+
main(
144+
[
145+
"tests.examples.traffic_light_machine.TrafficLightMachine",
146+
str(out),
147+
"--events",
148+
"cycle",
149+
"cycle",
150+
"cycle",
151+
]
152+
)
153+
154+
assert out.exists()
155+
assert out.stat().st_size > 0
156+
139157
def test_generate_complain_about_module_without_sm(self, tmp_path):
140158
out = tmp_path / "sm.svg"
141159

0 commit comments

Comments
 (0)