Marco Ricci commited on 2025-02-15 00:01:29
Zeige 3 geänderte Dateien mit 57 Einfügungen und 1 Löschungen.
Emit known and supported features in the version output, such as master SSH key support for the `vault` subcommand.
| ... | ... |
@@ -20,6 +20,7 @@ import importlib.metadata |
| 20 | 20 |
import inspect |
| 21 | 21 |
import logging |
| 22 | 22 |
import os |
| 23 |
+import socket |
|
| 23 | 24 |
import warnings |
| 24 | 25 |
from typing import TYPE_CHECKING, Callable, Literal, TextIO, TypeVar |
| 25 | 26 |
|
| ... | ... |
@@ -1126,6 +1127,19 @@ def vault_version_option_callback( |
| 1126 | 1127 |
) -> None: |
| 1127 | 1128 |
if value and not ctx.resilient_parsing: |
| 1128 | 1129 |
common_version_output(ctx, param, value) |
| 1130 |
+ features = {
|
|
| 1131 |
+ 'master SSH key': hasattr(socket, 'AF_UNIX'), |
|
| 1132 |
+ } |
|
| 1133 |
+ click.echo() |
|
| 1134 |
+ version_info_types = {
|
|
| 1135 |
+ _msg.Label.SUPPORTED_FEATURES: [ |
|
| 1136 |
+ k for k, v in features.items() if v |
|
| 1137 |
+ ], |
|
| 1138 |
+ _msg.Label.KNOWN_FEATURES: [ |
|
| 1139 |
+ k for k, v in features.items() if not v |
|
| 1140 |
+ ], |
|
| 1141 |
+ } |
|
| 1142 |
+ print_version_info_types(version_info_types, ctx=ctx) |
|
| 1129 | 1143 |
ctx.exit() |
| 1130 | 1144 |
|
| 1131 | 1145 |
|
| ... | ... |
@@ -1300,6 +1300,16 @@ class Label(enum.Enum): |
| 1300 | 1300 |
'Known derivation schemes:', |
| 1301 | 1301 |
) |
| 1302 | 1302 |
"""""" |
| 1303 |
+ KNOWN_FEATURES = commented( |
|
| 1304 |
+ 'This is part of the version output, emitting lists of known, ' |
|
| 1305 |
+ 'unavailable features for this subcommand. ' |
|
| 1306 |
+ 'A comma-separated English list of items follows, ' |
|
| 1307 |
+ 'with standard English punctuation.', |
|
| 1308 |
+ )( |
|
| 1309 |
+ 'Label :: Info Message:: Table row header', |
|
| 1310 |
+ 'Known features:', |
|
| 1311 |
+ ) |
|
| 1312 |
+ """""" |
|
| 1303 | 1313 |
KNOWN_FOREIGN_CONFIGURATION_FORMATS = commented( |
| 1304 | 1314 |
'This is part of the version output, emitting lists of known ' |
| 1305 | 1315 |
'foreign configuration formats. A comma-separated English list ' |
| ... | ... |
@@ -1318,6 +1328,15 @@ class Label(enum.Enum): |
| 1318 | 1328 |
'Supported derivation schemes:', |
| 1319 | 1329 |
) |
| 1320 | 1330 |
"""""" |
| 1331 |
+ SUPPORTED_FEATURES = commented( |
|
| 1332 |
+ 'This is part of the version output, emitting lists of supported ' |
|
| 1333 |
+ 'features for this subcommand. A comma-separated ' |
|
| 1334 |
+ 'English list of items follows, with standard English punctuation.', |
|
| 1335 |
+ )( |
|
| 1336 |
+ 'Label :: Info Message:: Table row header', |
|
| 1337 |
+ 'Supported features:', |
|
| 1338 |
+ ) |
|
| 1339 |
+ """""" |
|
| 1321 | 1340 |
SUPPORTED_FOREIGN_CONFIGURATION_FORMATS = commented( |
| 1322 | 1341 |
'This is part of the version output, emitting lists of supported ' |
| 1323 | 1342 |
'foreign configuration formats. A comma-separated English list ' |
| ... | ... |
@@ -86,6 +86,7 @@ class VersionOutputData(NamedTuple): |
| 86 | 86 |
foreign_configuration_formats: dict[str, bool] |
| 87 | 87 |
extras: frozenset[str] |
| 88 | 88 |
subcommands: frozenset[str] |
| 89 |
+ features: dict[str, bool] |
|
| 89 | 90 |
|
| 90 | 91 |
|
| 91 | 92 |
PASSPHRASE_GENERATION_OPTIONS: list[tuple[str, ...]] = [ |
| ... | ... |
@@ -405,12 +406,14 @@ def parse_version_output( # noqa: C901 |
| 405 | 406 |
formats: dict[str, bool] = {}
|
| 406 | 407 |
subcommands: set[str] = set() |
| 407 | 408 |
extras: set[str] = set() |
| 408 |
- if len(paragraphs) < 2: |
|
| 409 |
+ features: dict[str, bool] = {}
|
|
| 410 |
+ if len(paragraphs) < 2: # pragma: no cover |
|
| 409 | 411 |
return VersionOutputData( |
| 410 | 412 |
derivation_schemes=schemes, |
| 411 | 413 |
foreign_configuration_formats=formats, |
| 412 | 414 |
subcommands=frozenset(subcommands), |
| 413 | 415 |
extras=frozenset(extras), |
| 416 |
+ features=features, |
|
| 414 | 417 |
) |
| 415 | 418 |
for line in paragraphs[1]: |
| 416 | 419 |
line_type, _, value = line.partition(':')
|
| ... | ... |
@@ -432,6 +435,10 @@ def parse_version_output( # noqa: C901 |
| 432 | 435 |
subcommands.add(item) |
| 433 | 436 |
elif line_type == 'PEP 508 extras': |
| 434 | 437 |
extras.add(item) |
| 438 |
+ elif line_type == 'Supported features': |
|
| 439 |
+ features[item] = True |
|
| 440 |
+ elif line_type == 'Known features': |
|
| 441 |
+ features[item] = False |
|
| 435 | 442 |
else: |
| 436 | 443 |
raise AssertionError( # noqa: TRY003 |
| 437 | 444 |
f'Unknown version info line type: {line_type!r}' # noqa: EM102
|
| ... | ... |
@@ -441,6 +448,7 @@ def parse_version_output( # noqa: C901 |
| 441 | 448 |
foreign_configuration_formats=formats, |
| 442 | 449 |
subcommands=frozenset(subcommands), |
| 443 | 450 |
extras=frozenset(extras), |
| 451 |
+ features=features, |
|
| 444 | 452 |
) |
| 445 | 453 |
|
| 446 | 454 |
|
| ... | ... |
@@ -1481,6 +1489,7 @@ PEP 508 extras: export. |
| 1481 | 1489 |
'vault v0.3': True, |
| 1482 | 1490 |
}, |
| 1483 | 1491 |
subcommands=frozenset(), |
| 1492 |
+ features={},
|
|
| 1484 | 1493 |
extras=frozenset({'export'}),
|
| 1485 | 1494 |
), |
| 1486 | 1495 |
id='derivepassphrase-0.4.0-export', |
| ... | ... |
@@ -1504,6 +1513,7 @@ No PEP 508 extras are active. |
| 1504 | 1513 |
'vault v0.3': False, |
| 1505 | 1514 |
}, |
| 1506 | 1515 |
subcommands=frozenset({'export', 'vault'}),
|
| 1516 |
+ features={},
|
|
| 1507 | 1517 |
extras=frozenset({}),
|
| 1508 | 1518 |
), |
| 1509 | 1519 |
id='derivepassphrase-0.5-plain', |
| ... | ... |
@@ -1525,6 +1535,8 @@ Supported foreign configuration formats: derivepassphrase, nonsense. |
| 1525 | 1535 |
Known foreign configuration formats: divination v3.141592, |
| 1526 | 1536 |
/dev/random. |
| 1527 | 1537 |
Supported subcommands: delete-all-files, dump-core. |
| 1538 |
+Supported features: delete-while-open. |
|
| 1539 |
+Known features: backups-are-nice-to-have. |
|
| 1528 | 1540 |
PEP 508 extras: annoying-popups, delete-all-files, |
| 1529 | 1541 |
dump-core-depending-on-the-phase-of-the-moon. |
| 1530 | 1542 |
|
| ... | ... |
@@ -1548,6 +1560,10 @@ PEP 508 extras: annoying-popups, delete-all-files, |
| 1548 | 1560 |
'/dev/random': False, |
| 1549 | 1561 |
}, |
| 1550 | 1562 |
subcommands=frozenset({'delete-all-files', 'dump-core'}),
|
| 1563 |
+ features={
|
|
| 1564 |
+ 'delete-while-open': True, |
|
| 1565 |
+ 'backups-are-nice-to-have': False, |
|
| 1566 |
+ }, |
|
| 1551 | 1567 |
extras=frozenset({
|
| 1552 | 1568 |
'annoying-popups', |
| 1553 | 1569 |
'delete-all-files', |
| ... | ... |
@@ -1837,6 +1853,7 @@ class TestAllCLI: |
| 1837 | 1853 |
assert version_data.derivation_schemes == actually_known_schemes |
| 1838 | 1854 |
assert not version_data.foreign_configuration_formats |
| 1839 | 1855 |
assert version_data.subcommands == subcommands |
| 1856 |
+ assert not version_data.features |
|
| 1840 | 1857 |
assert not version_data.extras |
| 1841 | 1858 |
|
| 1842 | 1859 |
def test_202b_export_version_option_output( |
| ... | ... |
@@ -1885,6 +1902,7 @@ class TestAllCLI: |
| 1885 | 1902 |
== actually_known_formats |
| 1886 | 1903 |
) |
| 1887 | 1904 |
assert version_data.subcommands == subcommands |
| 1905 |
+ assert not version_data.features |
|
| 1888 | 1906 |
assert not version_data.extras |
| 1889 | 1907 |
|
| 1890 | 1908 |
def test_202c_export_vault_version_option_output( |
| ... | ... |
@@ -1939,6 +1957,7 @@ class TestAllCLI: |
| 1939 | 1957 |
== actually_known_formats |
| 1940 | 1958 |
) |
| 1941 | 1959 |
assert not version_data.subcommands |
| 1960 |
+ assert not version_data.features |
|
| 1942 | 1961 |
assert version_data.extras == actually_enabled_extras |
| 1943 | 1962 |
|
| 1944 | 1963 |
def test_202d_vault_version_option_output( |
| ... | ... |
@@ -1974,9 +1993,13 @@ class TestAllCLI: |
| 1974 | 1993 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
| 1975 | 1994 |
assert result.output.strip(), 'expected version output' |
| 1976 | 1995 |
version_data = parse_version_output(result.output) |
| 1996 |
+ features: dict[str, bool] = {
|
|
| 1997 |
+ 'master SSH key': hasattr(socket, 'AF_UNIX'), |
|
| 1998 |
+ } |
|
| 1977 | 1999 |
assert not version_data.derivation_schemes |
| 1978 | 2000 |
assert not version_data.foreign_configuration_formats |
| 1979 | 2001 |
assert not version_data.subcommands |
| 2002 |
+ assert version_data.features == features |
|
| 1980 | 2003 |
assert not version_data.extras |
| 1981 | 2004 |
|
| 1982 | 2005 |
|
| 1983 | 2006 |