Compare commits

..
1 Commits
Author SHA1 Message Date
sneak a83743383e 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
2026-10-04 21:39:24 +00:00
3 changed files with 11 additions and 25 deletions
+1 -3
View File
@@ -23,9 +23,7 @@ https://git.eeqj.de/sneak/secret/milestone/12
keeps its own copies of `vault.ErrSecretNotFound`, `ErrVaultNotFound`, keeps its own copies of `vault.ErrSecretNotFound`, `ErrVaultNotFound`,
`ErrVersionNotFound` and `ErrSecretExists`: `secret mv`, `rm`, `decrypt`, `ErrVersionNotFound` and `ErrSecretExists`: `secret mv`, `rm`, `decrypt`,
`vault import`, `vault remove` and `version list`, `promote` and `rm` wrap `vault import`, `vault remove` and `version list`, `promote` and `rm` wrap
the `vault` errors. `errUnsupportedUnlockerType` is removed: `secret the `vault` errors. Messages are unchanged, except that `secret decrypt`
unlocker add` gives `errInvalidUnlockerType` for an unknown type, whichever
check rejects it. Messages are unchanged, except that `secret decrypt`
of a missing secret says "not found", as `secret get` does, not "does not of a missing secret says "not found", as `secret get` does, not "does not
exist". Every error of `secret.ReadPassphrase` wraps exist". Every error of `secret.ReadPassphrase` wraps
`secret.ErrPassphraseNotRead`, which supplies the words "failed to read `secret.ErrPassphraseNotRead`, which supplies the words "failed to read
+7 -20
View File
@@ -61,29 +61,16 @@ func TestRejectedMoveWithinVaultLeavesStateUnchanged(t *testing.T) {
}) })
} }
missing := []struct { // A missing secret, and a missing vault: only an existing vault is used.
command string for source, want := range map[string]error{
source, dest string "work:nosuch": vault.ErrSecretNotFound,
force bool "nosuch:x": vault.ErrVaultNotFound,
want error
} { } {
{ t.Run("mv --force "+source+" work:y", func(t *testing.T) {
"mv work:nosuch work:y", "work:nosuch", "work:y", false,
vault.ErrSecretNotFound,
},
// Only an existing vault is used.
{
"mv --force nosuch:x nosuch:y", "nosuch:x", "nosuch:y", true,
vault.ErrVaultNotFound,
},
}
for _, tt := range missing {
t.Run(tt.command, func(t *testing.T) {
t.Parallel() t.Parallel()
requireRejectedAndUnchanged(t, before, tt.want, func(c *cli.Instance) error { requireRejectedAndUnchanged(t, before, want, func(c *cli.Instance) error {
return c.MoveSecret(&cobra.Command{}, tt.source, tt.dest, tt.force) return c.MoveSecret(&cobra.Command{}, source, "work:y", true)
}) })
}) })
} }
+2 -1
View File
@@ -47,6 +47,7 @@ var (
// composes "GPG key <id> is already added as an unlocker". // composes "GPG key <id> is already added as an unlocker".
errGPGKeyAlreadyUnlocker = errors.New( errGPGKeyAlreadyUnlocker = errors.New(
"is already added as an unlocker") "is already added as an unlocker")
errUnsupportedUnlockerType = errors.New("unsupported unlocker type")
) )
// UnlockerInfo represents unlocker information for display // UnlockerInfo represents unlocker information for display
@@ -438,7 +439,7 @@ func (cli *Instance) UnlockersAdd(unlockerType string, cmd *cobra.Command) error
} }
return fmt.Errorf("%w: %s (supported: %s)", return fmt.Errorf("%w: %s (supported: %s)",
errInvalidUnlockerType, unlockerType, supportedTypes) errUnsupportedUnlockerType, unlockerType, supportedTypes)
} }
} }