df1756fe1222e9bf01b9f256a8a212174c144876
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

1) # SPDX-FileCopyrightText: 2024 Marco Ricci <software@the13thletter.info>
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) 
9) import enum
10) import gettext
11) import inspect
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

13) import types
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

15) 
16) import derivepassphrase as dpp
17) 
18) if TYPE_CHECKING:
19)     from collections.abc import Iterable, Mapping
20) 
21)     from typing_extensions import Any, Self
22) 
23) __author__ = dpp.__author__
24) __version__ = dpp.__version__
25) 
26) __all__ = ('PROG_NAME',)
27) 
28) PROG_NAME = 'derivepassphrase'
29) translation = gettext.translation(PROG_NAME, fallback=True)
30) 
31) 
32) class TranslatableString(NamedTuple):
33)     singular: str
34)     plural: str
35)     l10n_context: str
36)     translator_comments: str
37)     flags: frozenset[str]
38) 
39) 
40) def _prepare_translatable(
41)     msg: str,
42)     comments: str = '',
43)     context: str = '',
44)     plural_msg: str = '',
45)     *,
46)     flags: Iterable[str] = (),
47) ) -> TranslatableString:
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

48)     def maybe_rewrap(string: str) -> str:
49)         string = inspect.cleandoc(string)
50)         if not any(s.strip() == '\b' for s in string.splitlines()):
51)             string = '\n'.join(
52)                 textwrap.wrap(
53)                     string,
54)                     width=float('inf'),  # type: ignore[arg-type]
55)                     fix_sentence_endings=True,
56)                 )
57)             )
58)         else:  # pragma: no cover
59)             string = ''.join(
60)                 s
61)                 for s in string.splitlines(True)  # noqa: FBT003
62)                 if s.strip() == '\b'
63)             )
64)         return string
65) 
66)     msg = maybe_rewrap(msg)
67)     plural_msg = maybe_rewrap(plural_msg)
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

68)     context = context.strip()
69)     comments = inspect.cleandoc(comments)
70)     flags = (
71)         frozenset(f.strip() for f in flags)
72)         if not isinstance(flags, str)
73)         else frozenset({flags})
74)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

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

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

80)     ), f'Missing flag for how to deal with percent character in {msg!r}'
81)     return TranslatableString(msg, plural_msg, context, comments, flags)
82) 
83) 
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

85)     def __init__(
86)         self,
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

87)         template: (
88)             str
89)             | TranslatableString
90)             | Label
91)             | InfoMsgTemplate
92)             | WarnMsgTemplate
93)             | ErrMsgTemplate
94)         ),
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

95)         args_dict: Mapping[str, Any] = types.MappingProxyType({}),
96)         /,
97)         **kwargs: Any,  # noqa: ANN401
98)     ) -> None:
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

99)         if isinstance(
100)             template, (Label, InfoMsgTemplate, WarnMsgTemplate, ErrMsgTemplate)
101)         ):
102)             template = cast(TranslatableString, template.value)
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

103)         self.template = template
104)         self.kwargs = {**args_dict, **kwargs}
105)         self._rendered: str | None = None
106) 
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

107)     def __bool__(self) -> bool:
108)         return bool(str(self))
109) 
110)     def __eq__(self, other: object) -> bool:  # pragma: no cover
111)         return str(self) == other
112) 
113)     def __hash__(self) -> int:  # pragma: no cover
114)         return hash(str(self))
115) 
116)     def __repr__(self) -> str:  # pragma: no cover
117)         return (
118)             f'{self.__class__.__name__}({self.template!r}, '
119)             f'{dict(self.kwargs)!r})'
120)         )
121) 
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

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

Marco Ricci authored 1 week ago

124)             # raw str support is currently unneeded, so excluded from coverage
125)             if isinstance(self.template, str):  # pragma: no cover
126)                 context = None
127)                 template = self.template
128)             else:
129)                 context = self.template.l10n_context
130)                 template = self.template.singular
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

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

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

134)                 template = translation.gettext(template)
135)             self._rendered = template.format(**self.kwargs)
136)         return self._rendered
137) 
138)     def maybe_without_filename(self) -> Self:
139)         if (
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

142)             and ': {filename!r}' in self.template.singular
143)         ):
144)             singular = ''.join(
145)                 self.template.singular.split(': {filename!r}', 1)
146)             )
147)             plural = (
148)                 ''.join(self.template.plural.split(': {filename!r}', 1))
149)                 if self.template.plural
150)                 else self.template.plural
151)             )
152)             return self.__class__(
153)                 self.template._replace(singular=singular, plural=plural),
154)                 self.kwargs,
155)             )
156)         return self
157) 
158) 
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

159) class Label(enum.Enum):
160)     DEPRECATION_WARNING_LABEL = _prepare_translatable(
161)         'Deprecation warning', comments='', context='diagnostic label'
162)     )
163)     WARNING_LABEL = _prepare_translatable(
164)         'Warning', comments='', context='diagnostic label'
165)     )
166)     DERIVEPASSPHRASE_01 = _prepare_translatable(
167)         msg="""
168)         Derive a strong passphrase, deterministically, from a master secret.
169)         """,
170)         comments='',
171)         context='help text (long form)',
172)     )
173)     DERIVEPASSPHRASE_02 = _prepare_translatable(
174)         msg="""
175)         The currently implemented subcommands are "vault" (for the
176)         scheme used by vault) and "export" (for exporting foreign
177)         configuration data).  See the respective `--help` output for
178)         instructions.  If no subcommand is given, we default to "vault".
179)         """,
180)         comments='',
181)         context='help text (long form)',
182)     )
183)     DERIVEPASSPHRASE_03 = _prepare_translatable(
184)         msg="""
185)         Deprecation notice: Defaulting to "vault" is deprecated.
186)         Starting in v1.0, the subcommand must be specified explicitly.
187)         """,
188)         comments='',
189)         context='help text (long form)',
190)     )
191)     DERIVEPASSPHRASE_EPILOG_01 = _prepare_translatable(
192)         msg=r"""
193)         Configuration is stored in a directory according to the
194)         `DERIVEPASSPHRASE_PATH` variable, which defaults to
195)         `~/.derivepassphrase` on UNIX-like systems and
196)         `C:\Users\<user>\AppData\Roaming\Derivepassphrase` on Windows.
197)         """,
198)         comments='',
199)         context='help text (long form)',
200)     )
201)     DERIVEPASSPHRASE_EXPORT_01 = _prepare_translatable(
202)         msg="""
203)         Export a foreign configuration to standard output.
204)         """,
205)         comments='',
206)         context='help text (long form)',
207)     )
208)     DERIVEPASSPHRASE_EXPORT_02 = _prepare_translatable(
209)         msg="""
210)         The only available subcommand is "vault", which implements the
211)         vault-native configuration scheme.  If no subcommand is given,
212)         we default to "vault".
213)         """,
214)         comments='',
215)         context='help text (long form)',
216)     )
217)     DERIVEPASSPHRASE_EXPORT_03 = DERIVEPASSPHRASE_03
218)     DERIVEPASSPHRASE_EXPORT_VAULT_01 = _prepare_translatable(
219)         msg="""
220)         Export a vault-native configuration to standard output.
221)         """,
222)         comments='',
223)         context='help text (long form)',
224)     )
225)     DERIVEPASSPHRASE_EXPORT_VAULT_02 = _prepare_translatable(
226)         msg="""
227)         Depending on the configuration format, {path_metavar!s} may
228)         either be a file or a directory.  We support the vault "v0.2",
229)         "v0.3" and "storeroom" formats.
230)         """,
231)         comments='',
232)         context='help text (long form)',
233)         flags='python-brace-format',
234)     )
235)     DERIVEPASSPHRASE_EXPORT_VAULT_03 = _prepare_translatable(
236)         msg="""
237)         If {path_metavar!s} is explicitly given as `VAULT_PATH`, then
238)         use the `VAULT_PATH` environment variable to determine the
239)         correct path.  (Use `./VAULT_PATH` or similar to indicate
240)         a file/directory actually named `VAULT_PATH`.)
241)         """,
242)         comments='',
243)         context='help text (long form)',
244)         flags='python-brace-format',
245)     )
246)     DERIVEPASSPHRASE_VAULT_01 = _prepare_translatable(
247)         msg="""
248)         Derive a passphrase using the vault derivation scheme.
249)         """,
250)         comments='',
251)         context='help text (long form)',
252)     )
253)     DERIVEPASSPHRASE_VAULT_02 = _prepare_translatable(
254)         msg="""
255)         If operating on global settings, or importing/exporting
256)         settings, then {service_metavar!s} must be omitted.  Otherwise
257)         it is required.
258)         """,
259)         comments='',
260)         context='help text (long form)',
261)         flags='python-brace-format',
262)     )
263)     DERIVEPASSPHRASE_VAULT_EPILOG_01 = _prepare_translatable(
264)         msg="""
265)         WARNING: There is NO WAY to retrieve the generated passphrases
266)         if the master passphrase, the SSH key, or the exact passphrase
267)         settings are lost, short of trying out all possible
268)         combinations.  You are STRONGLY advised to keep independent
269)         backups of the settings and the SSH key, if any.
270)         """,
271)         comments='',
272)         context='help text (long form)',
273)     )
274)     DERIVEPASSPHRASE_VAULT_EPILOG_02 = _prepare_translatable(
275)         msg="""
276)         The configuration is NOT encrypted, and you are STRONGLY
277)         discouraged from using a stored passphrase.
278)         """,
279)         comments='',
280)         context='help text (long form)',
281)     )
282)     DEPRECATED_COMMAND_LABEL = _prepare_translatable(
283)         msg='(Deprecated) {text}',
284)         comments='',
285)         context='help text (long form, label)',
286)         flags='python-brace-format',
287)     )
288)     DEBUG_OPTION_HELP_TEXT = _prepare_translatable(
289)         'also emit debug information (implies --verbose)',
290)         comments='',
291)         context='help text (option one-line description)',
292)     )
293)     EXPORT_VAULT_FORMAT_HELP_TEXT = _prepare_translatable(
294)         comments=r"""
295)         TRANSLATORS: The defaults_hint is the text in
296)         EXPORT_VAULT_FORMAT_DEFAULTS_HELP_TEXT, the metavar is in
297)         EXPORT_VAULT_FORMAT_METAVAR_FMT.
298)         """,
299)         msg=r"""
300)         try the following storage format {metavar!s}; may be
301)         specified multiple times, formats will be tried in order
302)         {defaults_hint!s}
303)         """,
304)         context='help text (option one-line description)',
305)         flags='python-brace-format',
306)     )
307)     EXPORT_VAULT_FORMAT_DEFAULTS_HELP_TEXT = _prepare_translatable(
308)         comments=r"""
309)         TRANSLATORS: See EXPORT_VAULT_FORMAT_HELP_TEXT.  The format
310)         names/labels "v0.3", "v0.2" and "storeroom" should not be
311)         translated.
312)         """,
313)         msg=r"""
314)         (default: v0.3, v0.2, storeroom)
315)         """,
316)         context='help text (option one-line description)',
317)     )
318)     EXPORT_VAULT_KEY_HELP_TEXT = _prepare_translatable(
319)         comments=r"""
320)         TRANSLATORS: The defaults_hint is the text in
321)         EXPORT_VAULT_KEY_DEFAULTS_HELP_TEXT, the metavar is in
322)         EXPORT_VAULT_KEY_METAVAR_K.
323)         """,
324)         msg=r"""
325)         use {metavar!s} as the storage master key {defaults_hint!s}
326)         """,
327)         context='help text (option one-line description)',
328)         flags='python-brace-format',
329)     )
330)     EXPORT_VAULT_KEY_DEFAULTS_HELP_TEXT = _prepare_translatable(
331)         comments=r"""
332)         TRANSLATORS: See EXPORT_VAULT_KEY_HELP_TEXT.
333)         """,
334)         msg=r"""
335)         (default: check the `VAULT_KEY`, `LOGNAME`, `USER`, or
336)         `USERNAME` environment variables)
337)         """,
338)         context='help text (option one-line description)',
339)     )
340)     QUIET_OPTION_HELP_TEXT = _prepare_translatable(
341)         'suppress even warnings, emit only errors',
342)         comments='',
343)         context='help text (option one-line description)',
344)     )
345)     VERBOSE_OPTION_HELP_TEXT = _prepare_translatable(
346)         'emit extra/progress information to standard error',
347)         comments='',
348)         context='help text (option one-line description)',
349)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

350) 
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

351)     DERIVEPASSPHRASE_VAULT_PHRASE_HELP_TEXT = _prepare_translatable(
352)         msg='prompt for a master passphrase',
353)         comments='',
354)         context='help text (option one-line description)',
355)     )
356)     DERIVEPASSPHRASE_VAULT_KEY_HELP_TEXT = _prepare_translatable(
357)         msg='select a suitable SSH key from the SSH agent',
358)         comments='',
359)         context='help text (option one-line description)',
360)     )
361)     DERIVEPASSPHRASE_VAULT_LENGTH_HELP_TEXT = _prepare_translatable(
362)         comments=r"""
363)         TRANSLATORS: The metavar is specified in
364)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
365)         """,
366)         msg='ensure a passphrase length of {metavar!s} characters',
367)         context='help text (option one-line description)',
368)         flags='python-brace-format',
369)     )
370)     DERIVEPASSPHRASE_VAULT_REPEAT_HELP_TEXT = _prepare_translatable(
371)         comments=r"""
372)         TRANSLATORS: The metavar is specified in
373)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
374)         """,
375)         msg='forbid any run of {metavar!s} identical characters',
376)         context='help text (option one-line description)',
377)         flags='python-brace-format',
378)     )
379)     DERIVEPASSPHRASE_VAULT_LOWER_HELP_TEXT = _prepare_translatable(
380)         comments=r"""
381)         TRANSLATORS: The metavar is specified in
382)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
383)         """,
384)         msg='ensure at least {metavar!s} lowercase characters',
385)         context='help text (option one-line description)',
386)         flags='python-brace-format',
387)     )
388)     DERIVEPASSPHRASE_VAULT_UPPER_HELP_TEXT = _prepare_translatable(
389)         comments=r"""
390)         TRANSLATORS: The metavar is specified in
391)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
392)         """,
393)         msg='ensure at least {metavar!s} uppercase characters',
394)         context='help text (option one-line description)',
395)         flags='python-brace-format',
396)     )
397)     DERIVEPASSPHRASE_VAULT_NUMBER_HELP_TEXT = _prepare_translatable(
398)         comments=r"""
399)         TRANSLATORS: The metavar is specified in
400)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
401)         """,
402)         msg='ensure at least {metavar!s} digits',
403)         context='help text (option one-line description)',
404)         flags='python-brace-format',
405)     )
406)     DERIVEPASSPHRASE_VAULT_SPACE_HELP_TEXT = _prepare_translatable(
407)         comments=r"""
408)         TRANSLATORS: The metavar is specified in
409)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
410)         """,
411)         msg='ensure at least {metavar!s} spaces',
412)         context='help text (option one-line description)',
413)         flags='python-brace-format',
414)     )
415)     DERIVEPASSPHRASE_VAULT_DASH_HELP_TEXT = _prepare_translatable(
416)         comments=r"""
417)         TRANSLATORS: The metavar is specified in
418)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
419)         """,
420)         msg='ensure at least {metavar!s} "-" or "_" characters',
421)         context='help text (option one-line description)',
422)         flags='python-brace-format',
423)     )
424)     DERIVEPASSPHRASE_VAULT_SYMBOL_HELP_TEXT = _prepare_translatable(
425)         comments=r"""
426)         TRANSLATORS: The metavar is specified in
427)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
428)         """,
429)         msg='ensure at least {metavar!s} symbol characters',
430)         context='help text (option one-line description)',
431)         flags='python-brace-format',
432)     )
433) 
434)     DERIVEPASSPHRASE_VAULT_NOTES_HELP_TEXT = _prepare_translatable(
435)         msg='spawn an editor to edit notes for {service_metavar!s}',
436)         comments='',
437)         context='help text (option one-line description)',
438)         flags='python-brace-format',
439)     )
440)     DERIVEPASSPHRASE_VAULT_CONFIG_HELP_TEXT = _prepare_translatable(
441)         msg='save the given settings for {service_metavar!s}, or global',
442)         comments='',
443)         context='help text (option one-line description)',
444)         flags='python-brace-format',
445)     )
446)     DERIVEPASSPHRASE_VAULT_DELETE_HELP_TEXT = _prepare_translatable(
447)         msg='delete the settings for {service_metavar!s}',
448)         comments='',
449)         context='help text (option one-line description)',
450)         flags='python-brace-format',
451)     )
452)     DERIVEPASSPHRASE_VAULT_DELETE_GLOBALS_HELP_TEXT = _prepare_translatable(
453)         msg='delete the global settings',
454)         comments='',
455)         context='help text (option one-line description)',
456)     )
457)     DERIVEPASSPHRASE_VAULT_DELETE_ALL_HELP_TEXT = _prepare_translatable(
458)         msg='delete all settings',
459)         comments='',
460)         context='help text (option one-line description)',
461)     )
462)     DERIVEPASSPHRASE_VAULT_EXPORT_HELP_TEXT = _prepare_translatable(
463)         comments="""
464)         TRANSLATORS: The metavar is specified in
465)         STORAGE_MANAGEMENT_METAVAR_SERVICE.
466)         """,
467)         msg='export all saved settings to {metavar!s}',
468)         context='help text (option one-line description)',
469)         flags='python-brace-format',
470)     )
471)     DERIVEPASSPHRASE_VAULT_IMPORT_HELP_TEXT = _prepare_translatable(
472)         comments="""
473)         TRANSLATORS: The metavar is specified in
474)         STORAGE_MANAGEMENT_METAVAR_SERVICE.
475)         """,
476)         msg='import saved settings from {metavar!s}',
477)         context='help text (option one-line description)',
478)         flags='python-brace-format',
479)     )
480)     DERIVEPASSPHRASE_VAULT_OVERWRITE_HELP_TEXT = _prepare_translatable(
481)         comments="""
482)         TRANSLATORS: The corresponding option is displayed as
483)         "--overwrite-existing / --merge-existing", so you may want to
484)         hint that the default (merge) is the second of those options.
485)         """,
486)         msg='overwrite or merge (default) the existing configuration',
487)         context='help text (option one-line description)',
488)         flags='python-brace-format',
489)     )
490)     DERIVEPASSPHRASE_VAULT_UNSET_HELP_TEXT = _prepare_translatable(
491)         comments="""
492)         TRANSLATORS: The corresponding option is displayed as
493)         "--unset=phrase|key|...|symbol", so the "given setting" is
494)         referring to "phrase", "key", "lower", ..., or "symbol",
495)         respectively.  "with --config" here means that the user must
496)         also specify "--config" for this option to have any effect.
497)         """,
498)         msg="""
499)         with --config, also unsets the given setting; may be specified
500)         multiple times
501)         """,
502)         context='help text (option one-line description)',
503)     )
504)     DERIVEPASSPHRASE_VAULT_EXPORT_AS_HELP_TEXT = _prepare_translatable(
505)         comments="""
506)         TRANSLATORS: The corresponding option is displayed as
507)         "--export-as=json|sh", so json refers to the JSON format
508)         (default) and sh refers to the POSIX sh format.
509)         """,
510)         msg='when exporting, export as JSON (default) or POSIX sh',
511)         context='help text (option one-line description)',
512)     )
513) 
514)     EXPORT_VAULT_FORMAT_METAVAR_FMT = _prepare_translatable(
515)         msg='FMT',
516)         comments='',
517)         context='help text, metavar (export vault subcommand)',
518)     )
519)     EXPORT_VAULT_KEY_METAVAR_K = _prepare_translatable(
520)         comments=r"""
521)         TRANSLATORS: See EXPORT_VAULT_KEY_HELP_TEXT.
522)         """,
523)         msg='K',
524)         context='help text, metavar (export vault subcommand)',
525)     )
526)     EXPORT_VAULT_METAVAR_PATH = _prepare_translatable(
527)         comments=r"""
528)         TRANSLATORS: This metavar is also used in multiple one-line help
529)         texts, as "path_metavar".
530)         """,
531)         msg='PATH',
532)         context='help text, metavar (export vault subcommand)',
533)     )
534)     PASSPHRASE_GENERATION_METAVAR_NUMBER = _prepare_translatable(
535)         comments=r"""
536)         TRANSLATORS: This metavar is also used in a matching epilog.
537)         """,
538)         msg='NUMBER',
539)         context='help text, metavar (passphrase generation group)',
540)     )
541)     STORAGE_MANAGEMENT_METAVAR_PATH = _prepare_translatable(
542)         comments=r"""
543)         TRANSLATORS: This metavar is also used in multiple one-line help
544)         texts.
545)         """,
546)         msg='NUMBER',
547)         context='help text, metavar (storage management group)',
548)     )
549)     VAULT_METAVAR_SERVICE = _prepare_translatable(
550)         comments=r"""
551)         TRANSLATORS: This metavar is also used in multiple one-line help
552)         texts, as "service_metavar".
553)         """,
554)         msg='SERVICE',
555)         context='help text, metavar (vault subcommand)',
556)     )
557)     CONFIGURATION_EPILOG = _prepare_translatable(
558)         'Use $VISUAL or $EDITOR to configure the spawned editor.',
559)         comments='',
560)         context='help text, option group epilog (configuration group)',
561)     )
562)     PASSPHRASE_GENERATION_EPILOG = _prepare_translatable(
563)         comments=r"""
564)         TRANSLATORS: The metavar is specified in
565)         PASSPHRASE_GENERATION_METAVAR_NUMBER.
566)         """,
567)         msg=r"""
568)         Use {metavar!s}=0 to exclude a character type from the output.
569)         """,
570)         context='help text, option group epilog (passphrase generation group)',
571)         flags='python-brace-format',
572)     )
573)     STORAGE_MANAGEMENT_EPILOG = _prepare_translatable(
574)         comments=r"""
575)         TRANSLATORS: The metavar is specified in
576)         STORAGE_MANAGEMENT_METAVAR_PATH.
577)         """,
578)         msg=r"""
579)         Using "-" as {metavar!s} for standard input/standard output
580)         is supported.
581)         """,
582)         context='help text, option group epilog (storage management group)',
583)         flags='python-brace-format',
584)     )
585)     COMMANDS_LABEL = _prepare_translatable(
586)         'Commands', comments='', context='help text, option group name'
587)     )
588)     COMPATIBILITY_OPTION_LABEL = _prepare_translatable(
589)         'Compatibility and extension options',
590)         comments='',
591)         context='help text, option group name',
592)     )
593)     CONFIGURATION_LABEL = _prepare_translatable(
594)         'Configuration', comments='', context='help text, option group name'
595)     )
596)     LOGGING_LABEL = _prepare_translatable(
597)         'Logging', comments='', context='help text, option group name'
598)     )
599)     OPTIONS_LABEL = _prepare_translatable(
600)         'Options', comments='', context='help text, option group name'
601)     )
602)     OTHER_OPTIONS_LABEL = _prepare_translatable(
603)         'Other options', comments='', context='help text, option group name'
604)     )
605)     PASSPHRASE_GENERATION_LABEL = _prepare_translatable(
606)         'Passphrase generation',
607)         comments='',
608)         context='help text, option group name',
609)     )
610)     STORAGE_MANAGEMENT_LABEL = _prepare_translatable(
611)         'Storage management',
612)         comments='',
613)         context='help text, option group name',
614)     )
615)     CONFIRM_THIS_CHOICE_PROMPT_TEXT = _prepare_translatable(
616)         comments=r"""
617)         TRANSLATORS: There is no support for "yes" or "no" in other
618)         languages than English, so it is advised that your translation
619)         makes it clear that only the strings "y", "yes", "n" or "no" are
620)         supported, even if the prompt becomes a bit longer.
621)         """,
622)         msg='Confirm this choice? (y/N)',
623)         context='interactive prompt',
624)     )
625)     SUITABLE_SSH_KEYS_LABEL = _prepare_translatable(
626)         comments=r"""
627)         TRANSLATORS: This label is the heading of the list of suitable
628)         SSH keys.
629)         """,
630)         msg='Suitable SSH keys:',
631)         context='interactive prompt',
632)     )
633)     YOUR_SELECTION_PROMPT_TEXT = _prepare_translatable(
634)         'Your selection? (1-{n}, leave empty to abort)',
635)         comments='',
636)         context='interactive prompt',
637)         flags='python-brace-format',
638)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

639) 
640) 
641) class InfoMsgTemplate(enum.Enum):
642)     CANNOT_LOAD_AS_VAULT_CONFIG = _prepare_translatable(
643)         comments=r"""
644)         TRANSLATORS: "fmt" is a string such as "v0.2" or "storeroom",
645)         indicating the format which we tried to load the vault
646)         configuration as.
647)         """,
648)         msg='Cannot load {path!r} as a {fmt!s} vault configuration.',
649)         context='info message',
650)         flags='python-brace-format',
651)     )
652)     PIP_INSTALL_EXTRA = _prepare_translatable(
653)         comments=r"""
654)         TRANSLATORS: This message immediately follows an error message
655)         about a missing library that needs to be installed.  The Python
656)         Package Index (PyPI) supports declaring sets of optional
657)         dependencies as "extras", so users installing from PyPI can
658)         request reinstallation with a named "extra" being enabled.  This
659)         would then let the installer take care of the missing libraries
660)         automatically, hence this suggestion to PyPI users.
661)         """,
662)         msg='(For users installing from PyPI, see the {extra_name!r} extra.)',
663)         context='info message',
664)         flags='python-brace-format',
665)     )
666)     SUCCESSFULLY_MIGRATED = _prepare_translatable(
667)         comments=r"""
668)         TRANSLATORS: This info message immediately follows the "Using
669)         deprecated v0.1-style ..." deprecation warning.
670)         """,
671)         msg='Successfully migrated to {path!r}.',
672)         context='info message',
673)         flags='python-brace-format',
674)     )
675) 
676) 
677) class WarnMsgTemplate(enum.Enum):
678)     EMPTY_SERVICE_NOT_SUPPORTED = _prepare_translatable(
679)         comments='',
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

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

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

687)     )
688)     EMPTY_SERVICE_SETTINGS_INACCESSIBLE = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

689)         msg="""
690)         An empty {service_metavar!s} is not supported by vault(1).
691)         The empty-string service settings will be inaccessible and
692)         ineffective.  To ensure that vault(1) and {PROG_NAME!s} see the
693)         settings, move them into the "global" section.
694)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

695)         comments='',
696)         context='warning message',
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

698)     )
699)     FAILED_TO_MIGRATE_CONFIG = _prepare_translatable(
700)         comments=r"""
701)         TRANSLATORS: The error message is usually supplied by the
702)         operating system, e.g. ENOENT/"No such file or directory".
703)         """,
704)         msg='Failed to migrate to {path!r}: {error!s}: {filename!r}.',
705)         context='warning message',
706)         flags='python-brace-format',
707)     )
708)     GLOBAL_PASSPHRASE_INEFFECTIVE = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

709)         msg=r"""
710)         Setting a global passphrase is ineffective
711)         because a key is also set.
712)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

713)         comments='',
714)         context='warning message',
715)     )
716)     PASSPHRASE_NOT_NORMALIZED = _prepare_translatable(
717)         comments=r"""
718)         TRANSLATORS: The key is a (vault) configuration key, in JSONPath
719)         syntax, typically "$.global" for the global passphrase or
720)         "$.services.service_name" or "$.services["service with spaces"]"
721)         for the services "service_name" and "service with spaces",
722)         respectively.  The form is one of the four Unicode normalization
723)         forms: NFC, NFD, NFKC, NFKD.
724) 
725)         The asterisks are not special.  Please feel free to substitute
726)         any other appropriate way to mark up emphasis of the word
727)         "displays".
728)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

735)         context='warning message',
736)         flags='python-brace-format',
737)     )
738)     SERVICE_PASSPHRASE_INEFFECTIVE = _prepare_translatable(
739)         comments=r"""
740)         TRANSLATORS: The key that is set need not necessarily be set at
741)         the service level; it may be a global key as well.
742)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

743)         msg=r"""
744)         Setting a service passphrase is ineffective because a key is
745)         also set: {service!s}.
746)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

747)         context='warning message',
748)         flags='python-brace-format',
749)     )
750)     STEP_REMOVE_INEFFECTIVE_VALUE = _prepare_translatable(
751)         'Removing ineffective setting {path!s} = {old!s}.',
752)         comments='',
753)         context='warning message',
754)         flags='python-brace-format',
755)     )
756)     STEP_REPLACE_INVALID_VALUE = _prepare_translatable(
757)         'Replacing invalid value {old!s} for key {path!s} with {new!s}.',
758)         comments='',
759)         context='warning message',
760)         flags='python-brace-format',
761)     )
762)     V01_STYLE_CONFIG = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

763)         msg=r"""
764)         Using deprecated v0.1-style config file {old!r}, instead of
765)         v0.2-style {new!r}.  Support for v0.1-style config filenames
766)         will be removed in v1.0.,
767)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

768)         comments='',
769)         context='deprecation warning message',
770)         flags='python-brace-format',
771)     )
772)     V10_SUBCOMMAND_REQUIRED = _prepare_translatable(
773)         comments=r"""
774)         TRANSLATORS: This deprecation warning may be issued at any
775)         level, i.e. we may actually be talking about subcommands, or
776)         sub-subcommands, or sub-sub-subcommands, etc., which is what the
777)         "here" is supposed to indicate.
778)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

779)         msg="""
780)         A subcommand will be required here in v1.0.  See --help for
781)         available subcommands.  Defaulting to subcommand "vault".
782)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

783)         context='deprecation warning message',
784)     )
785) 
786) 
787) class ErrMsgTemplate(enum.Enum):
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

788)     AGENT_REFUSED_LIST_KEYS = _prepare_translatable(
789)         comments=r"""
790)         TRANSLATORS: "loaded keys" being keys loaded into the agent.
791)         """,
792)         msg="""
793)         The SSH agent failed to or refused to supply a list of loaded keys.
794)         """,
795)         context='error message',
796)     )
797)     AGENT_REFUSED_SIGNATURE = _prepare_translatable(
798)         comments=r"""
799)         TRANSLATORS: The message to be signed is the vault UUID, but
800)         there's no space to explain that here, so ideally the error
801)         message does not go into detail.
802)         """,
803)         msg="""
804)         The SSH agent failed to or refused to issue a signature with the
805)         selected key, necessary for deriving a service passphrase.
806)         """,
807)         context='error message',
808)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

809)     CANNOT_CONNECT_TO_AGENT = _prepare_translatable(
810)         comments=r"""
811)         TRANSLATORS: The error message is usually supplied by the
812)         operating system, e.g. ENOENT/"No such file or directory".
813)         """,
814)         msg='Cannot connect to the SSH agent: {error!s}: {filename!r}.',
815)         context='error message',
816)         flags='python-brace-format',
817)     )
818)     CANNOT_DECODEIMPORT_VAULT_SETTINGS = _prepare_translatable(
819)         msg='Cannot import vault settings: cannot decode JSON: {error!s}.',
820)         comments='',
821)         context='error message',
822)         flags='python-brace-format',
823)     )
824)     CANNOT_EXPORT_VAULT_SETTINGS = _prepare_translatable(
825)         comments=r"""
826)         TRANSLATORS: The error message is usually supplied by the
827)         operating system, e.g. ENOENT/"No such file or directory".
828)         """,
829)         msg='Cannot export vault settings: {error!s}: {filename!r}.',
830)         context='error message',
831)         flags='python-brace-format',
832)     )
833)     CANNOT_IMPORT_VAULT_SETTINGS = _prepare_translatable(
834)         comments=r"""
835)         TRANSLATORS: The error message is usually supplied by the
836)         operating system, e.g. ENOENT/"No such file or directory".
837)         """,
838)         msg='Cannot import vault settings: {error!s}: {filename!r}.',
839)         context='error message',
840)         flags='python-brace-format',
841)     )
842)     CANNOT_LOAD_USER_CONFIG = _prepare_translatable(
843)         comments=r"""
844)         TRANSLATORS: The error message is usually supplied by the
845)         operating system, e.g. ENOENT/"No such file or directory".
846)         """,
847)         msg='Cannot load user config: {error!s}: {filename!r}.',
848)         context='error message',
849)         flags='python-brace-format',
850)     )
851)     CANNOT_LOAD_VAULT_SETTINGS = _prepare_translatable(
852)         comments=r"""
853)         TRANSLATORS: The error message is usually supplied by the
854)         operating system, e.g. ENOENT/"No such file or directory".
855)         """,
856)         msg='Cannot load vault settings: {error!s}: {filename!r}.',
857)         context='error message',
858)         flags='python-brace-format',
859)     )
860)     CANNOT_PARSE_AS_VAULT_CONFIG = _prepare_translatable(
861)         comments=r"""
862)         TRANSLATORS: Unlike the "Cannot load {path!r} as a {fmt!s} vault
863)         configuration." message, *this* error message is emitted when we
864)         have tried loading the path in each of our supported formats,
865)         and failed.  The user will thus see the above "Cannot load ..."
866)         warning message potentially multiple times, and this error
867)         message at the very bottom.
868)         """,
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

869)         msg=r"""
870)         Cannot parse {path!r} as a valid vault-native configuration
871)         file/directory.
872)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

873)         context='error message',
874)         flags='python-brace-format',
875)     )
876)     CANNOT_STORE_VAULT_SETTINGS = _prepare_translatable(
877)         comments=r"""
878)         TRANSLATORS: The error message is usually supplied by the
879)         operating system, e.g. ENOENT/"No such file or directory".
880)         """,
881)         msg='Cannot store vault settings: {error!s}: {filename!r}.',
882)         context='error message',
883)         flags='python-brace-format',
884)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

885)     CANNOT_UNDERSTAND_AGENT = _prepare_translatable(
886)         comments=r"""
887)         TRANSLATORS: This error message is used whenever we cannot make
888)         any sense of a response from the SSH agent because the response
889)         is ill-formed (truncated, improperly encoded, etc.) or otherwise
890)         violates the communications protocol.  Well-formed responses
891)         that adhere to the protocol, even if they indicate that the
892)         requested operation failed, are handled with a different error
893)         message.
894)         """,
895)         msg="""
896)         Cannot understand the SSH agent's response because it violates
897)         the communications protocol.
898)         """,
899)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

900)     CANNOT_UPDATE_SETTINGS_NO_SETTINGS = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

901)         msg=r"""
902)         Cannot update {settings_type!s} settings without any given
903)         settings.  You must specify at least one of --lower, ...,
904)         --symbol, or --phrase or --key.
905)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

906)         comments='',
907)         context='error message',
908)         flags='python-brace-format',
909)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

910)     INVALID_USER_CONFIG = _prepare_translatable(
911)         comments=r"""
912)         TRANSLATORS: The error message is usually supplied by the
913)         operating system, e.g. ENOENT/"No such file or directory".
914)         """,
915)         msg=r"""
916)         The user configuration file is invalid.  {error!s}: {filename!r}.
917)         """,
918)         context='error message',
919)         flags='python-brace-format',
920)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

921)     INVALID_VAULT_CONFIG = _prepare_translatable(
922)         comments=r"""
923)         TRANSLATORS: This error message is a reaction to a validator
924)         function saying *that* the configuration is not valid, but not
925)         *how* it is not valid.  The configuration file is principally
926)         parsable, however.
927)         """,
928)         msg='Invalid vault config: {config!r}.',
929)         context='error message',
930)         flags='python-brace-format',
931)     )
932)     MISSING_MODULE = _prepare_translatable(
933)         'Cannot load the required Python module {module!r}.',
934)         comments='',
935)         context='error message',
936)         flags='python-brace-format',
937)     )
938)     NO_AF_UNIX = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

939)         msg=r"""
940)         Cannot connect to an SSH agent because this Python version does
941)         not support UNIX domain sockets.
942)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

943)         comments='',
944)         context='error message',
945)     )
946)     NO_KEY_OR_PHRASE = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

947)         msg=r"""
948)         No passphrase or key was given in the configuration.  In this
949)         case, the --phrase or --key argument is required.
950)         """,
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

951)         comments='',
952)         context='error message',
953)     )
954)     NO_SSH_AGENT_FOUND = _prepare_translatable(
955)         'Cannot find any running SSH agent because SSH_AUTH_SOCK is not set.',
956)         comments='',
957)         context='error message',
958)     )
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

959)     NO_SUITABLE_SSH_KEYS = _prepare_translatable(
960)         msg="""
961)         The SSH agent contains no keys suitable for {PROG_NAME!s}.
962)         """,  # noqa: RUF027
963)         comments='',
964)         context='error message',
965)         flags='python-brace-format',
966)     )
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

967)     PARAMS_MUTUALLY_EXCLUSIVE = _prepare_translatable(
968)         comments=r"""
969)         TRANSLATORS: The params are long-form command-line option names.
970)         Typical example: "--key is mutually exclusive with --phrase."
971)         """,
972)         msg='{param1!s} is mutually exclusive with {param2!s}.',
973)         context='error message',
974)         flags='python-brace-format',
975)     )
976)     PARAMS_NEEDS_SERVICE_OR_CONFIG = _prepare_translatable(
977)         comments=r"""
978)         TRANSLATORS: The param is a long-form command-line option name,
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

979)         and the metavar is given in VAULT_METAVAR_SERVICE.
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

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

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

982)         context='error message',
983)         flags='python-brace-format',
984)     )
985)     PARAMS_NEEDS_SERVICE = _prepare_translatable(
986)         comments=r"""
987)         TRANSLATORS: The param is a long-form command-line option name,
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

988)         and the metavar is given in VAULT_METAVAR_SERVICE.
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

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

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

991)         context='error message',
992)         flags='python-brace-format',
993)     )
994)     PARAMS_NO_SERVICE = _prepare_translatable(
995)         comments=r"""
996)         TRANSLATORS: The param is a long-form command-line option name,
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

997)         and the metavar is given in VAULT_METAVAR_SERVICE.
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

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

Marco Ricci authored 1 week ago

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

Marco Ricci authored 2 weeks ago

1000)         context='error message',
1001)         flags='python-brace-format',
1002)     )
1003)     SERVICE_REQUIRED = _prepare_translatable(
Marco Ricci Add more translatable strin...

Marco Ricci authored 1 week ago

1004)         comments=r"""
1005)         TRANSLATORS: The metavar is given in VAULT_METAVAR_SERVICE.
1006)         """,
1007)         msg='Deriving a passphrase requires a {service_metavar!s}.',
1008)         context='error message',
1009)         flags='python-brace-format',
1010)     )
1011)     SET_AND_UNSET_SAME_SETTING = _prepare_translatable(
1012)         comments=r"""
1013)         TRANSLATORS: The rephrasing "Attempted to unset and set the same
1014)         setting (--unset={setting!s} --{setting!s}=...) at the same
1015)         time." may or may not be more suitable as a basis for
1016)         translation instead.
1017)         """,
1018)         msg='Attempted to unset and set --{setting!s} at the same time.',
Marco Ricci Extract translatable log me...

Marco Ricci authored 2 weeks ago

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

Marco Ricci authored 1 week ago

1020)         flags='python-brace-format',