Marco Ricci commited on 2025-02-06 13:16:37
Zeige 4 geänderte Dateien mit 92 Einfügungen und 0 Löschungen.
In 7b0f4e121a5e688b59abad73b8b60bacfc7d02ed, we adjusted `derivepassphrase` to only act upon `--notes` if `--config` is also given, for compatibility with vault(1). However, this is incompatible with previous versions of `derivepassphrase`, and potentially confusing even to vault(1) users. As such, `derivepassphrase vault` now emits a warning if it is called with `--notes` but without `--config`.
... | ... |
@@ -1740,6 +1740,13 @@ class InfoMsgTemplate(enum.Enum): |
1740 | 1740 |
class WarnMsgTemplate(enum.Enum): |
1741 | 1741 |
"""Warning messages for the `derivepassphrase` command-line.""" |
1742 | 1742 |
|
1743 |
+ EDITING_NOTES_BUT_NOT_STORING_CONFIG = commented( |
|
1744 |
+ '', |
|
1745 |
+ )( |
|
1746 |
+ 'Warning message', |
|
1747 |
+ 'Specifying --notes without --config is ineffective. ' |
|
1748 |
+ 'No notes will be edited.', |
|
1749 |
+ ) |
|
1743 | 1750 |
EMPTY_SERVICE_NOT_SUPPORTED = commented( |
1744 | 1751 |
'', |
1745 | 1752 |
)( |
... | ... |
@@ -987,6 +987,15 @@ def derivepassphrase_vault( # noqa: C901,PLR0912,PLR0913,PLR0914,PLR0915 |
987 | 987 |
extra={'color': ctx.color}, |
988 | 988 |
) |
989 | 989 |
|
990 |
+ if edit_notes and not store_config_only: |
|
991 |
+ logger.warning( |
|
992 |
+ _msg.TranslatedString( |
|
993 |
+ _msg.WarnMsgTemplate.EDITING_NOTES_BUT_NOT_STORING_CONFIG, |
|
994 |
+ service_metavar=service_metavar, |
|
995 |
+ ), |
|
996 |
+ extra={'color': ctx.color}, |
|
997 |
+ ) |
|
998 |
+ |
|
990 | 999 |
if delete_service_settings: |
991 | 1000 |
assert service is not None |
992 | 1001 |
configuration = get_config() |
... | ... |
@@ -2763,6 +2763,81 @@ class TestCLI: |
2763 | 2763 |
'services': {}, |
2764 | 2764 |
} |
2765 | 2765 |
|
2766 |
+ @hypothesis.settings( |
|
2767 |
+ suppress_health_check=[ |
|
2768 |
+ *hypothesis.settings().suppress_health_check, |
|
2769 |
+ hypothesis.HealthCheck.function_scoped_fixture, |
|
2770 |
+ ], |
|
2771 |
+ ) |
|
2772 |
+ @hypothesis.given( |
|
2773 |
+ notes=strategies.text( |
|
2774 |
+ strategies.characters( |
|
2775 |
+ min_codepoint=32, max_codepoint=126, include_characters='\n' |
|
2776 |
+ ), |
|
2777 |
+ max_size=512, |
|
2778 |
+ ), |
|
2779 |
+ ) |
|
2780 |
+ def test_223b_edit_notes_fail_config_option_missing( |
|
2781 |
+ self, |
|
2782 |
+ caplog: pytest.LogCaptureFixture, |
|
2783 |
+ notes: str, |
|
2784 |
+ ) -> None: |
|
2785 |
+ """Editing notes fails (and warns) if `--config` is missing.""" |
|
2786 |
+ maybe_notes = {'notes': notes.strip()} if notes.strip() else {} |
|
2787 |
+ vault_config = { |
|
2788 |
+ 'global': {'phrase': DUMMY_PASSPHRASE}, |
|
2789 |
+ 'services': { |
|
2790 |
+ DUMMY_SERVICE: {**maybe_notes, **DUMMY_CONFIG_SETTINGS} |
|
2791 |
+ }, |
|
2792 |
+ } |
|
2793 |
+ # Reset caplog between hypothesis runs. |
|
2794 |
+ caplog.clear() |
|
2795 |
+ runner = click.testing.CliRunner(mix_stderr=False) |
|
2796 |
+ # TODO(the-13th-letter): Rewrite using parenthesized |
|
2797 |
+ # with-statements. |
|
2798 |
+ # https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
|
2799 |
+ with contextlib.ExitStack() as stack: |
|
2800 |
+ monkeypatch = stack.enter_context(pytest.MonkeyPatch.context()) |
|
2801 |
+ stack.enter_context( |
|
2802 |
+ tests.isolated_vault_config( |
|
2803 |
+ monkeypatch=monkeypatch, |
|
2804 |
+ runner=runner, |
|
2805 |
+ vault_config=vault_config, |
|
2806 |
+ ) |
|
2807 |
+ ) |
|
2808 |
+ EDIT_ATTEMPTED = 'edit attempted!' # noqa: N806 |
|
2809 |
+ |
|
2810 |
+ def raiser(*_args: Any, **_kwargs: Any) -> NoReturn: |
|
2811 |
+ pytest.fail(EDIT_ATTEMPTED) |
|
2812 |
+ |
|
2813 |
+ monkeypatch.setattr(click, 'edit', raiser) |
|
2814 |
+ result_ = runner.invoke( |
|
2815 |
+ cli.derivepassphrase_vault, |
|
2816 |
+ ['--notes', '--', DUMMY_SERVICE], |
|
2817 |
+ catch_exceptions=False, |
|
2818 |
+ ) |
|
2819 |
+ result = tests.ReadableResult.parse(result_) |
|
2820 |
+ assert result.clean_exit( |
|
2821 |
+ output=DUMMY_RESULT_PASSPHRASE.decode('ascii') |
|
2822 |
+ ), 'expected clean exit' |
|
2823 |
+ assert result.stderr |
|
2824 |
+ assert notes.strip() in result.stderr |
|
2825 |
+ assert all( |
|
2826 |
+ is_warning_line(line) |
|
2827 |
+ for line in result.stderr.splitlines(True) |
|
2828 |
+ if line.startswith(f'{cli.PROG_NAME}: ') |
|
2829 |
+ ) |
|
2830 |
+ assert tests.warning_emitted( |
|
2831 |
+ 'Specifying --notes without --config is ineffective. ' |
|
2832 |
+ 'No notes will be edited.', |
|
2833 |
+ caplog.record_tuples, |
|
2834 |
+ ), 'expected known warning message in stderr' |
|
2835 |
+ with cli_helpers.config_filename(subsystem='vault').open( |
|
2836 |
+ encoding='UTF-8' |
|
2837 |
+ ) as infile: |
|
2838 |
+ config = json.load(infile) |
|
2839 |
+ assert config == vault_config |
|
2840 |
+ |
|
2766 | 2841 |
@Parametrize.CONFIG_EDITING_VIA_CONFIG_FLAG |
2767 | 2842 |
def test_224_store_config_good( |
2768 | 2843 |
self, |
2769 | 2844 |