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