Give each failure one error value (closes #113)
check / check (push) Failing after 3s

internal/cli's copies of vault.ErrSecretNotFound, ErrVaultNotFound,
ErrVersionNotFound and ErrSecretExists are removed; the commands wrap the
vault errors. Every error of secret.ReadPassphrase wraps
ErrPassphraseNotRead, so its callers no longer add those words.
ResolveGPGKeyFingerprint returns ErrGPGKeyNotFound for a key the keyring
lacks, recognised by gpg's status line. storeInKeychain returns
errNilDataBuffer. bip85's ErrPasswordTooShort and ErrEncodedTooShort go
with their unreachable checks. Tests that matched these errors' text use
errors.Is.

Model: opus-5-5
This commit is contained in:
2026-10-04 21:39:24 +00:00
parent 176095e3d1
commit a83743383e
19 changed files with 159 additions and 97 deletions
+14 -9
View File
@@ -45,15 +45,6 @@ func TestRejectedMoveWithinVaultLeavesStateUnchanged(t *testing.T) {
{`mv --force work:x ""`, workX, "", true, ontoItself},
// "work" is a vault name, so the destination is work:x.
{"mv --force work:x work", workX, "work", true, ontoItself},
{
"mv work:nosuch work:y", "work:nosuch", "work:y", false,
"secret 'nosuch' not found",
},
// Only an existing vault is used.
{
"mv --force nosuch:x nosuch:y", "nosuch:x", "nosuch:y", true,
"vault 'nosuch' does not exist",
},
}
for _, tt := range tests {
@@ -70,6 +61,20 @@ func TestRejectedMoveWithinVaultLeavesStateUnchanged(t *testing.T) {
})
}
// A missing secret, and a missing vault: only an existing vault is used.
for source, want := range map[string]error{
"work:nosuch": vault.ErrSecretNotFound,
"nosuch:x": vault.ErrVaultNotFound,
} {
t.Run("mv --force "+source+" work:y", func(t *testing.T) {
t.Parallel()
requireRejectedAndUnchanged(t, before, want, func(c *cli.Instance) error {
return c.MoveSecret(&cobra.Command{}, source, "work:y", true)
})
})
}
// Each of these spells "work" a second way. The spelling is not a valid
// vault name, so the move is not taken for a move between two vaults,
// which would delete the destination, here the source.