fe7b6349a5c5781a4d1b1ecf16d976e43d0e7f95
Marco Ricci Update copyright notices to...

Marco Ricci authored 2 months ago

1) # SPDX-FileCopyrightText: 2025 Marco Ricci <software@the13thletter.info>
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

2) #
3) # SPDX-Licence-Identifier: MIT
4) 
5) """Internal module.  Do not use.  Contains error strings and functions."""
6) 
7) from __future__ import annotations
8) 
Marco Ricci Provide a function to reloa...

Marco Ricci authored 2 months ago

9) import contextlib
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

10) import datetime
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

11) import enum
12) import gettext
13) import inspect
Marco Ricci Provide a function to reloa...

Marco Ricci authored 2 months ago

14) import os
15) import sys
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

16) import textwrap
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

17) import types
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

18) from typing import TYPE_CHECKING, NamedTuple, TextIO, cast
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

19) 
20) import derivepassphrase as dpp
21) 
22) if TYPE_CHECKING:
Marco Ricci Provide a function to reloa...

Marco Ricci authored 2 months ago

23)     from collections.abc import Iterable, Mapping, Sequence
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

24) 
25)     from typing_extensions import Any, Self
26) 
27) __author__ = dpp.__author__
28) __version__ = dpp.__version__
29) 
30) __all__ = ('PROG_NAME',)
31) 
32) PROG_NAME = 'derivepassphrase'
Marco Ricci Provide a function to reloa...

Marco Ricci authored 2 months ago

33) 
34) 
35) def load_translations(
36)     localedirs: list[str] | None = None,
37)     languages: Sequence[str] | None = None,
38)     class_: type[gettext.NullTranslations] | None = None,
Marco Ricci Fix coverage

Marco Ricci authored 2 months ago

39) ) -> gettext.NullTranslations:  # pragma: no cover
Marco Ricci Provide a function to reloa...

Marco Ricci authored 2 months ago

40)     """Load a translation catalog for derivepassphrase.
41) 
42)     Runs [`gettext.translation`][] under the hood for multiple locale
43)     directories.  `fallback=True` is implied.
44) 
45)     Args:
46)         localedirs:
47)             A list of directories to run [`gettext.translation`][]
48)             against.  Defaults to `$XDG_DATA_HOME/locale` (usually
49)             `~/.local/share/locale`), `{sys.prefix}/share/locale` and
50)             `{sys.base_prefix}/share/locale` if not given.
51)         languages:
52)             Passed directly to [`gettext.translation`][].
53)         class_:
54)             Passed directly to [`gettext.translation`][].
55) 
56)     Returns:
57)         A (potentially dummy) translation catalog.
58) 
59)     """
60)     if localedirs is None:
61)         if sys.platform.startswith('win'):
62)             xdg_data_home = os.environ.get(
63)                 'APPDATA',
64)                 os.path.expanduser('~'),
65)             )
66)         elif os.environ.get('XDG_DATA_HOME'):
67)             xdg_data_home = os.environ['XDG_DATA_HOME']
68)         else:
69)             xdg_data_home = os.path.join(
70)                 os.path.expanduser('~'), '.local', 'share'
71)             )
72)         localedirs = [
73)             os.path.join(xdg_data_home, 'locale'),
74)             os.path.join(sys.prefix, 'share', 'locale'),
75)             os.path.join(sys.base_prefix, 'share', 'locale'),
76)         ]
77)     for localedir in localedirs:
78)         with contextlib.suppress(OSError):
79)             return gettext.translation(
80)                 PROG_NAME,
81)                 localedir=localedir,
82)                 languages=languages,
83)                 class_=class_,
84)             )
85)     return gettext.NullTranslations()
86) 
87) 
88) translation = load_translations()
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

89) 
90) 
91) class TranslatableString(NamedTuple):
92)     singular: str
93)     plural: str
94)     l10n_context: str
95)     translator_comments: str
96)     flags: frozenset[str]
97) 
98) 
99) def _prepare_translatable(
100)     msg: str,
101)     comments: str = '',
102)     context: str = '',
103)     plural_msg: str = '',
104)     *,
105)     flags: Iterable[str] = (),
106) ) -> TranslatableString:
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

107)     def maybe_rewrap(string: str) -> str:
108)         string = inspect.cleandoc(string)
109)         if not any(s.strip() == '\b' for s in string.splitlines()):
110)             string = '\n'.join(
111)                 textwrap.wrap(
112)                     string,
113)                     width=float('inf'),  # type: ignore[arg-type]
114)                     fix_sentence_endings=True,
115)                 )
116)             )
117)         else:  # pragma: no cover
118)             string = ''.join(
119)                 s
120)                 for s in string.splitlines(True)  # noqa: FBT003
121)                 if s.strip() == '\b'
122)             )
123)         return string
124) 
125)     msg = maybe_rewrap(msg)
126)     plural_msg = maybe_rewrap(plural_msg)
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

127)     context = context.strip()
128)     comments = inspect.cleandoc(comments)
129)     flags = (
130)         frozenset(f.strip() for f in flags)
131)         if not isinstance(flags, str)
132)         else frozenset({flags})
133)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

134)     assert '{' not in msg or bool(
135)         flags & {'python-brace-format', 'no-python-brace-format'}
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

136)     ), f'Missing flag for how to deal with brace in {msg!r}'
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

137)     assert '%' not in msg or bool(
138)         flags & {'python-format', 'no-python-format'}
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

139)     ), f'Missing flag for how to deal with percent character in {msg!r}'
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

140)     assert (
141)         not flags & {'python-format', 'python-brace-format'}
142)         or '%' in msg
143)         or '{' in msg
144)     ), f'Missing format string parameters in {msg!r}'
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

145)     return TranslatableString(msg, plural_msg, context, comments, flags)
146) 
147) 
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

148) class TranslatedString:
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

149)     def __init__(
150)         self,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

151)         template: (
152)             str
153)             | TranslatableString
154)             | Label
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

155)             | DebugMsgTemplate
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

156)             | InfoMsgTemplate
157)             | WarnMsgTemplate
158)             | ErrMsgTemplate
159)         ),
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

160)         args_dict: Mapping[str, Any] = types.MappingProxyType({}),
161)         /,
162)         **kwargs: Any,  # noqa: ANN401
163)     ) -> None:
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

164)         if isinstance(
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

165)             template, (Label, DebugMsgTemplate, InfoMsgTemplate, WarnMsgTemplate, ErrMsgTemplate)
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

166)         ):
Marco Ricci Add remaining re-linting ch...

Marco Ricci authored 2 months ago

167)             template = cast('TranslatableString', template.value)
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

168)         self.template = template
169)         self.kwargs = {**args_dict, **kwargs}
170)         self._rendered: str | None = None
171) 
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

172)     def __bool__(self) -> bool:
173)         return bool(str(self))
174) 
175)     def __eq__(self, other: object) -> bool:  # pragma: no cover
176)         return str(self) == other
177) 
178)     def __hash__(self) -> int:  # pragma: no cover
179)         return hash(str(self))
180) 
181)     def __repr__(self) -> str:  # pragma: no cover
182)         return (
183)             f'{self.__class__.__name__}({self.template!r}, '
184)             f'{dict(self.kwargs)!r})'
185)         )
186) 
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

187)     def __str__(self) -> str:
188)         if self._rendered is None:
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

189)             # raw str support is currently unneeded, so excluded from coverage
190)             if isinstance(self.template, str):  # pragma: no cover
191)                 context = None
192)                 template = self.template
193)             else:
194)                 context = self.template.l10n_context
195)                 template = self.template.singular
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

196)             if context is not None:
197)                 template = translation.pgettext(context, template)
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

198)             else:  # pragma: no cover
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

199)                 template = translation.gettext(template)
200)             self._rendered = template.format(**self.kwargs)
201)         return self._rendered
202) 
203)     def maybe_without_filename(self) -> Self:
204)         if (
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

205)             not isinstance(self.template, str)
206)             and self.kwargs.get('filename') is None
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

207)             and ': {filename!r}' in self.template.singular
208)         ):
209)             singular = ''.join(
210)                 self.template.singular.split(': {filename!r}', 1)
211)             )
212)             plural = (
213)                 ''.join(self.template.plural.split(': {filename!r}', 1))
214)                 if self.template.plural
215)                 else self.template.plural
216)             )
217)             return self.__class__(
218)                 self.template._replace(singular=singular, plural=plural),
219)                 self.kwargs,
220)             )
221)         return self
222) 
223) 
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

224) class Label(enum.Enum):
225)     DEPRECATION_WARNING_LABEL = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

226)         comments=r"""
227)         TRANSLATORS: This is a short label that will be prepended to
228)         a warning message, e.g., "Deprecation warning: A subcommand will
229)         be required in v1.0."
230)         """,
231)         msg='Deprecation warning',
232)         context='diagnostic label',
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

233)     )
234)     WARNING_LABEL = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

235)         comments=r"""
236)         TRANSLATORS: This is a short label that will be prepended to
237)         a warning message, e.g., "Warning: An empty service name is not
238)         supported by vault(1)."
239)         """,
240)         msg='Warning',
241)         context='diagnostic label',
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

242)     )
Marco Ricci Fix phrasing of "Cannot upd...

Marco Ricci authored 2 months ago

243)     CANNOT_UPDATE_SETTINGS_METAVAR_SETTINGS_TYPE_GLOBAL = (
244)         _prepare_translatable(
245)             comments=r"""
246)             TRANSLATORS: This is one of two values of the settings_type
247)             metavar used in the CANNOT_UPDATE_SETTINGS_NO_SETTINGS
248)             entry.  It is only used there.  The full sentence then
249)             reads: "Cannot update the global settings without any given
250)             settings."
251)             """,
252)             msg='global settings',
253)             context='diagnostic label (metavar value)',
254)         )
255)     )
256)     CANNOT_UPDATE_SETTINGS_METAVAR_SETTINGS_TYPE_SERVICE = (
257)         _prepare_translatable(
258)             comments=r"""
259)             TRANSLATORS: This is one of two values of the settings_type
260)             metavar used in the CANNOT_UPDATE_SETTINGS_NO_SETTINGS
261)             entry.  It is only used there.  The full sentence then
262)             reads: "Cannot update the service-specific settings without
263)             any given settings."
264)             """,
265)             msg='service-specific settings',
266)             context='diagnostic label (metavar value)',
267)         )
268)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

269)     DERIVEPASSPHRASE_01 = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

270)         comments=r"""
271)         TRANSLATORS: This is the first paragraph of the command help
272)         text, but it also appears (in truncated form, if necessary) as
273)         one-line help text for this command.  The translation should
274)         thus be as meaningful as possible even if truncated.
275)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

276)         msg="""
277)         Derive a strong passphrase, deterministically, from a master secret.
278)         """,
279)         context='help text (long form)',
280)     )
281)     DERIVEPASSPHRASE_02 = _prepare_translatable(
282)         msg="""
283)         The currently implemented subcommands are "vault" (for the
284)         scheme used by vault) and "export" (for exporting foreign
285)         configuration data).  See the respective `--help` output for
286)         instructions.  If no subcommand is given, we default to "vault".
287)         """,
288)         comments='',
289)         context='help text (long form)',
290)     )
291)     DERIVEPASSPHRASE_03 = _prepare_translatable(
292)         msg="""
293)         Deprecation notice: Defaulting to "vault" is deprecated.
294)         Starting in v1.0, the subcommand must be specified explicitly.
295)         """,
296)         comments='',
297)         context='help text (long form)',
298)     )
299)     DERIVEPASSPHRASE_EPILOG_01 = _prepare_translatable(
300)         msg=r"""
301)         Configuration is stored in a directory according to the
302)         `DERIVEPASSPHRASE_PATH` variable, which defaults to
303)         `~/.derivepassphrase` on UNIX-like systems and
304)         `C:\Users\<user>\AppData\Roaming\Derivepassphrase` on Windows.
305)         """,
306)         comments='',
307)         context='help text (long form)',
308)     )
309)     DERIVEPASSPHRASE_EXPORT_01 = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

310)         comments=r"""
311)         TRANSLATORS: This is the first paragraph of the command help
312)         text, but it also appears (in truncated form, if necessary) as
313)         one-line help text for this command.  The translation should
314)         thus be as meaningful as possible even if truncated.
315)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

316)         msg="""
317)         Export a foreign configuration to standard output.
318)         """,
319)         context='help text (long form)',
320)     )
321)     DERIVEPASSPHRASE_EXPORT_02 = _prepare_translatable(
322)         msg="""
323)         The only available subcommand is "vault", which implements the
324)         vault-native configuration scheme.  If no subcommand is given,
325)         we default to "vault".
326)         """,
327)         comments='',
328)         context='help text (long form)',
329)     )
330)     DERIVEPASSPHRASE_EXPORT_03 = DERIVEPASSPHRASE_03
331)     DERIVEPASSPHRASE_EXPORT_VAULT_01 = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

332)         comments=r"""
333)         TRANSLATORS: This is the first paragraph of the command help
334)         text, but it also appears (in truncated form, if necessary) as
335)         one-line help text for this command.  The translation should
336)         thus be as meaningful as possible even if truncated.
337)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

338)         msg="""
339)         Export a vault-native configuration to standard output.
340)         """,
341)         context='help text (long form)',
342)     )
343)     DERIVEPASSPHRASE_EXPORT_VAULT_02 = _prepare_translatable(
344)         msg="""
345)         Depending on the configuration format, {path_metavar!s} may
346)         either be a file or a directory.  We support the vault "v0.2",
347)         "v0.3" and "storeroom" formats.
348)         """,
349)         comments='',
350)         context='help text (long form)',
351)         flags='python-brace-format',
352)     )
353)     DERIVEPASSPHRASE_EXPORT_VAULT_03 = _prepare_translatable(
354)         msg="""
355)         If {path_metavar!s} is explicitly given as `VAULT_PATH`, then
356)         use the `VAULT_PATH` environment variable to determine the
357)         correct path.  (Use `./VAULT_PATH` or similar to indicate
358)         a file/directory actually named `VAULT_PATH`.)
359)         """,
360)         comments='',
361)         context='help text (long form)',
362)         flags='python-brace-format',
363)     )
364)     DERIVEPASSPHRASE_VAULT_01 = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

365)         comments=r"""
366)         TRANSLATORS: This is the first paragraph of the command help
367)         text, but it also appears (in truncated form, if necessary) as
368)         one-line help text for this command.  The translation should
369)         thus be as meaningful as possible even if truncated.
370)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

371)         msg="""
372)         Derive a passphrase using the vault derivation scheme.
373)         """,
374)         context='help text (long form)',
375)     )
376)     DERIVEPASSPHRASE_VAULT_02 = _prepare_translatable(
377)         msg="""
378)         If operating on global settings, or importing/exporting
379)         settings, then {service_metavar!s} must be omitted.  Otherwise
380)         it is required.
381)         """,
382)         comments='',
383)         context='help text (long form)',
384)         flags='python-brace-format',
385)     )
386)     DERIVEPASSPHRASE_VAULT_EPILOG_01 = _prepare_translatable(
387)         msg="""
388)         WARNING: There is NO WAY to retrieve the generated passphrases
389)         if the master passphrase, the SSH key, or the exact passphrase
390)         settings are lost, short of trying out all possible
391)         combinations.  You are STRONGLY advised to keep independent
392)         backups of the settings and the SSH key, if any.
393)         """,
394)         comments='',
395)         context='help text (long form)',
396)     )
397)     DERIVEPASSPHRASE_VAULT_EPILOG_02 = _prepare_translatable(
398)         msg="""
399)         The configuration is NOT encrypted, and you are STRONGLY
400)         discouraged from using a stored passphrase.
401)         """,
402)         comments='',
403)         context='help text (long form)',
404)     )
405)     DEPRECATED_COMMAND_LABEL = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

406)         comments=r"""
407)         TRANSLATORS: We use this format string to indicate, at the
408)         beginning of a command's help text, that this command is
409)         deprecated.
410)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

411)         msg='(Deprecated) {text}',
412)         context='help text (long form, label)',
413)         flags='python-brace-format',
414)     )
415)     DEBUG_OPTION_HELP_TEXT = _prepare_translatable(
416)         'also emit debug information (implies --verbose)',
417)         comments='',
418)         context='help text (option one-line description)',
419)     )
420)     EXPORT_VAULT_FORMAT_HELP_TEXT = _prepare_translatable(
421)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

422)         TRANSLATORS: The defaults_hint is
423)         Label.EXPORT_VAULT_FORMAT_DEFAULTS_HELP_TEXT, the metavar is
424)         Label.EXPORT_VAULT_FORMAT_METAVAR_FMT.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

425)         """,
426)         msg=r"""
427)         try the following storage format {metavar!s}; may be
428)         specified multiple times, formats will be tried in order
429)         {defaults_hint!s}
430)         """,
431)         context='help text (option one-line description)',
432)         flags='python-brace-format',
433)     )
434)     EXPORT_VAULT_FORMAT_DEFAULTS_HELP_TEXT = _prepare_translatable(
435)         comments=r"""
436)         TRANSLATORS: See EXPORT_VAULT_FORMAT_HELP_TEXT.  The format
437)         names/labels "v0.3", "v0.2" and "storeroom" should not be
438)         translated.
439)         """,
440)         msg=r"""
441)         (default: v0.3, v0.2, storeroom)
442)         """,
443)         context='help text (option one-line description)',
444)     )
445)     EXPORT_VAULT_KEY_HELP_TEXT = _prepare_translatable(
446)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

447)         TRANSLATORS: The defaults_hint is
448)         Label.EXPORT_VAULT_KEY_DEFAULTS_HELP_TEXT, the metavar is
449)         Label.EXPORT_VAULT_KEY_METAVAR_K.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

450)         """,
451)         msg=r"""
452)         use {metavar!s} as the storage master key {defaults_hint!s}
453)         """,
454)         context='help text (option one-line description)',
455)         flags='python-brace-format',
456)     )
457)     EXPORT_VAULT_KEY_DEFAULTS_HELP_TEXT = _prepare_translatable(
458)         comments=r"""
459)         TRANSLATORS: See EXPORT_VAULT_KEY_HELP_TEXT.
460)         """,
461)         msg=r"""
462)         (default: check the `VAULT_KEY`, `LOGNAME`, `USER`, or
463)         `USERNAME` environment variables)
464)         """,
465)         context='help text (option one-line description)',
466)     )
Marco Ricci Reimplement `--help` and `-...

Marco Ricci authored 2 months ago

467)     HELP_OPTION_HELP_TEXT = _prepare_translatable(
468)         'show this help text, then exit',
469)         comments='',
470)         context='help text (option one-line description)',
471)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

472)     QUIET_OPTION_HELP_TEXT = _prepare_translatable(
473)         'suppress even warnings, emit only errors',
474)         comments='',
475)         context='help text (option one-line description)',
476)     )
477)     VERBOSE_OPTION_HELP_TEXT = _prepare_translatable(
478)         'emit extra/progress information to standard error',
479)         comments='',
480)         context='help text (option one-line description)',
481)     )
Marco Ricci Reimplement `--help` and `-...

Marco Ricci authored 2 months ago

482)     VERSION_OPTION_HELP_TEXT = _prepare_translatable(
483)         'show applicable version information, then exit',
484)         comments='',
485)         context='help text (option one-line description)',
486)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

487) 
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

488)     DERIVEPASSPHRASE_VAULT_PHRASE_HELP_TEXT = _prepare_translatable(
489)         msg='prompt for a master passphrase',
490)         comments='',
491)         context='help text (option one-line description)',
492)     )
493)     DERIVEPASSPHRASE_VAULT_KEY_HELP_TEXT = _prepare_translatable(
494)         msg='select a suitable SSH key from the SSH agent',
495)         comments='',
496)         context='help text (option one-line description)',
497)     )
498)     DERIVEPASSPHRASE_VAULT_LENGTH_HELP_TEXT = _prepare_translatable(
499)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

500)         TRANSLATORS: The metavar is
501)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

502)         """,
503)         msg='ensure a passphrase length of {metavar!s} characters',
504)         context='help text (option one-line description)',
505)         flags='python-brace-format',
506)     )
507)     DERIVEPASSPHRASE_VAULT_REPEAT_HELP_TEXT = _prepare_translatable(
508)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

509)         TRANSLATORS: The metavar is
510)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

511)         """,
512)         msg='forbid any run of {metavar!s} identical characters',
513)         context='help text (option one-line description)',
514)         flags='python-brace-format',
515)     )
516)     DERIVEPASSPHRASE_VAULT_LOWER_HELP_TEXT = _prepare_translatable(
517)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

518)         TRANSLATORS: The metavar is
519)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

520)         """,
521)         msg='ensure at least {metavar!s} lowercase characters',
522)         context='help text (option one-line description)',
523)         flags='python-brace-format',
524)     )
525)     DERIVEPASSPHRASE_VAULT_UPPER_HELP_TEXT = _prepare_translatable(
526)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

527)         TRANSLATORS: The metavar is
528)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

529)         """,
530)         msg='ensure at least {metavar!s} uppercase characters',
531)         context='help text (option one-line description)',
532)         flags='python-brace-format',
533)     )
534)     DERIVEPASSPHRASE_VAULT_NUMBER_HELP_TEXT = _prepare_translatable(
535)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

536)         TRANSLATORS: The metavar is
537)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

538)         """,
539)         msg='ensure at least {metavar!s} digits',
540)         context='help text (option one-line description)',
541)         flags='python-brace-format',
542)     )
543)     DERIVEPASSPHRASE_VAULT_SPACE_HELP_TEXT = _prepare_translatable(
544)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

545)         TRANSLATORS: The metavar is
546)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

547)         """,
548)         msg='ensure at least {metavar!s} spaces',
549)         context='help text (option one-line description)',
550)         flags='python-brace-format',
551)     )
552)     DERIVEPASSPHRASE_VAULT_DASH_HELP_TEXT = _prepare_translatable(
553)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

554)         TRANSLATORS: The metavar is
555)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

556)         """,
557)         msg='ensure at least {metavar!s} "-" or "_" characters',
558)         context='help text (option one-line description)',
559)         flags='python-brace-format',
560)     )
561)     DERIVEPASSPHRASE_VAULT_SYMBOL_HELP_TEXT = _prepare_translatable(
562)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

563)         TRANSLATORS: The metavar is
564)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

565)         """,
566)         msg='ensure at least {metavar!s} symbol characters',
567)         context='help text (option one-line description)',
568)         flags='python-brace-format',
569)     )
570) 
571)     DERIVEPASSPHRASE_VAULT_NOTES_HELP_TEXT = _prepare_translatable(
572)         msg='spawn an editor to edit notes for {service_metavar!s}',
573)         comments='',
574)         context='help text (option one-line description)',
575)         flags='python-brace-format',
576)     )
577)     DERIVEPASSPHRASE_VAULT_CONFIG_HELP_TEXT = _prepare_translatable(
578)         msg='save the given settings for {service_metavar!s}, or global',
579)         comments='',
580)         context='help text (option one-line description)',
581)         flags='python-brace-format',
582)     )
583)     DERIVEPASSPHRASE_VAULT_DELETE_HELP_TEXT = _prepare_translatable(
584)         msg='delete the settings for {service_metavar!s}',
585)         comments='',
586)         context='help text (option one-line description)',
587)         flags='python-brace-format',
588)     )
589)     DERIVEPASSPHRASE_VAULT_DELETE_GLOBALS_HELP_TEXT = _prepare_translatable(
590)         msg='delete the global settings',
591)         comments='',
592)         context='help text (option one-line description)',
593)     )
594)     DERIVEPASSPHRASE_VAULT_DELETE_ALL_HELP_TEXT = _prepare_translatable(
595)         msg='delete all settings',
596)         comments='',
597)         context='help text (option one-line description)',
598)     )
599)     DERIVEPASSPHRASE_VAULT_EXPORT_HELP_TEXT = _prepare_translatable(
600)         comments="""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

601)         TRANSLATORS: The metavar is
602)         Label.STORAGE_MANAGEMENT_METAVAR_SERVICE.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

603)         """,
604)         msg='export all saved settings to {metavar!s}',
605)         context='help text (option one-line description)',
606)         flags='python-brace-format',
607)     )
608)     DERIVEPASSPHRASE_VAULT_IMPORT_HELP_TEXT = _prepare_translatable(
609)         comments="""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

610)         TRANSLATORS: The metavar is
611)         Label.STORAGE_MANAGEMENT_METAVAR_SERVICE.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

612)         """,
613)         msg='import saved settings from {metavar!s}',
614)         context='help text (option one-line description)',
615)         flags='python-brace-format',
616)     )
617)     DERIVEPASSPHRASE_VAULT_OVERWRITE_HELP_TEXT = _prepare_translatable(
618)         comments="""
619)         TRANSLATORS: The corresponding option is displayed as
620)         "--overwrite-existing / --merge-existing", so you may want to
621)         hint that the default (merge) is the second of those options.
622)         """,
623)         msg='overwrite or merge (default) the existing configuration',
624)         context='help text (option one-line description)',
625)     )
626)     DERIVEPASSPHRASE_VAULT_UNSET_HELP_TEXT = _prepare_translatable(
627)         comments="""
628)         TRANSLATORS: The corresponding option is displayed as
629)         "--unset=phrase|key|...|symbol", so the "given setting" is
630)         referring to "phrase", "key", "lower", ..., or "symbol",
631)         respectively.  "with --config" here means that the user must
632)         also specify "--config" for this option to have any effect.
633)         """,
634)         msg="""
635)         with --config, also unsets the given setting; may be specified
636)         multiple times
637)         """,
638)         context='help text (option one-line description)',
639)     )
640)     DERIVEPASSPHRASE_VAULT_EXPORT_AS_HELP_TEXT = _prepare_translatable(
641)         comments="""
642)         TRANSLATORS: The corresponding option is displayed as
643)         "--export-as=json|sh", so json refers to the JSON format
644)         (default) and sh refers to the POSIX sh format.
645)         """,
646)         msg='when exporting, export as JSON (default) or POSIX sh',
647)         context='help text (option one-line description)',
648)     )
649) 
650)     EXPORT_VAULT_FORMAT_METAVAR_FMT = _prepare_translatable(
651)         msg='FMT',
652)         comments='',
653)         context='help text, metavar (export vault subcommand)',
654)     )
655)     EXPORT_VAULT_KEY_METAVAR_K = _prepare_translatable(
656)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

657)         TRANSLATORS: See Label.EXPORT_VAULT_KEY_HELP_TEXT.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

658)         """,
659)         msg='K',
660)         context='help text, metavar (export vault subcommand)',
661)     )
662)     EXPORT_VAULT_METAVAR_PATH = _prepare_translatable(
663)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

664)         TRANSLATORS: Used as "path_metavar" in
665)         Label.DERIVEPASSPHRASE_EXPORT_VAULT_02 and others.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

666)         """,
667)         msg='PATH',
668)         context='help text, metavar (export vault subcommand)',
669)     )
670)     PASSPHRASE_GENERATION_METAVAR_NUMBER = _prepare_translatable(
671)         comments=r"""
672)         TRANSLATORS: This metavar is also used in a matching epilog.
673)         """,
674)         msg='NUMBER',
675)         context='help text, metavar (passphrase generation group)',
676)     )
677)     STORAGE_MANAGEMENT_METAVAR_PATH = _prepare_translatable(
678)         comments=r"""
679)         TRANSLATORS: This metavar is also used in multiple one-line help
680)         texts.
681)         """,
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

682)         msg='PATH',
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

683)         context='help text, metavar (storage management group)',
684)     )
685)     VAULT_METAVAR_SERVICE = _prepare_translatable(
686)         comments=r"""
687)         TRANSLATORS: This metavar is also used in multiple one-line help
688)         texts, as "service_metavar".
689)         """,
690)         msg='SERVICE',
691)         context='help text, metavar (vault subcommand)',
692)     )
693)     CONFIGURATION_EPILOG = _prepare_translatable(
694)         'Use $VISUAL or $EDITOR to configure the spawned editor.',
695)         comments='',
696)         context='help text, option group epilog (configuration group)',
697)     )
698)     PASSPHRASE_GENERATION_EPILOG = _prepare_translatable(
699)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

700)         TRANSLATORS: The metavar is
701)         Label.PASSPHRASE_GENERATION_METAVAR_NUMBER.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

702)         """,
703)         msg=r"""
704)         Use {metavar!s}=0 to exclude a character type from the output.
705)         """,
706)         context='help text, option group epilog (passphrase generation group)',
707)         flags='python-brace-format',
708)     )
709)     STORAGE_MANAGEMENT_EPILOG = _prepare_translatable(
710)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

711)         TRANSLATORS: The metavar is
712)         Label.STORAGE_MANAGEMENT_METAVAR_PATH.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

713)         """,
714)         msg=r"""
715)         Using "-" as {metavar!s} for standard input/standard output
716)         is supported.
717)         """,
718)         context='help text, option group epilog (storage management group)',
719)         flags='python-brace-format',
720)     )
721)     COMMANDS_LABEL = _prepare_translatable(
722)         'Commands', comments='', context='help text, option group name'
723)     )
724)     COMPATIBILITY_OPTION_LABEL = _prepare_translatable(
725)         'Compatibility and extension options',
726)         comments='',
727)         context='help text, option group name',
728)     )
729)     CONFIGURATION_LABEL = _prepare_translatable(
730)         'Configuration', comments='', context='help text, option group name'
731)     )
732)     LOGGING_LABEL = _prepare_translatable(
733)         'Logging', comments='', context='help text, option group name'
734)     )
735)     OPTIONS_LABEL = _prepare_translatable(
736)         'Options', comments='', context='help text, option group name'
737)     )
738)     OTHER_OPTIONS_LABEL = _prepare_translatable(
739)         'Other options', comments='', context='help text, option group name'
740)     )
741)     PASSPHRASE_GENERATION_LABEL = _prepare_translatable(
742)         'Passphrase generation',
743)         comments='',
744)         context='help text, option group name',
745)     )
746)     STORAGE_MANAGEMENT_LABEL = _prepare_translatable(
747)         'Storage management',
748)         comments='',
749)         context='help text, option group name',
750)     )
Marco Ricci Reimplement `--help` and `-...

Marco Ricci authored 2 months ago

751)     VERSION_INFO_TEXT = _prepare_translatable(
752)         msg=r"""
753)         {PROG_NAME!s} {__version__}
754)         """,  # noqa: RUF027
755)         comments='',
756)         context='help text, version info text',
757)         flags='python-brace-format',
758)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

759)     CONFIRM_THIS_CHOICE_PROMPT_TEXT = _prepare_translatable(
760)         comments=r"""
761)         TRANSLATORS: There is no support for "yes" or "no" in other
762)         languages than English, so it is advised that your translation
763)         makes it clear that only the strings "y", "yes", "n" or "no" are
764)         supported, even if the prompt becomes a bit longer.
765)         """,
766)         msg='Confirm this choice? (y/N)',
767)         context='interactive prompt',
768)     )
769)     SUITABLE_SSH_KEYS_LABEL = _prepare_translatable(
770)         comments=r"""
771)         TRANSLATORS: This label is the heading of the list of suitable
772)         SSH keys.
773)         """,
774)         msg='Suitable SSH keys:',
775)         context='interactive prompt',
776)     )
777)     YOUR_SELECTION_PROMPT_TEXT = _prepare_translatable(
778)         'Your selection? (1-{n}, leave empty to abort)',
779)         comments='',
780)         context='interactive prompt',
781)         flags='python-brace-format',
782)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

783) 
784) 
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

785) class DebugMsgTemplate(enum.Enum):
786)     BUCKET_ITEM_FOUND = _prepare_translatable(
787)         comments=r"""
788)         TRANSLATORS: This message is emitted by the vault configuration
789)         exporter for "storeroom"-type configuration directories.  The
790)         system stores entries in different "buckets" of a hash table.
791)         Here, we report on a single item (path and value) we discovered
792)         after decrypting the whole bucket.  (We ensure the path and
793)         value are printable as-is.)
794)         """,
795)         msg='Found bucket item: {path} -> {value}',
796)         context='debug message',
797)         flags='python-brace-format',
798)     )
799)     DECRYPT_BUCKET_ITEM_INFO = _prepare_translatable(
800)         comments=r"""
801)         TRANSLATORS: "AES256-CBC" and "PKCS#7" are, in essence, names of
802)         formats, and should not be translated.  "IV" means
803)         "initialization vector", and is specifically a cryptographic
804)         term, as are "plaintext" and "ciphertext".
805)         """,
806)         msg="""
807)         Decrypt bucket item contents:
808) 
809)           \b
810)           Encryption key (master key): {enc_key}
811)           Encryption cipher: AES256-CBC with PKCS#7 padding
812)           Encryption IV: {iv}
813)           Encrypted ciphertext: {ciphertext}
814)           Plaintext: {plaintext}
815)         """,
816)         context='debug message',
817)         flags='python-brace-format',
818)     )
819)     DECRYPT_BUCKET_ITEM_KEY_INFO = _prepare_translatable(
820)         msg="""
821)         Decrypt bucket item:
822) 
823)           \b
824)           Plaintext: {plaintext}
825)           Encryption key (master key): {enc_key}
826)           Signing key (master key): {sign_key}
827)         """,
828)         comments='',
829)         context='debug message',
830)         flags='python-brace-format',
831)     )
832)     DECRYPT_BUCKET_ITEM_MAC_INFO = _prepare_translatable(
833)         comments=r"""
834)         TRANSLATORS: The MAC stands for "message authentication code",
835)         which guarantees the authenticity of the message to anyone who
836)         holds the corresponding key, similar to a digital signature.
837)         The acronym "MAC" is assumed to be well-known to the English
838)         target audience, or at least discoverable by them; they *are*
839)         asking for debug output, after all.  Please use your judgement
840)         as to whether to translate this term or not, expanded or not.
841)         """,
842)         msg="""
843)         Decrypt bucket item contents:
844) 
845)           \b
846)           MAC key: {sign_key}
847)           Authenticated content: {ciphertext}
848)           Claimed MAC value: {claimed_mac}
849)           Computed MAC value: {actual_mac}
850)         """,
851)         context='debug message',
852)         flags='python-brace-format',
853)     )
854)     DECRYPT_BUCKET_ITEM_SESSION_KEYS_INFO = _prepare_translatable(
855)         comments=r"""
856)         TRANSLATORS: "AES256-CBC" and "PKCS#7" are, in essence, names of
857)         formats, and should not be translated.  "IV" means
858)         "initialization vector", and is specifically a cryptographic
859)         term, as are "plaintext" and "ciphertext".
860)         """,
861)         msg="""
862)         Decrypt bucket item session keys:
863) 
864)           \b
865)           Encryption key (master key): {enc_key}
866)           Encryption cipher: AES256-CBC with PKCS#7 padding
867)           Encryption IV: {iv}
868)           Encrypted ciphertext: {ciphertext}
869)           Plaintext: {plaintext}
870)           Parsed plaintext: {code}
871)         """,
872)         context='debug message',
873)         flags='python-brace-format',
874)     )
875)     DECRYPT_BUCKET_ITEM_SESSION_KEYS_MAC_INFO = _prepare_translatable(
876)         comments=r"""
877)         TRANSLATORS: The MAC stands for "message authentication code",
878)         which guarantees the authenticity of the message to anyone who
879)         holds the corresponding key, similar to a digital signature.
880)         The acronym "MAC" is assumed to be well-known to the English
881)         target audience, or at least discoverable by them; they *are*
882)         asking for debug output, after all.  Please use your judgement
883)         as to whether to translate this term or not, expanded or not.
884)         """,
885)         msg="""
886)         Decrypt bucket item session keys:
887) 
888)           \b
889)           MAC key (master key): {sign_key}
890)           Authenticated content: {ciphertext}
891)           Claimed MAC value: {claimed_mac}
892)           Computed MAC value: {actual_mac}
893)         """,
894)         context='debug message',
895)         flags='python-brace-format',
896)     )
897)     DERIVED_MASTER_KEYS_KEYS = _prepare_translatable(
898)         msg="""
899)         Derived master keys' keys:
900) 
901)           \b
902)           Encryption key: {enc_key}
903)           Signing key: {sign_key}
904)           Password: {pw_bytes}
905)           Function call: pbkdf2(algorithm={algorithm!r}, length={length!r}, salt={salt!r}, iterations={iterations!r})
906) 
907)         """,  # noqa: E501
908)         comments='',
909)         context='debug message',
910)         flags='python-brace-format',
911)     )
912)     DIRECTORY_CONTENTS_CHECK_OK = _prepare_translatable(
913)         comments=r"""
914)         TRANSLATORS: This message is emitted by the vault configuration
915)         exporter for "storeroom"-type configuration directories, while
916)         "assembling" the items stored in the configuration according to
917)         the item's "path".  Each "directory" in the path contains a list
918)         of children it claims to contain, and this list must be matched
919)         against the actual discovered items.  Now, at the end, we
920)         actually confirm the claim.  (We would have already thrown an
921)         error here otherwise.)
922)         """,
923)         msg='Directory contents check OK: {path} -> {contents}',
924)         context='debug message',
925)         flags='python-brace-format',
926)     )
927)     MASTER_KEYS_DATA_MAC_INFO = _prepare_translatable(
928)         comments=r"""
929)         TRANSLATORS: The MAC stands for "message authentication code",
930)         which guarantees the authenticity of the message to anyone who
931)         holds the corresponding key, similar to a digital signature.
932)         The acronym "MAC" is assumed to be well-known to the English
933)         target audience, or at least discoverable by them; they *are*
934)         asking for debug output, after all.  Please use your judgement
935)         as to whether to translate this term or not, expanded or not.
936)         """,
937)         msg="""
938)         Master keys data:
939) 
940)           \b
941)           MAC key: {sign_key}
942)           Authenticated content: {ciphertext}
943)           Claimed MAC value: {claimed_mac}
944)           Computed MAC value: {actual_mac}
945)         """,
946)         context='debug message',
947)         flags='python-brace-format',
948)     )
949)     POSTPONING_DIRECTORY_CONTENTS_CHECK = _prepare_translatable(
950)         comments=r"""
951)         TRANSLATORS: This message is emitted by the vault configuration
952)         exporter for "storeroom"-type configuration directories, while
953)         "assembling" the items stored in the configuration according to
954)         the item's "path".  Each "directory" in the path contains a list
955)         of children it claims to contain, and this list must be matched
956)         against the actual discovered items.  When emitting this
957)         message, we merely indicate that we saved the "claimed" list for
958)         this directory for later.
959)         """,
960)         msg='Postponing directory contents check: {path} -> {contents}',
961)         context='debug message',
962)         flags='python-brace-format',
963)     )
964)     SETTING_CONFIG_STRUCTURE_CONTENTS = _prepare_translatable(
965)         comments=r"""
966)         TRANSLATORS: This message is emitted by the vault configuration
967)         exporter for "storeroom"-type configuration directories, while
968)         "assembling" the items stored in the configuration according to
969)         the item's "path".  We confirm that we set the entry at the
970)         given path to the given value.
971)         """,
972)         msg='Setting contents: {path} -> {value}',
973)         context='debug message',
974)         flags='python-brace-format',
975)     )
976)     SETTING_CONFIG_STRUCTURE_CONTENTS_EMPTY_DIRECTORY = _prepare_translatable(
977)         comments=r"""
978)         TRANSLATORS: This message is emitted by the vault configuration
979)         exporter for "storeroom"-type configuration directories, while
980)         "assembling" the items stored in the configuration according to
981)         the item's "path".  We confirm that we set up a currently empty
982)         directory at the given path.
983)         """,
984)         msg='Setting contents (empty directory): {path}',
985)         context='debug message',
986)         flags='python-brace-format',
987)     )
988)     VAULT_NATIVE_EVP_BYTESTOKEY_INIT = _prepare_translatable(
989)         comments=r"""
990)         TRANSLATORS: This message is emitted by the vault configuration
991)         exporter for "native"-type configuration directories: in v0.2,
992)         the non-standard and deprecated "EVP_bytestokey" function from
993)         OpenSSL must be reimplemented from scratch.  The terms "salt"
994)         and "IV" (initialization vector) are cryptographic terms.
995)         """,
996)         msg="""
997)         evp_bytestokey_md5 (initialization):
998) 
999)           \b
1000)           Input: {data}
1001)           Salt: {salt}
1002)           Key size: {key_size}
1003)           IV size: {iv_size}
1004)           Buffer length: {buffer_length}
1005)           Buffer: {buffer}
1006)         """,
1007)         context='debug message',
1008)         flags='python-brace-format',
1009)     )
1010)     VAULT_NATIVE_EVP_BYTESTOKEY_RESULT = _prepare_translatable(
1011)         comments=r"""
1012)         TRANSLATORS: This message is emitted by the vault configuration
1013)         exporter for "native"-type configuration directories: in v0.2,
1014)         the non-standard and deprecated "EVP_bytestokey" function from
1015)         OpenSSL must be reimplemented from scratch.  The terms "salt"
1016)         and "IV" (initialization vector) are cryptographic terms.
1017)         This function reports on the updated buffer length and contents
1018)         after executing one round of hashing.
1019)         """,
1020)         msg="""
1021)         evp_bytestokey_md5 (result):
1022) 
1023)           \b
1024)           Encryption key: {enc_key}
1025)           IV: {iv}
1026)         """,
1027)         context='debug message',
1028)         flags='python-brace-format',
1029)     )
1030)     VAULT_NATIVE_EVP_BYTESTOKEY_ROUND = _prepare_translatable(
1031)         comments=r"""
1032)         TRANSLATORS: This message is emitted by the vault configuration
1033)         exporter for "native"-type configuration directories: in v0.2,
1034)         the non-standard and deprecated "EVP_bytestokey" function from
1035)         OpenSSL must be reimplemented from scratch.  The terms "salt"
1036)         and "IV" (initialization vector) are cryptographic terms.
1037)         This function reports on the updated buffer length and contents
1038)         after executing one round of hashing.
1039)         """,
1040)         msg="""
1041)         evp_bytestokey_md5 (round update):
1042) 
1043)           \b
1044)           Buffer length: {buffer_length}
1045)           Buffer: {buffer}
1046)         """,
1047)         context='debug message',
1048)         flags='python-brace-format',
1049)     )
1050)     VAULT_NATIVE_CHECKING_MAC_DETAILS = _prepare_translatable(
1051)         comments=r"""
1052)         TRANSLATORS: This message is emitted by the vault configuration
1053)         exporter for "native"-type configuration directories.  It is
1054)         preceded by the info message PARSING_IV_PAYLOAD_MAC; see the
1055)         commentary there concerning the terms and thoughts on
1056)         translating them.
1057)         """,
1058)         msg="""
1059)         MAC details:
1060) 
1061)           \b
1062)           MAC input: {mac_input}
1063)           Expected MAC: {mac}
1064)         """,
1065)         context='debug message',
1066)         flags='python-brace-format',
1067)     )
1068)     VAULT_NATIVE_PADDED_PLAINTEXT = _prepare_translatable(
1069)         comments=r"""
1070)         TRANSLATORS: This message is emitted by the vault configuration
1071)         exporter for "native"-type configuration directories.  "padding"
1072)         and "plaintext" are cryptographic terms.
1073)         """,
1074)         msg='Padded plaintext: {contents}',
1075)         context='debug message',
1076)         flags='python-brace-format',
1077)     )
1078)     VAULT_NATIVE_PARSE_BUFFER = _prepare_translatable(
1079)         comments=r"""
1080)         TRANSLATORS: This message is emitted by the vault configuration
1081)         exporter for "native"-type configuration directories.  It is
1082)         preceded by the info message PARSING_IV_PAYLOAD_MAC; see the
1083)         commentary there concerning the terms and thoughts on
1084)         translating them.
1085)         """,
1086)         msg="""
1087)         Buffer: {contents}
1088) 
1089)           \b
1090)           IV: {iv}
1091)           Payload: {payload}
1092)           MAC: {mac}
1093)         """,
1094)         context='debug message',
1095)         flags='python-brace-format',
1096)     )
1097)     VAULT_NATIVE_PLAINTEXT = _prepare_translatable(
1098)         comments=r"""
1099)         TRANSLATORS: This message is emitted by the vault configuration
1100)         exporter for "native"-type configuration directories.
1101)         "plaintext" is a cryptographic term.
1102)         """,
1103)         msg='Plaintext: {contents}',
1104)         context='debug message',
1105)         flags='python-brace-format',
1106)     )
1107)     VAULT_NATIVE_PBKDF2_CALL = _prepare_translatable(
1108)         msg="""
1109)         Master key derivation:
1110) 
1111)           \b
1112)           PBKDF2 call: PBKDF2-HMAC(password={password!r}, salt={salt!r}, iterations={iterations!r}, key_size={key_size!r}, algorithm={algorithm!r})
1113)           Result (binary): {raw_result}
1114)           Result (hex key): {result_key!r}
1115)         """,  # noqa: E501
1116)         comments='',
1117)         context='debug message',
1118)         flags='python-brace-format',
1119)     )
1120)     VAULT_NATIVE_V02_PAYLOAD_MAC_POSTPROCESSING = _prepare_translatable(
1121)         comments=r"""
1122)         TRANSLATORS: This message is emitted by the vault configuration
1123)         exporter for "native"-type configuration directories.  It is
1124)         preceded by the info message PARSING_IV_PAYLOAD_MAC and the
1125)         debug message PARSING_NATIVE_PARSE_BUFFER; see the commentary
1126)         there concerning the terms and thoughts on translating them.
1127)         """,
1128)         msg="""
1129)         Postprocessing buffer (v0.2):
1130) 
1131)           \b
1132)           Payload: {payload} (decoded from base64)
1133)           MAC: {mac} (decoded from hex)
1134)         """,
1135)         context='debug message',
1136)         flags='python-brace-format',
1137)     )
1138) 
1139) 
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1140) class InfoMsgTemplate(enum.Enum):
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

1141)     ASSEMBLING_CONFIG_STRUCTURE = _prepare_translatable(
1142)         comments=r"""
1143)         TRANSLATORS: This message is emitted by the vault configuration
1144)         exporter for "storeroom"-type configuration directories.  The
1145)         system stores entries in different "buckets" of a hash table.
1146)         After the respective items in the buckets have been decrypted,
1147)         we then have a list of item paths plus contents to populate.
1148)         This must be done in a certain order (we don't yet have an
1149)         existing directory tree to rely on, but rather must build it
1150)         on-the-fly), hence the term "assembling".
1151)         """,
1152)         msg='Assembling config structure',
1153)         context='info message',
1154)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1155)     CANNOT_LOAD_AS_VAULT_CONFIG = _prepare_translatable(
1156)         comments=r"""
1157)         TRANSLATORS: "fmt" is a string such as "v0.2" or "storeroom",
1158)         indicating the format which we tried to load the vault
1159)         configuration as.
1160)         """,
1161)         msg='Cannot load {path!r} as a {fmt!s} vault configuration.',
1162)         context='info message',
1163)         flags='python-brace-format',
1164)     )
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

1165)     CHECKING_CONFIG_STRUCTURE_CONSISTENCY = _prepare_translatable(
1166)         comments=r"""
1167)         TRANSLATORS: This message is emitted by the vault configuration
1168)         exporter for "storeroom"-type configuration directories.  Having
1169)         "assembled" the configuration items according to their claimed
1170)         paths and contents, we then check if the assembled structure is
1171)         internally consistent.
1172)         """,
1173)         msg='Checking config structure consistency',
1174)         context='info message',
1175)     )
1176)     DECRYPTING_BUCKET = _prepare_translatable(
1177)         comments=r"""
1178)         TRANSLATORS: This message is emitted by the vault configuration
1179)         exporter for "storeroom"-type configuration directories.  The
1180)         system stores entries in different "buckets" of a hash table.
1181)         We parse the directory bucket by bucket.  All buckets are
1182)         numbered in hexadecimal, and typically there are 32 buckets, so
1183)         2-digit hex numbers.
1184)         """,
1185)         msg='Decrypting bucket {bucket_number}',
1186)         context='info message',
1187)         flags='python-brace-format',
1188)     )
1189)     PARSING_MASTER_KEYS_DATA = _prepare_translatable(
1190)         comments=r"""
1191)         TRANSLATORS: This message is emitted by the vault configuration
1192)         exporter for "storeroom"-type configuration directories.
1193)         `.keys` is a filename, from which data about the master keys for
1194)         this configuration are loaded.
1195)         """,
1196)         msg='Parsing master keys data from .keys',
1197)         context='info message',
1198)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1199)     PIP_INSTALL_EXTRA = _prepare_translatable(
1200)         comments=r"""
1201)         TRANSLATORS: This message immediately follows an error message
1202)         about a missing library that needs to be installed.  The Python
1203)         Package Index (PyPI) supports declaring sets of optional
1204)         dependencies as "extras", so users installing from PyPI can
1205)         request reinstallation with a named "extra" being enabled.  This
1206)         would then let the installer take care of the missing libraries
1207)         automatically, hence this suggestion to PyPI users.
1208)         """,
1209)         msg='(For users installing from PyPI, see the {extra_name!r} extra.)',
1210)         context='info message',
1211)         flags='python-brace-format',
1212)     )
1213)     SUCCESSFULLY_MIGRATED = _prepare_translatable(
1214)         comments=r"""
1215)         TRANSLATORS: This info message immediately follows the "Using
1216)         deprecated v0.1-style ..." deprecation warning.
1217)         """,
1218)         msg='Successfully migrated to {path!r}.',
1219)         context='info message',
1220)         flags='python-brace-format',
1221)     )
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

1222)     VAULT_NATIVE_CHECKING_MAC = _prepare_translatable(
1223)         msg='Checking MAC',
1224)         comments='',
1225)         context='info message',
1226)     )
1227)     VAULT_NATIVE_DECRYPTING_CONTENTS = _prepare_translatable(
1228)         msg='Decrypting contents',
1229)         comments='',
1230)         context='info message',
1231)     )
1232)     VAULT_NATIVE_DERIVING_KEYS = _prepare_translatable(
1233)         msg='Deriving an encryption and signing key',
1234)         comments='',
1235)         context='info message',
1236)     )
1237)     VAULT_NATIVE_PARSING_IV_PAYLOAD_MAC = _prepare_translatable(
1238)         comments=r"""
1239)         TRANSLATORS: This message is emitted by the vault configuration
1240)         exporter for "native"-type configuration directories.  "IV"
1241)         means "initialization vector", and "MAC" means "message
1242)         authentication code".  They are specifically cryptographic
1243)         terms, as is "payload".  The acronyms "IV" and "MAC" are assumed
1244)         to be well-known to the English target audience, or at least
1245)         discoverable by them; they *are* asking for debug output, after
1246)         all.  Please use your judgement as to whether to translate this
1247)         term or not, expanded or not.
1248)         """,
1249)         msg='Parsing IV, payload and MAC from the file contents',
1250)         context='info message',
1251)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1252) 
1253) 
1254) class WarnMsgTemplate(enum.Enum):
1255)     EMPTY_SERVICE_NOT_SUPPORTED = _prepare_translatable(
1256)         comments='',
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1257)         msg="""
1258)         An empty {service_metavar!s} is not supported by vault(1).
1259)         For compatibility, this will be treated as if SERVICE was not
1260)         supplied, i.e., it will error out, or operate on global settings.
1261)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1262)         context='warning message',
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1263)         flags='python-brace-format',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1264)     )
1265)     EMPTY_SERVICE_SETTINGS_INACCESSIBLE = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1266)         msg="""
1267)         An empty {service_metavar!s} is not supported by vault(1).
1268)         The empty-string service settings will be inaccessible and
1269)         ineffective.  To ensure that vault(1) and {PROG_NAME!s} see the
1270)         settings, move them into the "global" section.
1271)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1272)         comments='',
1273)         context='warning message',
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1274)         flags='python-brace-format',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1275)     )
1276)     FAILED_TO_MIGRATE_CONFIG = _prepare_translatable(
1277)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1278)         TRANSLATORS: "error" is supplied by the operating system
1279)         (errno/strerror).
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1280)         """,
1281)         msg='Failed to migrate to {path!r}: {error!s}: {filename!r}.',
1282)         context='warning message',
1283)         flags='python-brace-format',
1284)     )
1285)     GLOBAL_PASSPHRASE_INEFFECTIVE = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1286)         msg=r"""
1287)         Setting a global passphrase is ineffective
1288)         because a key is also set.
1289)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1290)         comments='',
1291)         context='warning message',
1292)     )
1293)     PASSPHRASE_NOT_NORMALIZED = _prepare_translatable(
1294)         comments=r"""
1295)         TRANSLATORS: The key is a (vault) configuration key, in JSONPath
1296)         syntax, typically "$.global" for the global passphrase or
1297)         "$.services.service_name" or "$.services["service with spaces"]"
1298)         for the services "service_name" and "service with spaces",
1299)         respectively.  The form is one of the four Unicode normalization
1300)         forms: NFC, NFD, NFKC, NFKD.
1301) 
1302)         The asterisks are not special.  Please feel free to substitute
1303)         any other appropriate way to mark up emphasis of the word
1304)         "displays".
1305)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1306)         msg=r"""
1307)         The {key!s} passphrase is not {form!s}-normalized.  Its
1308)         serialization as a byte string may not be what you expect it to
1309)         be, even if it *displays* correctly.  Please make sure to
1310)         double-check any derived passphrases for unexpected results.
1311)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1312)         context='warning message',
1313)         flags='python-brace-format',
1314)     )
Marco Ricci Consolidate shell completio...

Marco Ricci authored 2 months ago

1315)     SERVICE_NAME_INCOMPLETABLE = _prepare_translatable(
1316)         msg="""
1317)         The service name {service!r} contains an ASCII control
1318)         character, which is not supported by our shell completion code.
1319)         This service name will therefore not be available for completion
1320)         on the command-line.  You may of course still type it in
1321)         manually in whatever format your shell accepts, but we highly
1322)         recommend choosing a different service name instead.
1323)         """,
1324)         comments='',
1325)         context='warning message',
1326)         flags='python-brace-format',
1327)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1328)     SERVICE_PASSPHRASE_INEFFECTIVE = _prepare_translatable(
1329)         comments=r"""
1330)         TRANSLATORS: The key that is set need not necessarily be set at
1331)         the service level; it may be a global key as well.
1332)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1333)         msg=r"""
1334)         Setting a service passphrase is ineffective because a key is
1335)         also set: {service!s}.
1336)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1337)         context='warning message',
1338)         flags='python-brace-format',
1339)     )
1340)     STEP_REMOVE_INEFFECTIVE_VALUE = _prepare_translatable(
1341)         'Removing ineffective setting {path!s} = {old!s}.',
1342)         comments='',
1343)         context='warning message',
1344)         flags='python-brace-format',
1345)     )
1346)     STEP_REPLACE_INVALID_VALUE = _prepare_translatable(
1347)         'Replacing invalid value {old!s} for key {path!s} with {new!s}.',
1348)         comments='',
1349)         context='warning message',
1350)         flags='python-brace-format',
1351)     )
1352)     V01_STYLE_CONFIG = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1353)         msg=r"""
1354)         Using deprecated v0.1-style config file {old!r}, instead of
1355)         v0.2-style {new!r}.  Support for v0.1-style config filenames
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1356)         will be removed in v1.0.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1357)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1358)         comments='',
1359)         context='deprecation warning message',
1360)         flags='python-brace-format',
1361)     )
1362)     V10_SUBCOMMAND_REQUIRED = _prepare_translatable(
1363)         comments=r"""
1364)         TRANSLATORS: This deprecation warning may be issued at any
1365)         level, i.e. we may actually be talking about subcommands, or
1366)         sub-subcommands, or sub-sub-subcommands, etc., which is what the
1367)         "here" is supposed to indicate.
1368)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1369)         msg="""
1370)         A subcommand will be required here in v1.0.  See --help for
1371)         available subcommands.  Defaulting to subcommand "vault".
1372)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1373)         context='deprecation warning message',
1374)     )
1375) 
1376) 
1377) class ErrMsgTemplate(enum.Enum):
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1378)     AGENT_REFUSED_LIST_KEYS = _prepare_translatable(
1379)         comments=r"""
1380)         TRANSLATORS: "loaded keys" being keys loaded into the agent.
1381)         """,
1382)         msg="""
1383)         The SSH agent failed to or refused to supply a list of loaded keys.
1384)         """,
1385)         context='error message',
1386)     )
1387)     AGENT_REFUSED_SIGNATURE = _prepare_translatable(
1388)         comments=r"""
1389)         TRANSLATORS: The message to be signed is the vault UUID, but
1390)         there's no space to explain that here, so ideally the error
1391)         message does not go into detail.
1392)         """,
1393)         msg="""
1394)         The SSH agent failed to or refused to issue a signature with the
1395)         selected key, necessary for deriving a service passphrase.
1396)         """,
1397)         context='error message',
1398)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1399)     CANNOT_CONNECT_TO_AGENT = _prepare_translatable(
1400)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1401)         TRANSLATORS: "error" is supplied by the operating system
1402)         (errno/strerror).
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1403)         """,
1404)         msg='Cannot connect to the SSH agent: {error!s}: {filename!r}.',
1405)         context='error message',
1406)         flags='python-brace-format',
1407)     )
1408)     CANNOT_DECODEIMPORT_VAULT_SETTINGS = _prepare_translatable(
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1409)         comments=r"""
1410)         TRANSLATORS: "error" is supplied by the operating system
1411)         (errno/strerror).
1412)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1413)         msg='Cannot import vault settings: cannot decode JSON: {error!s}.',
1414)         context='error message',
1415)         flags='python-brace-format',
1416)     )
1417)     CANNOT_EXPORT_VAULT_SETTINGS = _prepare_translatable(
1418)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1419)         TRANSLATORS: "error" is supplied by the operating system
1420)         (errno/strerror).
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1421)         """,
1422)         msg='Cannot export vault settings: {error!s}: {filename!r}.',
1423)         context='error message',
1424)         flags='python-brace-format',
1425)     )
1426)     CANNOT_IMPORT_VAULT_SETTINGS = _prepare_translatable(
1427)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1428)         TRANSLATORS: "error" is supplied by the operating system
1429)         (errno/strerror).
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1430)         """,
1431)         msg='Cannot import vault settings: {error!s}: {filename!r}.',
1432)         context='error message',
1433)         flags='python-brace-format',
1434)     )
1435)     CANNOT_LOAD_USER_CONFIG = _prepare_translatable(
1436)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1437)         TRANSLATORS: "error" is supplied by the operating system
1438)         (errno/strerror).
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1439)         """,
1440)         msg='Cannot load user config: {error!s}: {filename!r}.',
1441)         context='error message',
1442)         flags='python-brace-format',
1443)     )
1444)     CANNOT_LOAD_VAULT_SETTINGS = _prepare_translatable(
1445)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1446)         TRANSLATORS: "error" is supplied by the operating system
1447)         (errno/strerror).
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1448)         """,
1449)         msg='Cannot load vault settings: {error!s}: {filename!r}.',
1450)         context='error message',
1451)         flags='python-brace-format',
1452)     )
1453)     CANNOT_PARSE_AS_VAULT_CONFIG = _prepare_translatable(
1454)         comments=r"""
1455)         TRANSLATORS: Unlike the "Cannot load {path!r} as a {fmt!s} vault
1456)         configuration." message, *this* error message is emitted when we
1457)         have tried loading the path in each of our supported formats,
1458)         and failed.  The user will thus see the above "Cannot load ..."
1459)         warning message potentially multiple times, and this error
1460)         message at the very bottom.
1461)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1462)         msg=r"""
1463)         Cannot parse {path!r} as a valid vault-native configuration
1464)         file/directory.
1465)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1466)         context='error message',
1467)         flags='python-brace-format',
1468)     )
Marco Ricci Replace strings in `derivep...

Marco Ricci authored 2 months ago

1469)     CANNOT_PARSE_AS_VAULT_CONFIG_OSERROR = _prepare_translatable(
1470)         comments=r"""
1471)         TRANSLATORS: "error" is supplied by the operating system
1472)         (errno/strerror).
1473)         """,
1474)         msg=r"""
1475)         Cannot parse {path!r} as a valid vault-native configuration
1476)         file/directory: {error!s}: {filename!r}.
1477)         """,
1478)         context='error message',
1479)         flags='python-brace-format',
1480)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1481)     CANNOT_STORE_VAULT_SETTINGS = _prepare_translatable(
1482)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1483)         TRANSLATORS: "error" is supplied by the operating system
1484)         (errno/strerror).
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1485)         """,
1486)         msg='Cannot store vault settings: {error!s}: {filename!r}.',
1487)         context='error message',
1488)         flags='python-brace-format',
1489)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1490)     CANNOT_UNDERSTAND_AGENT = _prepare_translatable(
1491)         comments=r"""
1492)         TRANSLATORS: This error message is used whenever we cannot make
1493)         any sense of a response from the SSH agent because the response
1494)         is ill-formed (truncated, improperly encoded, etc.) or otherwise
1495)         violates the communications protocol.  Well-formed responses
1496)         that adhere to the protocol, even if they indicate that the
1497)         requested operation failed, are handled with a different error
1498)         message.
1499)         """,
1500)         msg="""
1501)         Cannot understand the SSH agent's response because it violates
1502)         the communications protocol.
1503)         """,
Marco Ricci Fix missing context in CANN...

Marco Ricci authored 2 months ago

1504)         context='error message',
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1505)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1506)     CANNOT_UPDATE_SETTINGS_NO_SETTINGS = _prepare_translatable(
Marco Ricci Fix phrasing of "Cannot upd...

Marco Ricci authored 2 months ago

1507)         comments=r"""
1508)         TRANSLATORS: The settings_type metavar contains translations for
1509)         either "global settings" or "service-specific settings"; see the
1510)         CANNOT_UPDATE_SETTINGS_METAVAR_SETTINGS_TYPE_GLOBAL and
1511)         CANNOT_UPDATE_SETTINGS_METAVAR_SETTINGS_TYPE_SERVICE entries.
1512)         The first sentence will thus read either "Cannot update the
1513)         global settings without any given settings." or "Cannot update
1514)         the service-specific settings without any given settings.".  You
1515)         may update this entry, and the two metavar entries, in any way
1516)         you see fit that achieves the desired translations of the first
1517)         sentence.
1518)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1519)         msg=r"""
Marco Ricci Fix phrasing of "Cannot upd...

Marco Ricci authored 2 months ago

1520)         Cannot update the {settings_type!s} without any given settings.
1521)         You must specify at least one of --lower, ..., --symbol, or
1522)         --phrase or --key.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1523)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1524)         context='error message',
1525)         flags='python-brace-format',
1526)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1527)     INVALID_USER_CONFIG = _prepare_translatable(
1528)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1529)         TRANSLATORS: "error" is supplied by the operating system
1530)         (errno/strerror).
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1531)         """,
1532)         msg=r"""
1533)         The user configuration file is invalid.  {error!s}: {filename!r}.
1534)         """,
1535)         context='error message',
1536)         flags='python-brace-format',
1537)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1538)     INVALID_VAULT_CONFIG = _prepare_translatable(
1539)         comments=r"""
1540)         TRANSLATORS: This error message is a reaction to a validator
1541)         function saying *that* the configuration is not valid, but not
1542)         *how* it is not valid.  The configuration file is principally
1543)         parsable, however.
1544)         """,
1545)         msg='Invalid vault config: {config!r}.',
1546)         context='error message',
1547)         flags='python-brace-format',
1548)     )
1549)     MISSING_MODULE = _prepare_translatable(
1550)         'Cannot load the required Python module {module!r}.',
1551)         comments='',
1552)         context='error message',
1553)         flags='python-brace-format',
1554)     )
1555)     NO_AF_UNIX = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1556)         msg=r"""
1557)         Cannot connect to an SSH agent because this Python version does
1558)         not support UNIX domain sockets.
1559)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1560)         comments='',
1561)         context='error message',
1562)     )
1563)     NO_KEY_OR_PHRASE = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1564)         msg=r"""
1565)         No passphrase or key was given in the configuration.  In this
1566)         case, the --phrase or --key argument is required.
1567)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1568)         comments='',
1569)         context='error message',
1570)     )
1571)     NO_SSH_AGENT_FOUND = _prepare_translatable(
1572)         'Cannot find any running SSH agent because SSH_AUTH_SOCK is not set.',
1573)         comments='',
1574)         context='error message',
1575)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1576)     NO_SUITABLE_SSH_KEYS = _prepare_translatable(
1577)         msg="""
1578)         The SSH agent contains no keys suitable for {PROG_NAME!s}.
1579)         """,  # noqa: RUF027
1580)         comments='',
1581)         context='error message',
1582)         flags='python-brace-format',
1583)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1584)     PARAMS_MUTUALLY_EXCLUSIVE = _prepare_translatable(
1585)         comments=r"""
1586)         TRANSLATORS: The params are long-form command-line option names.
1587)         Typical example: "--key is mutually exclusive with --phrase."
1588)         """,
1589)         msg='{param1!s} is mutually exclusive with {param2!s}.',
1590)         context='error message',
1591)         flags='python-brace-format',
1592)     )
1593)     PARAMS_NEEDS_SERVICE_OR_CONFIG = _prepare_translatable(
1594)         comments=r"""
1595)         TRANSLATORS: The param is a long-form command-line option name,
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1596)         the metavar is Label.VAULT_METAVAR_SERVICE.
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1597)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1598)         msg='{param!s} requires a {service_metavar!s} or --config.',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1599)         context='error message',
1600)         flags='python-brace-format',
1601)     )
1602)     PARAMS_NEEDS_SERVICE = _prepare_translatable(
1603)         comments=r"""
1604)         TRANSLATORS: The param is a long-form command-line option name,
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1605)         the metavar is Label.VAULT_METAVAR_SERVICE.
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1606)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1607)         msg='{param!s} requires a {service_metavar!s}.',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1608)         context='error message',
1609)         flags='python-brace-format',
1610)     )
1611)     PARAMS_NO_SERVICE = _prepare_translatable(
1612)         comments=r"""
1613)         TRANSLATORS: The param is a long-form command-line option name,
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1614)         the metavar is Label.VAULT_METAVAR_SERVICE.
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1615)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1616)         msg='{param!s} does not take a {service_metavar!s} argument.',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1617)         context='error message',
1618)         flags='python-brace-format',
1619)     )
1620)     SERVICE_REQUIRED = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1621)         comments=r"""
Marco Ricci Fix some translation typos...

Marco Ricci authored 2 months ago

1622)         TRANSLATORS: The metavar is Label.VAULT_METAVAR_SERVICE.
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1623)         """,
1624)         msg='Deriving a passphrase requires a {service_metavar!s}.',
1625)         context='error message',
1626)         flags='python-brace-format',
1627)     )
1628)     SET_AND_UNSET_SAME_SETTING = _prepare_translatable(
1629)         comments=r"""
1630)         TRANSLATORS: The rephrasing "Attempted to unset and set the same
1631)         setting (--unset={setting!s} --{setting!s}=...) at the same
1632)         time." may or may not be more suitable as a basis for
1633)         translation instead.
1634)         """,
1635)         msg='Attempted to unset and set --{setting!s} at the same time.',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1636)         context='error message',
Marco Ricci Add more translatable strin...

Marco Ricci authored 2 months ago

1637)         flags='python-brace-format',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1638)     )
1639)     SSH_KEY_NOT_LOADED = _prepare_translatable(
1640)         'The requested SSH key is not loaded into the agent.',
1641)         comments='',
1642)         context='error message',
1643)     )
1644)     USER_ABORTED_EDIT = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

1645)         comments=r"""
1646)         TRANSLATORS: The user requested to edit the notes for a service,
1647)         but aborted the request mid-editing.
1648)         """,
1649)         msg='Not saving any new notes: the user aborted the request.',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1650)         context='error message',
1651)     )
1652)     USER_ABORTED_PASSPHRASE = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

1653)         comments=r"""
1654)         TRANSLATORS: The user was prompted for a master passphrase,
1655)         but aborted the request.
1656)         """,
1657)         msg='No passphrase was given; the user aborted the request.',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1658)         context='error message',
1659)     )
1660)     USER_ABORTED_SSH_KEY_SELECTION = _prepare_translatable(
Marco Ricci Add more translator's comments

Marco Ricci authored 2 months ago

1661)         comments=r"""
1662)         TRANSLATORS: The user was prompted to select a master SSH key,
1663)         but aborted the request.
1664)         """,
1665)         msg='No SSH key was selected; the user aborted the request.',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 months ago

1666)         context='error message',
1667)     )
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

1668) 
1669) 
Marco Ricci Fix coverage

Marco Ricci authored 2 months ago

1670) def _write_pot_file(fileobj: TextIO) -> None:  # pragma: no cover
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

1671)     r"""Write a .po template to the given file object.
1672) 
1673)     Assumes the file object is opened for writing and accepts string
1674)     inputs.  The file will *not* be closed when writing is complete.
1675)     The file *must* be opened in UTF-8 encoding, lest the file will
1676)     declare an incorrect encoding.
1677) 
1678)     This function crucially depends on all translatable strings
1679)     appearing in the enums of this module.  Certain parts of the
1680)     .po header are hard-coded, as is the source filename.
1681) 
Marco Ricci Update ruff to v0.8.x, refo...

Marco Ricci authored 2 months ago

1682)     """  # noqa: DOC501
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

1683)     entries: dict[
1684)         str,
1685)         dict[
1686)             str,
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

1687)             Label | DebugMsgTemplate | InfoMsgTemplate | WarnMsgTemplate | ErrMsgTemplate,
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

1688)         ],
1689)     ] = {}
1690)     for enum_class in (
1691)         Label,
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

1692)         DebugMsgTemplate,
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

1693)         InfoMsgTemplate,
1694)         WarnMsgTemplate,
1695)         ErrMsgTemplate,
1696)     ):
1697)         for member in enum_class.__members__.values():
1698)             ctx = member.value.l10n_context
1699)             msg = member.value.singular
1700)             if (
1701)                 msg in entries.setdefault(ctx, {})
1702)                 and entries[ctx][msg] != member
1703)             ):
Marco Ricci Update ruff to v0.8.x, refo...

Marco Ricci authored 2 months ago

1704)                 raise AssertionError(  # noqa: TRY003
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

1705)                     f'Duplicate entry for ({ctx!r}, {msg!r}): '  # noqa: EM102
1706)                     f'{entries[ctx][msg]!r} and {member!r}'
1707)                 )
1708)             entries[ctx][msg] = member
1709)     now = datetime.datetime.now().astimezone()
1710)     header = (
1711)         inspect.cleandoc(rf"""
1712)         # English translation for {PROG_NAME!s}.
1713)         # Copyright (C) {now.strftime('%Y')} AUTHOR
1714)         # This file is distributed under the same license as {PROG_NAME!s}.
1715)         # AUTHOR <someone@example.com>, {now.strftime('%Y')}.
1716)         #
1717)         msgid ""
1718)         msgstr ""
1719)         "Project-Id-Version: {PROG_NAME!s} {__version__!s}\n"
1720)         "Report-Msgid-Bugs-To: software@the13thletter.info\n"
1721)         "POT-Creation-Date: {now.strftime('%Y-%m-%d %H:%M%z')}\n"
1722)         "PO-Revision-Date: {now.strftime('%Y-%m-%d %H:%M%z')}\n"
1723)         "Last-Translator: AUTHOR <someone@example.com>\n"
1724)         "Language: en\n"
1725)         "MIME-Version: 1.0\n"
1726)         "Content-Type: text/plain; charset=UTF-8\n"
1727)         "Content-Transfer-Encoding: 8bit\n"
1728)         "Plural-Forms: nplurals=2; plural=(n != 1);\n"
1729)         """).removesuffix('\n')
1730)         + '\n'
1731)     )
1732)     fileobj.write(header)
1733)     for _ctx, subdict in sorted(entries.items()):
1734)         for _msg, enum_value in sorted(
1735)             subdict.items(),
1736)             key=lambda kv: str(kv[1]),
1737)         ):
1738)             fileobj.writelines(_format_po_entry(enum_value))
1739) 
1740) 
1741) def _format_po_entry(
Marco Ricci Make debug and info message...

Marco Ricci authored 2 months ago

1742)     enum_value: Label | DebugMsgTemplate | InfoMsgTemplate | WarnMsgTemplate | ErrMsgTemplate,
Marco Ricci Fix coverage

Marco Ricci authored 2 months ago

1743) ) -> tuple[str, ...]:  # pragma: no cover
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

1744)     ret: list[str] = ['\n']
1745)     ts = enum_value.value
1746)     if ts.translator_comments:
1747)         ret.extend(
1748)             f'#. {line}\n'
1749)             for line in ts.translator_comments.splitlines(False)  # noqa: FBT003
1750)         )
1751)     ret.append(f'#: derivepassphrase/_cli_msg.py:{enum_value}\n')
1752)     if ts.flags:
1753)         ret.append(f'#, {", ".join(sorted(ts.flags))}\n')
1754)     if ts.l10n_context:
1755)         ret.append(f'msgctxt {_cstr(ts.l10n_context)}\n')
1756)     ret.append(f'msgid {_cstr(ts.singular)}\n')
1757)     if ts.plural:
1758)         ret.append(f'msgid_plural {_cstr(ts.plural)}\n')
1759)     ret.append('msgstr ""\n')
1760)     return tuple(ret)
1761) 
1762) 
Marco Ricci Fix coverage

Marco Ricci authored 2 months ago

1763) def _cstr(s: str) -> str:  # pragma: no cover
Marco Ricci Add a writer function for d...

Marco Ricci authored 2 months ago

1764)     def escape(string: str) -> str:
1765)         return string.translate({
1766)             0: r'\000',
1767)             1: r'\001',
1768)             2: r'\002',
1769)             3: r'\003',
1770)             4: r'\004',
1771)             5: r'\005',
1772)             6: r'\006',
1773)             7: r'\007',
1774)             8: r'\b',
1775)             9: r'\t',
1776)             10: r'\n',
1777)             11: r'\013',
1778)             12: r'\f',
1779)             13: r'\r',
1780)             14: r'\016',
1781)             15: r'\017',
1782)             ord('"'): r'\"',
1783)             ord('\\'): r'\\',
1784)             127: r'\177',
1785)         })
1786) 
1787)     return '\n'.join(
1788)         f'"{escape(line)}"'
1789)         for line in s.splitlines(True)  # noqa: FBT003
1790)     )
1791) 
1792) 
1793) if __name__ == '__main__':