Coverage for putki/cli.py: 0.00%
56 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 22:07:46 +00:00
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 22:07:46 +00:00
1"""Command line interface for pipeline (Finnish: putki) - discovering and executing a specific task description."""
3import logging
4import pathlib
5import sys
7import typer
9import putki.api as api
10from putki import APP_NAME, DEFAULT_STRUCTURE_NAME, DEFAULT_STRUCTURES_NAME, QUIET, __version__ as APP_VERSION, log
12app = typer.Typer(
13 add_completion=False,
14 context_settings={'help_option_names': ['-h', '--help']},
15 no_args_is_help=True,
16)
18DocumentRoot = typer.Option(
19 '',
20 '-d',
21 '--document-root',
22 help='Root of the document tree to visit. Optional\n(default: positional tree root value)',
23)
25StructureName = typer.Option(
26 DEFAULT_STRUCTURE_NAME,
27 '-s',
28 '--structure',
29 help='structure mapping file (default: {DEFAULT_STRUCTURE_NAME})',
30)
32TargetName = typer.Option(
33 '',
34 '-t',
35 '--target',
36 help='target document key',
37)
39FacetName = typer.Option(
40 '',
41 '-f',
42 '--facet',
43 help='facet key of target document',
44)
46Verbosity = typer.Option(
47 False,
48 '-v',
49 '--verbose',
50 help='Verbose output (default is False)',
51)
53Strictness = typer.Option(
54 False,
55 '-s',
56 '--strict',
57 help='Ouput noisy warnings on console (default is False)',
58)
60OutputPath = typer.Option(
61 '',
62 '-o',
63 '--output-path',
64 help='Path to output unambiguous content to - like when ejecting a template',
65)
67StructuresName = typer.Option(
68 DEFAULT_STRUCTURES_NAME,
69 # '',
70 '--structures',
71 help='structures mapping file (default: {DEFAULT_STRUCTURES_NAME})',
72)
74ComponentFolderName = typer.Option( # TODO: prepare later for additional intermediates
75 'component',
76 # '',
77 '--component-folder-name',
78 help='component folder name (default: component)',
79)
82@app.callback(invoke_without_command=True)
83def callback(
84 version: bool = typer.Option(
85 False,
86 '-V',
87 '--version',
88 help='Display the application version and exit',
89 is_eager=True,
90 )
91) -> None:
92 """
93 Pipeline (Finnish: putki) - discovering and executing a specific task description.
94 """
95 if version:
96 typer.echo(f'{APP_NAME} version {APP_VERSION}')
97 raise typer.Exit()
100def _verify_call_vector(
101 doc_root: str, doc_root_pos: str, verbose: bool, strict: bool
102) -> tuple[int, str, str, dict[str, bool]]:
103 """DRY"""
104 doc = doc_root.strip()
105 if not doc and doc_root_pos:
106 doc = doc_root_pos
107 if not doc:
108 print('Document tree root required', file=sys.stderr)
109 return 2, 'Document tree root required', '', {}
111 doc_root_path = pathlib.Path(doc)
112 if doc_root_path.exists():
113 if not doc_root_path.is_dir():
114 print(f'requested tree root at ({doc}) is not a folder', file=sys.stderr)
115 return 2, f'requested tree root at ({doc}) is not a folder', '', {}
116 else:
117 print(f'requested tree root at ({doc}) does not exist', file=sys.stderr)
118 return 2, f'requested tree root at ({doc}) does not exist', '', {}
120 options = {
121 'quiet': QUIET and not verbose and not strict,
122 'strict': strict,
123 'verbose': verbose,
124 }
125 if verbose:
126 logging.getLogger().setLevel(logging.DEBUG)
127 return 0, '', doc, options
130@app.command('tasks')
131def verify_tasks( # noqa
132 doc_root_pos: str = typer.Argument(''),
133 doc_root: str = DocumentRoot,
134 structure: str = StructureName,
135 target: str = TargetName,
136 facet: str = FacetName,
137 verbose: bool = Verbosity,
138 strict: bool = Strictness,
139) -> int:
140 """
141 Verify the structure definition against the file system.
142 """
143 code, message, doc, options = _verify_call_vector(doc_root, doc_root_pos, verbose, strict)
144 if code:
145 log.error(message)
146 return code
148 return sys.exit(
149 api.verify_tasks(doc_root=doc, structure_name=structure, target_key=target, facet_key=facet, options=options)
150 )
153@app.command('structures')
154def verify_structures( # noqa
155 doc_root_pos: str = typer.Argument(''),
156 doc_root: str = DocumentRoot,
157 structures: str = StructuresName,
158 component: str = ComponentFolderName,
159 verbose: bool = Verbosity,
160 strict: bool = Strictness,
161) -> int:
162 """
163 Verify the structure definition against the file system.
164 """
165 code, message, doc, options = _verify_call_vector(doc_root, doc_root_pos, verbose, strict)
166 if code:
167 log.error(message)
168 return code
170 return sys.exit(
171 api.verify_structures(doc_root=doc, structures_name=structures, component=component, options=options)
172 )
175@app.command('version')
176def app_version() -> None:
177 """
178 Display the application version and exit.
179 """
180 callback(True)