Coverage for src/debputy/lsp/config/parser.py: 90%
50 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-09-07 09:27 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-09-07 09:27 +0000
1import textwrap
2from typing import Optional, Type, Any
4from debputy.manifest_parser.declarative_parser import (
5 ParserGenerator,
6 DeclarativeNonMappingInputParser,
7)
8from debputy.manifest_parser.tagging_types import DebputyParsedContent
9from debputy.plugin.api import reference_documentation
10from debputy.plugin.api.impl import plugin_metadata_for_debputys_own_plugin
11from debputy.plugin.api.impl_types import (
12 DispatchingObjectParser,
13 DebputyPluginMetadata,
14 DeclarativeInputParser,
15)
16from debputy.plugin.api.spec import ParserDocumentation
17from debputy.util import T, _error
18from .config_options import ALL_DEBPUTY_CONFIG_OPTIONS
21class BoolDebputyParsedContent(DebputyParsedContent):
22 content: bool
25TT = Type[T]
28def _debputy_config_parser() -> DispatchingObjectParser:
29 pg = ParserGenerator()
30 plugin_metadata = plugin_metadata_for_debputys_own_plugin()
31 root_parser = pg.add_object_parser(
32 "<ROOT>",
33 unknown_keys_diagnostic_severity=None,
34 allow_unknown_keys=True,
35 )
36 diagnostics_object_parser = _add_sub_object_parser(
37 pg,
38 root_parser,
39 "diagnostics",
40 plugin_metadata,
41 parser_documentation=reference_documentation(
42 title="Diagnostics related settings (`diagnostics`)",
43 description=textwrap.dedent(
44 """\
45 Configurations related to diagnostics.
46 """
47 ),
48 ),
49 )
51 spellchecking_diagnostics = _add_sub_object_parser(
52 pg,
53 diagnostics_object_parser,
54 "spellchecking",
55 plugin_metadata,
56 parser_documentation=reference_documentation(
57 title="Spellchecking related diagnostics settings (`spellchecking`)",
58 description=textwrap.dedent(
59 """\
60 Settings related to spellchecking diagnostics
61 """
62 ),
63 ),
64 )
65 _config_value(
66 pg,
67 spellchecking_diagnostics,
68 "spellcheck-comments",
69 bool,
70 plugin_metadata,
71 inline_reference_documentation=reference_documentation(
72 title="Whether to spellcheck comments (`spellcheck-comments`)",
73 description=textwrap.dedent(
74 """\
75 Define whether `debputy` should spellcheck syntactical comments.
77 Consider the following example:
78 ```debian/control
79 Source: foo
81 Package: foo
82 # Here is a comment with a typu.
83 Description: Also a mistkae here
84 ```
86 This option affects whether `typu` in the above example will be
87 reported provided textual spellchecking is enabled. The other typo
88 (`mistkae`) is unaffected by this option, since it is not inside
89 a syntactical comment.
91 When this option is present and set to `false`, then syntactical comments
92 are never spellchecked.
93 """
94 ),
95 ),
96 )
97 _debputy_self_check_config_parser(root_parser)
98 return root_parser
101def _debputy_self_check_config_parser(root_parser: DispatchingObjectParser) -> None:
102 for config_option in ALL_DEBPUTY_CONFIG_OPTIONS:
103 parser: DeclarativeInputParser[Any] = root_parser
104 for part in config_option.config_name.split("."):
105 if isinstance(parser, DispatchingObjectParser): 105 ↛ 108line 105 didn't jump to line 108 because the condition on line 105 was always true
106 parser = parser.parser_for(part).parser
107 else:
108 _error(
109 f"Unknown parser for {config_option.config_name} at {part}: {parser}"
110 )
111 if not isinstance(parser, DeclarativeNonMappingInputParser): 111 ↛ 112line 111 didn't jump to line 112 because the condition on line 111 was never true
112 _error(
113 f"Expecting {config_option.config_name} to resolve to a DeclarativeNonMappingInputParser, got: {parser}"
114 )
115 if parser.alt_form_parser.attribute_type != config_option.value_type: 115 ↛ 116line 115 didn't jump to line 116 because the condition on line 115 was never true
116 _error(
117 f"Expecting {config_option.config_name} to be of type {config_option.value_type}, but parser suggest it is {parser.alt_form_parser.attribute_type}"
118 )
121def _config_value(
122 pg: ParserGenerator,
123 parent_parser: DispatchingObjectParser,
124 path: str,
125 value_type: TT,
126 plugin_metadata: DebputyPluginMetadata,
127 *,
128 inline_reference_documentation: Optional[ParserDocumentation] = None,
129) -> None:
130 class DebputyParsedContentWrapper(DebputyParsedContent):
131 content: value_type # type: ignore
133 parser = pg.generate_parser(
134 DebputyParsedContentWrapper,
135 source_content=value_type,
136 inline_reference_documentation=inline_reference_documentation,
137 )
138 parent_parser.register_parser(
139 path,
140 parser,
141 lambda k, pf, ap, pc: pf["content"],
142 plugin_metadata,
143 )
146def _add_sub_object_parser(
147 pg: ParserGenerator,
148 parent_parser: DispatchingObjectParser,
149 path: str,
150 plugin_metadata: DebputyPluginMetadata,
151 *,
152 parser_documentation: Optional[ParserDocumentation] = None,
153) -> DispatchingObjectParser:
154 if parent_parser.manifest_attribute_path_template == "<ROOT>":
155 full_path = path
156 else:
157 full_path = f"{parent_parser.manifest_attribute_path_template}.{path}"
158 child_parser = pg.add_object_parser(
159 full_path,
160 unknown_keys_diagnostic_severity=None,
161 parser_documentation=parser_documentation,
162 allow_unknown_keys=True,
163 )
164 parent_parser.register_parser(
165 path,
166 child_parser,
167 lambda k, pf, ap, pc: pf,
168 plugin_metadata,
169 )
170 return child_parser
173DEBPUTY_CONFIG_PARSER = _debputy_config_parser()
175del _debputy_config_parser
176del _config_value
177del _add_sub_object_parser
178del _debputy_self_check_config_parser