Document the modern editor interface
Marco Ricci

Marco Ricci commited on 2025-02-07 15:19:22
Zeige 5 geänderte Dateien mit 132 Einfügungen und 26 Löschungen.


Update the manpages to include the corrected and extended handling of
the `--notes` config option.  That is, document the
`--modern-editor-interface` and `--vault-legacy-editor-interface`
options, and the new warning messages about `--notes` requiring
`--config` and that a backup copy of the notes have been made.

Some minor adjustments to the vault(1) legacy editor interface warning
messages were made to ease inclusion in the manpage while making the
intent clear.  Additionally, derivepassphrase with the legacy interface
correctly fills in the old notes contents if any, instead of
unconditionally filling in the placeholder text.
... ...
@@ -9,7 +9,8 @@ derivepassphrase-vault – derive a passphrase using the vault derivation scheme
9 9
 <pre>
10 10
 <code><b>derivepassphrase vault</b> [--phrase | --key] [--length <var>n</var>] [--repeat <var>n</var>] [--lower <var>n</var>] [--upper <var>n</var>] [--number <var>n</var>] [--space <var>n</var>] [--dash <var>n</var>] [--symbol <var>n</var>] <var>SERVICE</var></code>
11 11
 <code><b>derivepassphrase vault</b> {--phrase | --key | … | --symbol <var>n</var>} … --config [--unset <var>setting</var> …] [--overwrite-existing | --merge-existing] [<var>SERVICE</var>]</code>
12
-<code><b>derivepassphrase vault</b> {--notes <var>SERVICE</var> | --delete <var>SERVICE</var> | --delete-globals | --clear}</code>
12
+<code><b>derivepassphrase vault</b> [--phrase | --key | … | --symbol <var>n</var>] … --config --notes [--unset <var>setting</var> …] [--overwrite-existing | --merge-existing] [--modern-editor-interface | --vault-legacy-editor-interface] <var>SERVICE</var></code>
13
+<code><b>derivepassphrase vault</b> {--delete <var>SERVICE</var> | --delete-globals | --clear}</code>
13 14
 <code><b>derivepassphrase vault</b> [--export-as {json | sh}] {--import <var>PATH</var> | --export <var>PATH</var>}</code>
14 15
 </pre>
15 16
 
... ...
@@ -30,7 +31,7 @@ In lieu of a master passphrase, a master SSH key can also be used if there is a
30 31
 
31 32
 The passphrase generation options can be divided into "passphrase source" options (`--phrase`, `--key`) and "passphrase constraint" options (all others).
32 33
 The passphrase source options are mutually exclusive --- you may only specify one of them --- while the passphrase constraint options may be combined in any way.
33
-The <var>SERVICE</var> is mandatory (see synopsis #1), unless the `--config` option is specified (see synopsis #2).
34
+The <var>SERVICE</var> is mandatory (see synopsis #1 and #3), unless the `--config` option is specified and the `--notes` option is not (see synopsis #2).
34 35
 All character constraints refer to ASCII printable characters only (space (`U+0020`) to tilde (`U+007E`), excluding the grave accent (`U+0060`)).
35 36
 
36 37
 <b>-p</b>, <b>-</b><b>-phrase</b>
... ...
@@ -88,17 +89,20 @@ All character constraints refer to ASCII printable characters only (space (`U+00
88 89
 ### Configuration
89 90
 
90 91
 The configuration options directly modify the stored settings: default settings, known services, and service-specific settings.
91
-They are mutually exclusive; you may only specify one of them.
92
-The <var>SERVICE</var> is mandatory for `--notes` and `--delete`, optional for `--config`, and forbidden for `--delete-globals` and `--clear` (see synopsis #2 and synopsis #3).
92
+The `--notes` option requires the `--config` option, and modifies its operation.
93
+All others are mutually exclusive; you may only specify one of them.
94
+The <var>SERVICE</var> is mandatory for `--notes` and `--delete`, optional for `--config`, and forbidden for `--delete-globals` and `--clear` (see synopses #2, #3 and #4).
93 95
 
94 96
 <b>-n</b>, <b>-</b><b>-notes</b>
95 97
 :   Spawn an editor to edit notes for <var>SERVICE</var>.
96 98
     Use the `VISUAL` or `EDITOR` environment variables to configure the spawned editor.
99
+    Must be used together with `--config` to have any effect.
97 100
 
98 101
 <b>-c</b>, <b>-</b><b>-config</b>
99 102
 :   Save the given settings for <var>SERVICE</var> (if given), or save the given settings as global default settings.
100 103
 
101
-    See the ["Passphrase generation"](#passphrase-generation) and ["Compatibility and extension options"](#compatibility-and-extension-options) sections for other options compatible with `--config`.
104
+    The `--notes` option is compatible with `--config`.
105
+    See the ["Passphrase generation"](#passphrase-generation) and ["Compatibility and extension options"](#compatibility-and-extension-options) sections for other compatible options.
102 106
 
103 107
     !!! danger
104 108
 
... ...
@@ -156,6 +160,20 @@ The compatibility and extension options modify the behavior to enable additional
156 160
 
157 161
     (vault(1) behaves as if `--export-as json` were always given.)
158 162
 
163
+<b>-</b><b>-modern-editor-interface</b> | <b>-</b><b>-vault-legacy-editor-interface</b>
164
+:   When editing notes, use a modern editor interface similar to <i>git</i>(1), or use the <i>vault</i>(1) legacy editing interface.
165
+
166
+    The modern editor interface supports aborting the edit (i.e., leaving the stored notes (if any) unchanged) by leaving the edited file empty, and automatically removes the editing instructions text (which it inserts into the file prior to editing).
167
+    This is similar to how version-control systems/source code management systems such as <i>git</i>(1), <i>hg</i>(1) or <i>svn</i>(1) use text editors for commit messages.
168
+
169
+    The <i>vault</i>(1) legacy editing interface uses the file contents directly, including any leftover editing instructions, and does not support aborting the edit.
170
+    Its use is not recommended, unless required for compatibility.
171
+
172
+    <b>derivepassphrase vault</b> will use different editing instructions texts to reflect the editing interface in use.
173
+    Additionally, for the legacy editing interface, a backup of the old notes contents will be stored in the configuration directory if the new notes differ from the old notes, to mitigate the risk of data loss because the edit cannot be aborted.
174
+
175
+    (vault(1) behaves as if `--vault-legacy-editor-interface` were always given.)
176
+
159 177
 ### Other Options
160 178
 
161 179
 <b>-</b><b>-debug</b>
... ...
@@ -216,6 +234,9 @@ This is a property specific to the key type, and sometimes the agent used:
216 234
 :   The stored configuration for <b>derivepassphrase vault</b>: the default passphrase generation settings, the known service names, and the service-specific settings.
217 235
     This file is <em>not</em> intended for the user to edit.
218 236
 
237
+`$DERIVEPASSPHRASE_PATH/old-notes.txt`
238
+:   A backup copy of the old notes from the last successful notes editing operation, using the <i>vault</i>(1) legacy editor interface.
239
+
219 240
 ## SECURITY
220 241
 
221 242
 !!! danger
... ...
@@ -428,6 +449,15 @@ The <b>derivepassphrase vault</b> utility exits 0 on success, and >0 if an error
428 449
     A configuration file has been renamed.
429 450
     <b>derivepassphrase vault</b> will attempt to rename the file itself (`Successfully migrated to %s.`), or complain if it cannot rename it (`Failed to migrate to %s: %s`).
430 451
 
452
+??? warning "`Specifying --notes without --config is ineffective.`"
453
+
454
+    (Exactly what it says.)
455
+
456
+??? warning "`A backup copy of the notes was saved to %s.`"
457
+
458
+    The <i>vault</i>(1) legacy editor interface is in use, which carries a high risk of accidentally losing or corrupting the old notes because a notes editing session cannot be aborted mid-editing.
459
+    To guard against such accidental data loss, a backup copy of the old notes was saved to the <b>derivepassphrase</b> configuration directory.
460
+
431 461
 ## COMPATIBILITY
432 462
 
433 463
 ### With other software
... ...
@@ -31,10 +31,16 @@
31 31
 .Op Ar SERVICE
32 32
 .
33 33
 .Nm derivepassphrase vault
34
-.Bro
35
-.Fl \-notes
34
+.Op Fl \-phrase | \-key | No .\|.\|. | Fl \-symbol Ar n
35
+.No .\|.\|.
36
+.Fl \-config \-notes
37
+.Op Fl \-unset Ar setting No .\|.\|.
38
+.Op Fl \-overwrite\-existing | Fl \-merge\-existing
39
+.Op Fl \-modern\-editor\-interface | Fl \-vault-legacy-editor-interface
36 40
 .Ar SERVICE
37
-|
41
+.
42
+.Nm derivepassphrase vault
43
+.Bro
38 44
 .Fl \-delete
39 45
 .Ar SERVICE
40 46
 |
... ...
@@ -104,9 +110,11 @@ specify one of them \(em while the passphrase constraint options may be
104 110
 combined in any way.
105 111
 The
106 112
 .Ar SERVICE
107
-is mandatory (see synopsis\~#1), unless the
113
+is mandatory (see synopsis\~#1 and #3), unless the
108 114
 .Fl \-config
109
-option is specified (see synopsis\~#2).
115
+option is specified and the
116
+.Fl \-notes
117
+option is not (see synopsis\~#2).
110 118
 All character constraints refer to ASCII printable characters only (space
111 119
 .Pq Li U+0020
112 120
 to tilde
... ...
@@ -234,7 +242,12 @@ The default is to not constain the occurrences in any manner.
234 242
 .
235 243
 The configuration options directly modify the stored settings: default
236 244
 settings, known services, and service-specific settings.
237
-They are mutually exclusive; you may only specify one of them.
245
+The
246
+.Fl \-notes
247
+option requires the
248
+.Fl \-config
249
+option, and modifies its operation.
250
+All others are mutually exclusive; you may only specify one of them.
238 251
 The
239 252
 .Ar SERVICE
240 253
 is mandatory for
... ...
@@ -247,7 +260,7 @@ and forbidden for
247 260
 .Fl \-delete\-globals
248 261
 and
249 262
 .Fl \-clear
250
-(see synopsis\~#2 and synopsis\~#3).
263
+(see synopses\~#2, #3 and #4).
251 264
 .
252 265
 .Bl -tag -width ".Fl p , \-phrase"
253 266
 .
... ...
@@ -259,6 +272,9 @@ Use the
259 272
 or
260 273
 .Ev EDITOR
261 274
 environment variables to configure the spawned editor.
275
+Must be used together with
276
+.Fl \-config
277
+to have any effect.
262 278
 .
263 279
 .It Fl c , \-config
264 280
 Save the given settings for
... ...
@@ -266,12 +282,15 @@ Save the given settings for
266 282
 (if given), or save the given settings as global default settings.
267 283
 .Pp
268 284
 .
285
+The
286
+.Fl \-notes
287
+option is compatible with
288
+.Fl \-config .
269 289
 See the
270 290
 .Sx Passphrase generation
271 291
 and
272 292
 .Sx Compatibility and extension options
273
-sections for other options compatible with
274
-.Fl \-config .
293
+sections for other compatible options.
275 294
 .Pp
276 295
 .
277 296
 .Bf -symbolic
... ...
@@ -402,6 +421,48 @@ behaves as if
402 421
 .Fl \-export\-as Li json
403 422
 were always given.)
404 423
 .
424
+.It Fl \-modern\-editor\-interface | Fl \-vault\-legacy\-editor\-interface
425
+When editing notes, use a modern editor interface similar to
426
+.Xr git 1 ,
427
+or use the
428
+.Xr vault 1
429
+legacy editing interface.
430
+.Pp
431
+.
432
+The modern editor interface supports aborting the edit
433
+.Pq i.e., leaving the stored notes (if any) unchanged
434
+by leaving the edited file empty, and automatically removes the editing
435
+instructions text (which it inserts into the file prior to editing).
436
+This is similar to how version-control systems/source code management systems
437
+such as
438
+.Xr git 1 ,
439
+.Xr hg 1
440
+or
441
+.Xr svn 1
442
+use text editors for commit messages.
443
+.Pp
444
+.
445
+The
446
+.Xr vault 1
447
+legacy edititng interface uses the file contents directly, including any
448
+leftover editing instructions, and does not support aborting the edit.
449
+Its use is not recommended, unless required for compatibility.
450
+.Pp
451
+.
452
+.Nm derivepassphrase vault
453
+will use different editing instructions texts to reflect the editing
454
+interface in use.
455
+Additionally, for the legacy editing interface, a backup of the old notes
456
+contents will be stored in the configuration directory if the new notes differ
457
+from the old notes, to mitigate the risk of data loss because the edit cannot
458
+be aborted.
459
+.Pp
460
+.
461
+.Xr ( vault 1
462
+behaves as if
463
+.Fl \-vault\-legacy\-editor\-interface
464
+were always given.)
465
+.
405 466
 .El
406 467
 .
407 468
 .Ss Other options
... ...
@@ -548,6 +609,12 @@ This file is
548 609
 .Em not
549 610
 intended for the user to edit.
550 611
 .
612
+.It Ev $DERIVEPASSPHRASE_PATH Ns Pa /old-notes.txt
613
+A backup copy of the old notes from the last successful notes editing
614
+operation, using the
615
+.Xr vault 1
616
+legacy editor interface.
617
+.
551 618
 .El
552 619
 .
553 620
 .Sh SECURITY
... ...
@@ -871,6 +938,20 @@ will attempt to rename the file itself
871 938
 or complain if it cannot rename it
872 939
 .Pq Qq Li Failed to migrate to %s: %s .
873 940
 .
941
+.It Specifying \-\-notes without \-\-config is ineffective.
942
+(Exactly what it says.)
943
+.
944
+.It A backup copy of the notes was saved to %s.
945
+The
946
+.Xr vault 1
947
+legacy editor interface is in use, which carries a high risk of
948
+accidentally losing or corrupting the old notes because a notes editing
949
+session cannot be aborted mid-editing.
950
+To guard against such accidental data loss, a backup copy of the old
951
+notes was saved to the
952
+.Nm derivepassphrase
953
+configuration directory.
954
+.
874 955
 .El
875 956
 .
876 957
 .Sh COMPATIBILITY
... ...
@@ -828,9 +828,8 @@ class Label(enum.Enum):
828 828
     )
829 829
     """"""
830 830
     DERIVEPASSPHRASE_VAULT_NOTES_LEGACY_INSTRUCTION_TEXT = commented(
831
-        "This instruction text is shown above the user's old stored notes "
832
-        'for this service, if any, if the vault(1)-compatible '
833
-        '"legacy" editor interface is used.  '
831
+        'This instruction text is shown if the vault(1)-compatible '
832
+        '"legacy" editor interface is used and no previous notes exist.  '
834 833
         'The interface does not support commentary in the notes, '
835 834
         'so we fill this with obvious placeholder text instead.  '
836 835
         '(Please replace this with what *your* language/culture would '
... ...
@@ -1820,10 +1819,10 @@ class WarnMsgTemplate(enum.Enum):
1820 1819
         '',
1821 1820
     )(
1822 1821
         'Warning message',
1823
-        'Using the vault(1)-compatible legacy editor interface, '
1824
-        'which does not allow aborting mid-edit.  '
1825
-        'A backup copy of the old notes was saved to {filename!r} '
1826
-        'to guard against editing mistakes.',
1822
+        'A backup copy of the old notes was saved to {filename!r}.  '
1823
+        'This is a safeguard against editing mistakes, because the '
1824
+        'vault(1)-compatible legacy editor interface does not allow '
1825
+        'aborting mid-edit, and because the notes were actually changed.',
1827 1826
         flags='python-brace-format',
1828 1827
     )
1829 1828
     PASSPHRASE_NOT_NORMALIZED = commented(
... ...
@@ -1423,7 +1423,7 @@ def derivepassphrase_vault(  # noqa: C901,PLR0912,PLR0913,PLR0914,PLR0915
1423 1423
                         old_notes_value,
1424 1424
                     ])
1425 1425
                 else:
1426
-                    text = str(notes_legacy_instructions)
1426
+                    text = old_notes_value or str(notes_legacy_instructions)
1427 1427
                 notes_value = click.edit(text=text, require_save=False)
1428 1428
                 assert notes_value is not None
1429 1429
                 if (
... ...
@@ -2543,8 +2543,6 @@ class TestCLI:
2543 2543
             assert result.clean_exit(), 'expected clean exit'
2544 2544
             assert all(map(is_warning_line, result.stderr.splitlines(True)))
2545 2545
             assert modern_editor_interface or tests.warning_emitted(
2546
-                'Using the vault(1)-compatible legacy editor interface, '
2547
-                'which does not allow aborting mid-edit.  '
2548 2546
                 'A backup copy of the old notes was saved',
2549 2547
                 caplog.record_tuples,
2550 2548
             ), 'expected known warning message in stderr'
... ...
@@ -2737,8 +2735,6 @@ class TestCLI:
2737 2735
                 map(is_warning_line, result.stderr.splitlines(True))
2738 2736
             )
2739 2737
             assert not caplog.record_tuples or tests.warning_emitted(
2740
-                'Using the vault(1)-compatible legacy editor interface, '
2741
-                'which does not allow aborting mid-edit.  '
2742 2738
                 'A backup copy of the old notes was saved',
2743 2739
                 caplog.record_tuples,
2744 2740
             ), 'expected known warning message in stderr'
2745 2741