1"""Check and assemble commands for running Graphviz ``dot``."""
2
3import os
4import pathlib
5from typing import Final
6
7from .. import exceptions
8from .. import parameters
9
10__all__ = ['DOT_BINARY', 'command']
11
12DOT_BINARY: Final = pathlib.Path('dot')
13
14
15def command(engine: str, format_: str, *,
16 renderer: str | None = None,
17 formatter: str | None = None,
18 neato_no_op: bool | int | None = None) -> list[os.PathLike[str] | str]:
19 """Return ``subprocess.Popen`` argument list for rendering.
20
21 See also:
22 Upstream documentation:
23 - https://www.graphviz.org/doc/info/command.html#-K
24 - https://www.graphviz.org/doc/info/command.html#-T
25 - https://www.graphviz.org/doc/info/command.html#-n
26 """
27 if formatter is not None and renderer is None:
28 raise exceptions.RequiredArgumentError('formatter given without renderer')
29
30 parameters.verify_engine(engine, required=True)
31 parameters.verify_format(format_, required=True)
32 parameters.verify_renderer(renderer, required=False)
33 parameters.verify_formatter(formatter, required=False)
34
35 output_format = [f for f in (format_, renderer, formatter) if f is not None]
36 output_format_flag = ':'.join(output_format)
37
38 cmd: list[os.PathLike[str] | str]
39 cmd = [DOT_BINARY, f'-K{engine}', f'-T{output_format_flag}']
40
41 if neato_no_op:
42 cmd.append(f'-n{neato_no_op:d}')
43
44 return cmd