diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-14 20:17:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-14 20:17:41 +0000 |
commit | c2da8244dfd429c1737c029ed3993c15b4cd8c4f (patch) | |
tree | 771515cf321b1d24e56bce38be2c392a7669cf76 /src | |
parent | Adding debian version 0.1.26. (diff) | |
download | debputy-c2da8244dfd429c1737c029ed3993c15b4cd8c4f.tar.xz debputy-c2da8244dfd429c1737c029ed3993c15b4cd8c4f.zip |
Merging upstream version 0.1.27.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/debputy/commands/deb_packer.py | 4 | ||||
-rw-r--r-- | src/debputy/commands/debputy_cmd/output.py | 4 | ||||
-rw-r--r-- | src/debputy/commands/debputy_cmd/plugin_cmds.py | 2 | ||||
-rw-r--r-- | src/debputy/dh_migration/migrators_impl.py | 2 | ||||
-rw-r--r-- | src/debputy/installations.py | 4 | ||||
-rw-r--r-- | src/debputy/lsp/debian-wordlist.dic | 2 | ||||
-rw-r--r-- | src/debputy/lsp/lsp_debian_control_reference_data.py | 14 | ||||
-rw-r--r-- | src/debputy/lsp/lsp_debian_debputy_manifest.py | 337 | ||||
-rw-r--r-- | src/debputy/lsp/lsp_debian_rules.py | 8 | ||||
-rw-r--r-- | src/debputy/lsp/vendoring/_deb822_repro/__init__.py | 2 | ||||
-rw-r--r-- | src/debputy/lsp/vendoring/_deb822_repro/parsing.py | 2 | ||||
-rw-r--r-- | src/debputy/lsp/vendoring/_deb822_repro/tokens.py | 2 | ||||
-rw-r--r-- | src/debputy/lsp/vendoring/_deb822_repro/types.py | 2 | ||||
-rw-r--r-- | src/debputy/manifest_parser/declarative_parser.py | 4 | ||||
-rw-r--r-- | src/debputy/plugin/api/spec.py | 2 | ||||
-rw-r--r-- | src/debputy/plugin/debputy/binary_package_rules.py | 4 | ||||
-rw-r--r-- | src/debputy/plugin/debputy/private_api.py | 22 |
17 files changed, 315 insertions, 102 deletions
diff --git a/src/debputy/commands/deb_packer.py b/src/debputy/commands/deb_packer.py index 8c61099..986a8fa 100644 --- a/src/debputy/commands/deb_packer.py +++ b/src/debputy/commands/deb_packer.py @@ -288,7 +288,7 @@ def parse_args() -> argparse.Namespace: THIS IS A PROTOTYPE "dpkg-deb -b" emulator with basic manifest support DO NOT USE THIS TOOL DIRECTLY. It has not stability guarantees and will be removed as - soon as "dpkg-deb -b" grows support for the relevant features. + soon as "dpkg-deb -b" grows support for the relevant features. This tool is a prototype "dpkg-deb -b"-like interface for compiling a Debian package without requiring root even for static ownership. It is a temporary stand-in for @@ -297,7 +297,7 @@ def parse_args() -> argparse.Namespace: The tool operates on an internal JSON based manifest for now, because it was faster than building an mtree parser (which is the format that dpkg will likely end up using). - + As the tool is not meant to be used directly, it is full of annoying paper cuts that I refuse to fix or maintain. Use the high level tool instead. diff --git a/src/debputy/commands/debputy_cmd/output.py b/src/debputy/commands/debputy_cmd/output.py index 131338a..df8e6eb 100644 --- a/src/debputy/commands/debputy_cmd/output.py +++ b/src/debputy/commands/debputy_cmd/output.py @@ -243,8 +243,8 @@ class ANSIOutputStylingBase(OutputStylingBase): return super().render_url(link_url) link_text = link_url if not self.optimize_for_screen_reader and link_url.startswith("man:"): - # Rewrite manpage to a clickable link by default. I am not sure how the hyperlink - # ANSI code works with screen readers, so lets not rewrite the manpage link by + # Rewrite man page to a clickable link by default. I am not sure how the hyperlink + # ANSI code works with screen readers, so lets not rewrite the man page link by # default. My fear is that both the link url and the link text gets read out. m = MAN_URL_REWRITE.match(link_url) if m: diff --git a/src/debputy/commands/debputy_cmd/plugin_cmds.py b/src/debputy/commands/debputy_cmd/plugin_cmds.py index 69b2a2a..a8103fb 100644 --- a/src/debputy/commands/debputy_cmd/plugin_cmds.py +++ b/src/debputy/commands/debputy_cmd/plugin_cmds.py @@ -136,7 +136,7 @@ TEXT_CSV_FORMAT_NO_STABILITY_PROMISE = format_output_arg( ) def _plugin_cmd_list_plugins(context: CommandContext) -> None: plugin_metadata_entries = context.load_plugins().plugin_data.values() - # Because the "plugins" part is optional, we are not guaranteed tha TEXT_CSV_FORMAT applies + # Because the "plugins" part is optional, we are not guaranteed that TEXT_CSV_FORMAT applies output_format = getattr(context.parsed_args, "output_format", "text") assert output_format in {"text", "csv"} with _stream_to_pager(context.parsed_args) as (fd, fo): diff --git a/src/debputy/dh_migration/migrators_impl.py b/src/debputy/dh_migration/migrators_impl.py index 450b5a9..d7aa252 100644 --- a/src/debputy/dh_migration/migrators_impl.py +++ b/src/debputy/dh_migration/migrators_impl.py @@ -1079,7 +1079,7 @@ def migrate_installman_file( if warn_about_basename: feature_migration.warn( - 'Detected manpages that might rely on "derive-from-basename" logic. Please double check' + 'Detected man pages that might rely on "derive-from-basename" logic. Please double check' " that the generated `install-man` rules are correct" ) diff --git a/src/debputy/installations.py b/src/debputy/installations.py index 2310cfa..e1e8f3a 100644 --- a/src/debputy/installations.py +++ b/src/debputy/installations.py @@ -212,9 +212,9 @@ def _determine_manpage_real_section( f" which is not a valid section (must be between 1 and 9 incl.)" ) _error( - f"Could not determine the section for {match_rule.path.fs_path} automatically. The manpage" + f"Could not determine the section for {match_rule.path.fs_path} automatically. The man page" f" was detected via {definition_source}. Consider using `section: <number>` to" - " explicitly declare the section. Keep in mind that it applies to all manpages for that" + " explicitly declare the section. Keep in mind that it applies to all man pages for that" " rule and you may have to split the rule into two for this reason." ) return real_section diff --git a/src/debputy/lsp/debian-wordlist.dic b/src/debputy/lsp/debian-wordlist.dic index 11e0438..5d75eaa 100644 --- a/src/debputy/lsp/debian-wordlist.dic +++ b/src/debputy/lsp/debian-wordlist.dic @@ -171,8 +171,6 @@ maintscript maintscripts makefile makefiles -manpage -manpages md5sum md5sums menutest diff --git a/src/debputy/lsp/lsp_debian_control_reference_data.py b/src/debputy/lsp/lsp_debian_control_reference_data.py index 3e16f3c..feed858 100644 --- a/src/debputy/lsp/lsp_debian_control_reference_data.py +++ b/src/debputy/lsp/lsp_debian_control_reference_data.py @@ -233,7 +233,7 @@ def all_architectures_and_wildcards(arch2table) -> Iterable[Union[str, Keyword]] The package is an architecture dependent package and need to be compiled for each and every architecture it. - The name `any` refers to the fact that this is an architecture *wildcard* matching + The name `any` refers to the fact that this is an architecture *wildcard* matching *any machine architecture* supported by dpkg. """ ), @@ -1313,7 +1313,7 @@ BINARY_FIELDS = _fields( "no", hover_text=textwrap.dedent( """\ - The package is a regular package. This is the default and recommended.</p> + The package is a regular package. This is the default and recommended. Note that declaring a package to be "Essential: no" is the same as not having the field except omitting the field wastes fewer bytes on everyone's hard disk. @@ -1358,7 +1358,7 @@ BINARY_FIELDS = _fields( "no", hover_text=textwrap.dedent( """\ - The package is a regular package. This is the default and recommended.</p> + The package is a regular package. This is the default and recommended. Note that declaring a package to be `XB-Important: no` is the same as not having the field except omitting the field wastes fewer bytes on everyone's hard-disk. @@ -1381,7 +1381,7 @@ BINARY_FIELDS = _fields( "no", hover_text=textwrap.dedent( """\ - The package is a regular package. This is the default and recommended.</p> + The package is a regular package. This is the default and recommended. Note that declaring a package to be `Protected: no` is the same as not having the field except omitting the field wastes fewer bytes on everyone's hard-disk. @@ -1450,7 +1450,7 @@ BINARY_FIELDS = _fields( hover_text=textwrap.dedent( """\ Lists the packages that *should* be installed when this package is installed in all but - *unusual installations*.</p> + *unusual installations*. **Example**: ``` @@ -2017,7 +2017,7 @@ BINARY_FIELDS = _fields( custom_field_check=_each_value_match_regex_validation(PKGNAME_REGEX), hover_text=textwrap.dedent( """\ - Special purpose field renamed to the 64-bit time transition. + Special purpose field related to the 64-bit time transition. It is used to inform packaging helpers what the original (non-transitioned) package name was when the auto-detection is inadequate. The non-transitioned package name is then @@ -2644,7 +2644,7 @@ _DTESTSCTRL_FIELDS = _fields( hover_text=textwrap.dedent( """\ If your test only contains a shell command or two, or you want to - re-use an existing upstream test executable and just need to wrap it + reuse an existing upstream test executable and just need to wrap it with some command like `dbus-launch` or `env`, you can use this field to specify the shell command directly. It will be run under `bash -e`. This is mutually exclusive with the `Tests:` field. diff --git a/src/debputy/lsp/lsp_debian_debputy_manifest.py b/src/debputy/lsp/lsp_debian_debputy_manifest.py index d24d441..ba30c75 100644 --- a/src/debputy/lsp/lsp_debian_debputy_manifest.py +++ b/src/debputy/lsp/lsp_debian_debputy_manifest.py @@ -25,6 +25,8 @@ from lsprotocol.types import ( CompletionParams, CompletionList, CompletionItem, + DiagnosticRelatedInformation, + Location, ) from debputy.lsp.quickfixes import propose_correct_text_quick_fix from debputy.manifest_parser.base_types import DebputyDispatchableType @@ -123,7 +125,7 @@ def _word_range_at_position( @lint_diagnostics(_LANGUAGE_IDS) def _lint_debian_debputy_manifest( - _doc_reference: str, + doc_reference: str, path: str, lines: List[str], position_codec: LintCapablePositionCodec, @@ -172,94 +174,299 @@ def _lint_debian_debputy_manifest( ) else: feature_set = lsp_get_plugin_features() - root_parser = feature_set.manifest_parser_generator.dispatchable_object_parsers[ - OPARSER_MANIFEST_ROOT - ] - diagnostics.extend(_lint_content(root_parser, content, lines, position_codec)) + pg = feature_set.manifest_parser_generator + root_parser = pg.dispatchable_object_parsers[OPARSER_MANIFEST_ROOT] + diagnostics.extend( + _lint_content( + doc_reference, + pg, + root_parser, + content, + lines, + position_codec, + ) + ) return diagnostics +def _unknown_key( + key: str, + expected_keys: Iterable[str], + line: int, + col: int, + lines: List[str], + position_codec: LintCapablePositionCodec, +) -> Tuple["Diagnostic", Optional[str]]: + key_range = position_codec.range_to_client_units( + lines, + Range( + Position( + line, + col, + ), + Position( + line, + col + len(key), + ), + ), + ) + + candidates = detect_possible_typo(key, expected_keys) + extra = "" + corrected_key = None + if candidates: + extra = f' It looks like a typo of "{candidates[0]}".' + # TODO: We should be able to tell that `install-doc` and `install-docs` are the same. + # That would enable this to work in more cases. + corrected_key = candidates[0] if len(candidates) == 1 else None + + diagnostic = Diagnostic( + key_range, + f'Unknown or unsupported key "{key}".{extra}', + DiagnosticSeverity.Error, + source="debputy", + data=[propose_correct_text_quick_fix(n) for n in candidates], + ) + return diagnostic, corrected_key + + +def _conflicting_key( + uri: str, + key_a: str, + key_b: str, + key_a_line: int, + key_a_col: int, + key_b_line: int, + key_b_col: int, + lines: List[str], + position_codec: LintCapablePositionCodec, +) -> Iterable["Diagnostic"]: + key_a_range = position_codec.range_to_client_units( + lines, + Range( + Position( + key_a_line, + key_a_col, + ), + Position( + key_a_line, + key_a_col + len(key_a), + ), + ), + ) + key_b_range = position_codec.range_to_client_units( + lines, + Range( + Position( + key_b_line, + key_b_col, + ), + Position( + key_b_line, + key_b_col + len(key_b), + ), + ), + ) + yield Diagnostic( + key_a_range, + f'The "{key_a}" cannot be used with "{key_b}".', + DiagnosticSeverity.Error, + source="debputy", + related_information=[ + DiagnosticRelatedInformation( + location=Location( + uri, + key_b_range, + ), + message=f'The attribute "{key_b}" is used here.', + ) + ], + ) + + yield Diagnostic( + key_b_range, + f'The "{key_b}" cannot be used with "{key_a}".', + DiagnosticSeverity.Error, + source="debputy", + related_information=[ + DiagnosticRelatedInformation( + location=Location( + uri, + key_a_range, + ), + message=f'The attribute "{key_a}" is used here.', + ) + ], + ) + + +def _lint_attr_value( + uri: str, + attr: AttributeDescription, + pg: ParserGenerator, + value: Any, + lines: List[str], + position_codec: LintCapablePositionCodec, +) -> Iterable["Diagnostic"]: + attr_type = attr.attribute_type + orig = get_origin(attr_type) + valid_values: Sequence[Any] = tuple() + if orig == Literal: + valid_values = get_args(attr.attribute_type) + elif orig == bool or attr.attribute_type == bool: + valid_values = ("true", "false") + elif isinstance(attr_type, type) and issubclass(attr_type, DebputyDispatchableType): + parser = pg.dispatch_parser_table_for(attr_type) + yield from _lint_content( + uri, + pg, + parser, + value, + lines, + position_codec, + ) + return + + if value in valid_values: + return + # TODO: Emit diagnostic for broken values + return + + +def _lint_declarative_mapping_input_parser( + uri: str, + pg: ParserGenerator, + parser: DeclarativeMappingInputParser, + content: Any, + lines: List[str], + position_codec: LintCapablePositionCodec, +) -> Iterable["Diagnostic"]: + if not isinstance(content, CommentedMap): + return + lc = content.lc + for key, value in content.items(): + attr = parser.manifest_attributes.get(key) + line, col = lc.key(key) + if attr is None: + diag, corrected_key = _unknown_key( + key, + parser.manifest_attributes, + line, + col, + lines, + position_codec, + ) + yield diag + if corrected_key: + key = corrected_key + attr = parser.manifest_attributes.get(corrected_key) + if attr is None: + continue + + yield from _lint_attr_value( + uri, + attr, + pg, + value, + lines, + position_codec, + ) + + for forbidden_key in attr.conflicting_attributes: + if forbidden_key in content: + con_line, con_col = lc.key(forbidden_key) + yield from _conflicting_key( + uri, + key, + forbidden_key, + line, + col, + con_line, + con_col, + lines, + position_codec, + ) + for mx in parser.mutually_exclusive_attributes: + matches = content.keys() & mx + if len(matches) < 2: + continue + key, *others = list(matches) + line, col = lc.key(key) + for other in others: + con_line, con_col = lc.key(other) + yield from _conflicting_key( + uri, + key, + other, + line, + col, + con_line, + con_col, + lines, + position_codec, + ) + + def _lint_content( + uri: str, + pg: ParserGenerator, parser: DeclarativeInputParser[Any], content: Any, lines: List[str], position_codec: LintCapablePositionCodec, -) -> Iterable[Diagnostic]: +) -> Iterable["Diagnostic"]: if isinstance(parser, DispatchingParserBase): if not isinstance(content, CommentedMap): return lc = content.lc for key, value in content.items(): - if not parser.is_known_keyword(key): + is_known = parser.is_known_keyword(key) + if not is_known: line, col = lc.key(key) - key_range = position_codec.range_to_client_units( + diag, corrected_key = _unknown_key( + key, + parser.registered_keywords(), + line, + col, lines, - Range( - Position( - line, - col, - ), - Position( - line, - col + len(key), - ), - ), + position_codec, ) + yield diag + if corrected_key is not None: + key = corrected_key + is_known = True - candidates = detect_possible_typo(key, parser.registered_keywords()) - - yield Diagnostic( - key_range, - f"Unknown or unsupported key {key}", - DiagnosticSeverity.Error, - source="debputy", - data=[propose_correct_text_quick_fix(n) for n in candidates], - ) - else: + if is_known: subparser = parser.parser_for(key) assert subparser is not None - yield from _lint_content(subparser.parser, value, lines, position_codec) + yield from _lint_content( + uri, + pg, + subparser.parser, + value, + lines, + position_codec, + ) elif isinstance(parser, ListWrappedDeclarativeInputParser): if not isinstance(content, CommentedSeq): return subparser = parser.delegate for value in content: - yield from _lint_content(subparser, value, lines, position_codec) + yield from _lint_content(uri, pg, subparser, value, lines, position_codec) elif isinstance(parser, InPackageContextParser): if not isinstance(content, CommentedMap): return for v in content.values(): - yield from _lint_content(parser.delegate, v, lines, position_codec) + yield from _lint_content(uri, pg, parser.delegate, v, lines, position_codec) elif isinstance(parser, DeclarativeMappingInputParser): - if not isinstance(content, CommentedMap): - return - lc = content.lc - for key, value in content.items(): - attr = parser.manifest_attributes.get(key) - if attr is None: - line, col = lc.key(key) - key_range = position_codec.range_to_client_units( - lines, - Range( - Position( - line, - col, - ), - Position( - line, - col + len(key), - ), - ), - ) - - candidates = detect_possible_typo(key, parser.manifest_attributes) - yield Diagnostic( - key_range, - f"Unknown or unsupported key {key}", - DiagnosticSeverity.Error, - source="debputy", - data=[propose_correct_text_quick_fix(n) for n in candidates], - ) + yield from _lint_declarative_mapping_input_parser( + uri, + pg, + parser, + content, + lines, + position_codec, + ) def is_at(position: Position, lc_pos: Tuple[int, int]) -> bool: @@ -469,7 +676,7 @@ def _guess_rule_name(segments: List[Union[str, int]], idx: int) -> str: return "<Bug: unknown rule name>" -def _ecsape(v: str) -> str: +def _escape(v: str) -> str: return '"' + v.replace("\n", "\\n") + '"' @@ -479,7 +686,7 @@ def _insert_snippet(lines: List[str], server_position: Position) -> bool: line = lines[line_no] pos_rhs = line[server_position.character :] if pos_rhs and not pos_rhs.isspace(): - _info(f"No insertion: {_ecsape(line[server_position.character:])}") + _info(f"No insertion: {_escape(line[server_position.character:])}") return False lhs_ws = line[: server_position.character] lhs = lhs_ws.strip() @@ -492,17 +699,17 @@ def _insert_snippet(lines: List[str], server_position: Position) -> bool: snippet = _COMPLETION_HINT_KEY if ":" not in lhs else _COMPLETION_HINT_VALUE new_line = line[: server_position.character] + snippet elif not lhs or (lhs_ws and not lhs_ws[0].isspace()): - _info(f"Insertion of key or value: {_ecsape(line[server_position.character:])}") + _info(f"Insertion of key or value: {_escape(line[server_position.character:])}") # Respect the provided indentation snippet = _COMPLETION_HINT_KEY if ":" not in lhs else _COMPLETION_HINT_VALUE new_line = line[: server_position.character] + snippet elif lhs.isalpha() and ":" not in lhs: - _info(f"Expanding value to a key: {_ecsape(line[server_position.character:])}") + _info(f"Expanding value to a key: {_escape(line[server_position.character:])}") # Respect the provided indentation new_line = line[: server_position.character] + _COMPLETION_HINT_KEY else: c = line[server_position.character] - _info(f"Not touching line: {_ecsape(line)} -- {_ecsape(c)}") + _info(f"Not touching line: {_escape(line)} -- {_escape(c)}") return False _info(f'Evaluating complete on synthetic line: "{new_line}"') lines[line_no] = new_line diff --git a/src/debputy/lsp/lsp_debian_rules.py b/src/debputy/lsp/lsp_debian_rules.py index 86b114c..f05099d 100644 --- a/src/debputy/lsp/lsp_debian_rules.py +++ b/src/debputy/lsp/lsp_debian_rules.py @@ -1,3 +1,4 @@ +import functools import itertools import json import os @@ -152,10 +153,17 @@ def _lint_debian_rules( ) +@functools.lru_cache +def _is_project_trusted(source_root: str) -> bool: + return os.environ.get("DEBPUTY_TRUST_PROJECT", "0") == "1" + + def _run_make_dryrun( source_root: str, lines: List[str], ) -> Optional[Diagnostic]: + if not _is_project_trusted(source_root): + return None try: make_res = subprocess.run( ["make", "--dry-run", "-f", "-", "debhelper-fail-me"], diff --git a/src/debputy/lsp/vendoring/_deb822_repro/__init__.py b/src/debputy/lsp/vendoring/_deb822_repro/__init__.py index cc2b1de..0736189 100644 --- a/src/debputy/lsp/vendoring/_deb822_repro/__init__.py +++ b/src/debputy/lsp/vendoring/_deb822_repro/__init__.py @@ -150,7 +150,7 @@ Deb822ParagraphElement.as_interpreted_dict_view method. Stability of this API --------------------- -The API is subject to change based on feedback from early adoptors and beta +The API is subject to change based on feedback from early adopters and beta testers. That said, the code for valid files is unlikely to change in a backwards incompatible way. diff --git a/src/debputy/lsp/vendoring/_deb822_repro/parsing.py b/src/debputy/lsp/vendoring/_deb822_repro/parsing.py index 1a2da25..e2c638a 100644 --- a/src/debputy/lsp/vendoring/_deb822_repro/parsing.py +++ b/src/debputy/lsp/vendoring/_deb822_repro/parsing.py @@ -3008,7 +3008,7 @@ class Deb822FileElement(Deb822Element): """Inserts a paragraph into the file at the given "index" of paragraphs Note that if the index is between two paragraphs containing a "free - floating" comment (e.g. paragrah/start-of-file, empty line, comment, + floating" comment (e.g. paragraph/start-of-file, empty line, comment, empty line, paragraph) then it is unspecified which "side" of the comment the new paragraph will appear and this may change between versions of python-debian. diff --git a/src/debputy/lsp/vendoring/_deb822_repro/tokens.py b/src/debputy/lsp/vendoring/_deb822_repro/tokens.py index 5db991a..6697a2c 100644 --- a/src/debputy/lsp/vendoring/_deb822_repro/tokens.py +++ b/src/debputy/lsp/vendoring/_deb822_repro/tokens.py @@ -171,7 +171,7 @@ class Deb822Token(Locatable): return self._text def size(self, *, skip_leading_comments: bool = False) -> Range: - # As tokens are an atomtic unit + # As tokens are an atomic unit token_size = self._token_size if token_size is not None: return token_size diff --git a/src/debputy/lsp/vendoring/_deb822_repro/types.py b/src/debputy/lsp/vendoring/_deb822_repro/types.py index 7b78024..181f5c9 100644 --- a/src/debputy/lsp/vendoring/_deb822_repro/types.py +++ b/src/debputy/lsp/vendoring/_deb822_repro/types.py @@ -61,7 +61,7 @@ try: """ FormatterCallback.__doc__ = """\ Formatter callback used with the round-trip safe parser - + See debian._repro_deb822.formatter.format_field for details """ except AttributeError: diff --git a/src/debputy/manifest_parser/declarative_parser.py b/src/debputy/manifest_parser/declarative_parser.py index f18dc1c..850cfa8 100644 --- a/src/debputy/manifest_parser/declarative_parser.py +++ b/src/debputy/manifest_parser/declarative_parser.py @@ -652,7 +652,7 @@ class DebputyParseHint: Generally, this type hint must be placed on the **source** format. Any source attribute matching the parsed format will be ignored. - Mind the assymmetry: The annotation is placed in the **source** format while `debputy` looks at + Mind the asymmetry: The annotation is placed in the **source** format while `debputy` looks at the type of the target attribute to determine if it counts as path. """ return NOT_PATH_HINT @@ -795,7 +795,7 @@ class ParserGenerator: into: ["my-pkg"] ``` - While this is sufficient for programmers, it is a bit ridig for the packager writing the manifest. Therefore, + While this is sufficient for programmers, it is a bit rigid for the packager writing the manifest. Therefore, you can also provide a TypedDict describing the input, enabling more flexibility: >>> class InstallDocsRule(DebputyParsedContent): diff --git a/src/debputy/plugin/api/spec.py b/src/debputy/plugin/api/spec.py index 5d7a261..dba4523 100644 --- a/src/debputy/plugin/api/spec.py +++ b/src/debputy/plugin/api/spec.py @@ -1288,7 +1288,7 @@ class VirtualPath: :param use_fs_path_mode: If True, any changes to the mode on the physical FS path will be recorded as the desired mode of the file when the contextmanager ends. The provided FS path with start with the current mode when `use_fs_path_mode` is True. Otherwise, `debputy` will - ignore the mode of the file system entry and re-use its own current mode + ignore the mode of the file system entry and reuse its own current mode definition. :return: A Context manager that upon entering provides the path to a muable (copy) of this path's `fs_path` attribute. The file on the underlying path may be mutated however diff --git a/src/debputy/plugin/debputy/binary_package_rules.py b/src/debputy/plugin/debputy/binary_package_rules.py index 14d9b91..29c6136 100644 --- a/src/debputy/plugin/debputy/binary_package_rules.py +++ b/src/debputy/plugin/debputy/binary_package_rules.py @@ -96,7 +96,7 @@ def register_binary_package_rules(api: DebputyPluginInitializerProvider) -> None `dpkg-gencontrol`. The value for the `binary-version` key is a string that defines the binary version. Generally, - you will want it to contain one of the versioned related substitution variables such as + you will want it to contain one of the versioned related substitution variables such as `{{DEB_VERSION_UPSTREAM_REVISION}}`. Otherwise, you will have to remember to bump the version manually with each upload as versions cannot be reused and the package would not support binNMUs either. @@ -257,7 +257,7 @@ def register_binary_package_rules(api: DebputyPluginInitializerProvider) -> None manager integration determines that `reload` is not supported. - `restart`: During an upgrade, `restart` the service post upgrade. The service will be left running during the upgrade process. - - `stop-then-start`: Stop the service before the upgrade, preform the upgrade and + - `stop-then-start`: Stop the service before the upgrade, perform the upgrade and then start the service. """ ), diff --git a/src/debputy/plugin/debputy/private_api.py b/src/debputy/plugin/debputy/private_api.py index 3b5087b..6d60333 100644 --- a/src/debputy/plugin/debputy/private_api.py +++ b/src/debputy/plugin/debputy/private_api.py @@ -897,7 +897,7 @@ def register_install_rules(api: DebputyPluginInitializerProvider) -> None: With these two things in mind, it behaves just like the `install` rule. Note: It is often worth considering to use a more specialized version of the `install-docs` - rule when one such is available. If you are looking to install an example or a manpage, + rule when one such is available. If you are looking to install an example or a man page, consider whether `install-examples` or `install-man` might be a better fit for your use-case. """ @@ -1066,18 +1066,18 @@ def register_install_rules(api: DebputyPluginInitializerProvider) -> None: _install_man_rule_handler, source_format=_with_alt_form(ParsedInstallManpageRuleSourceFormat), inline_reference_documentation=reference_documentation( - title="Install manpages (`install-man`)", + title="Install man pages (`install-man`)", description=textwrap.dedent( """\ - Install rule for installing manpages similar to `dh_installman`. It is a shorthand + Install rule for installing man pages similar to `dh_installman`. It is a shorthand over the generic `install` rule with the following key features: 1) The rule can only match files (notably, symlinks cannot be matched by this rule). - 2) The `dest-dir` is computed per source file based on the manpage's section and + 2) The `dest-dir` is computed per source file based on the man page's section and language. 3) The `into` parameter can be omitted as long as there is a exactly one non-`udeb` package listed in `debian/control`. - 4) The rule comes with manpage specific attributes such as `language` and `section` + 4) The rule comes with man page specific attributes such as `language` and `section` for when the auto-detection is insufficient. 5) The rule comes with pre-defined conditional logic for skipping the rule under `DEB_BUILD_OPTIONS=nodoc`, so you do not have to write that conditional yourself. @@ -1111,7 +1111,7 @@ def register_install_rules(api: DebputyPluginInitializerProvider) -> None: textwrap.dedent( """\ Either a package name or a list of package names for which these paths should be - installed as manpages. This key is conditional on whether there are multiple (non-`udeb`) + installed as man pages. This key is conditional on whether there are multiple (non-`udeb`) binary packages listed in `debian/control`. When there is only one (non-`udeb`) binary package, then that binary is the default for `into`. Otherwise, the key is required. """ @@ -1122,7 +1122,7 @@ def register_install_rules(api: DebputyPluginInitializerProvider) -> None: textwrap.dedent( """\ If provided, it must be an integer between 1 and 9 (both inclusive), defining the - section the manpages belong overriding any auto-detection that `debputy` would + section the man pages belong overriding any auto-detection that `debputy` would have performed. """ ), @@ -1134,8 +1134,8 @@ def register_install_rules(api: DebputyPluginInitializerProvider) -> None: If provided, it must be either a 2 letter language code (such as `de`), a 5 letter language + dialect code (such as `pt_BR`), or one of the special keywords `C`, `derive-from-path`, or `derive-from-basename`. The default is `derive-from-path`. - - When `language` is `C`, then the manpages are assumed to be "untranslated". - - When `language` is a language code (with or without dialect), then all manpages + - When `language` is `C`, then the man pages are assumed to be "untranslated". + - When `language` is a language code (with or without dialect), then all man pages matched will be assumed to be translated to that concrete language / dialect. - When `language` is `derive-from-path`, then `debputy` attempts to derive the language from the path (`man/<language>/man<section>`). This matches the @@ -1216,7 +1216,7 @@ def register_install_rules(api: DebputyPluginInitializerProvider) -> None: requested by the packager or a search directory that `debputy` provided automatically (such as `debian/tmp`). Listing other paths will make `debputy` report an error. - - Note that the `path` or `paths` must match at least one entry in + - Note that the `path` or `paths` must match at least one entry in any of the search directories unless *none* of the search directories exist (or the condition in `required-when` evaluates to false). When none of the search directories exist, the discard rule is silently @@ -2604,7 +2604,7 @@ def _install_man_rule_handler( ) if section is None and any(s.raw_match_rule.endswith(".gz") for s in sources): raise ManifestParseException( - "Sorry, compressed manpages are not supported without an explicit `section` definition at the moment." + "Sorry, compressed man pages are not supported without an explicit `section` definition at the moment." " This limitation may be removed in the future. Problematic definition from" f' {attribute_path["sources"]}' ) |