gopasspw--gopass
114 行
3.8 KiB
Go
114 行
3.8 KiB
Go
package exit
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"text/tabwriter"
|
|
|
|
"github.com/gopasspw/gopass/pkg/debug"
|
|
"github.com/urfave/cli/v3"
|
|
)
|
|
|
|
// Exit code constants. Values are fixed and must never be re-ordered or
|
|
// renumbered — callers and scripts depend on their stability.
|
|
const (
|
|
// OK means no error (status code 0).
|
|
OK = 0
|
|
// Unknown is used if we can't determine the exact exit cause.
|
|
Unknown = 1
|
|
// Usage is used if there was some kind of invocation error.
|
|
Usage = 2
|
|
// Aborted is used if the user willingly aborted an action.
|
|
Aborted = 3
|
|
// Unsupported is used if an operation is not supported by gopass.
|
|
Unsupported = 4
|
|
// AlreadyInitialized is used if someone is trying to initialize
|
|
// an already initialized store.
|
|
AlreadyInitialized = 5
|
|
// NotInitialized is used if someone is trying to use an uninitialized
|
|
// store.
|
|
NotInitialized = 6
|
|
// Git is used if any git errors are encountered.
|
|
Git = 7
|
|
// Mount is used if a substore mount operation fails.
|
|
Mount = 8
|
|
// NoName is used when no name was provided for a named entry.
|
|
NoName = 9
|
|
// NotFound is used if a requested secret is not found.
|
|
NotFound = 10
|
|
// Decrypt is used when reading/decrypting a secret failed.
|
|
Decrypt = 11
|
|
// Encrypt is used when writing/encrypting of a secret fails.
|
|
Encrypt = 12
|
|
// List is used when listing the store content fails.
|
|
List = 13
|
|
// Audit is used when audit reports possible issues.
|
|
Audit = 14
|
|
// Fsck is used when the integrity check fails.
|
|
Fsck = 15
|
|
// Config is used when config errors occur.
|
|
Config = 16
|
|
// Recipients is used when a recipient operation fails.
|
|
Recipients = 17
|
|
// IO is used for misc. I/O errors.
|
|
IO = 18
|
|
// GPG is used for misc. gpg errors.
|
|
GPG = 19
|
|
// Hook is used for Hook failures.
|
|
Hook = 20
|
|
// Doctor is used when the doctor command finds failing checks.
|
|
Doctor = 21
|
|
)
|
|
|
|
// exitCodeDescriptions lists every defined exit code together with a short
|
|
// description suitable for human consumption.
|
|
var exitCodeDescriptions = []struct {
|
|
Code int
|
|
Name string
|
|
Desc string
|
|
}{
|
|
{OK, "OK", "Success — no error"},
|
|
{Unknown, "Unknown", "Unclassified or unexpected error"},
|
|
{Usage, "Usage", "Bad invocation: wrong arguments or flags"},
|
|
{Aborted, "Aborted", "User deliberately aborted the operation"},
|
|
{Unsupported, "Unsupported", "Operation is not supported"},
|
|
{AlreadyInitialized, "AlreadyInitialized", "Store is already initialized"},
|
|
{NotInitialized, "NotInitialized", "Store is not initialized"},
|
|
{Git, "Git", "Git operation failed"},
|
|
{Mount, "Mount", "Substore mount operation failed"},
|
|
{NoName, "NoName", "No name provided for the entry"},
|
|
{NotFound, "NotFound", "Requested secret not found"},
|
|
{Decrypt, "Decrypt", "Reading or decrypting a secret failed"},
|
|
{Encrypt, "Encrypt", "Writing or encrypting a secret failed"},
|
|
{List, "List", "Listing store contents failed"},
|
|
{Audit, "Audit", "Audit found one or more issues"},
|
|
{Fsck, "Fsck", "Integrity check found errors"},
|
|
{Config, "Config", "Configuration error (reserved)"},
|
|
{Recipients, "Recipients", "Recipient operation failed"},
|
|
{IO, "IO", "Miscellaneous I/O error"},
|
|
{GPG, "GPG", "Miscellaneous GPG error (reserved)"},
|
|
{Hook, "Hook", "Hook execution failed"},
|
|
{Doctor, "Doctor", "Doctor found one or more failing checks"},
|
|
}
|
|
|
|
// PrintExitCodes writes a human-readable table of all defined exit codes to w.
|
|
func PrintExitCodes(w io.Writer) {
|
|
tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0)
|
|
fmt.Fprintln(tw, "Code\tName\tDescription")
|
|
fmt.Fprintln(tw, "----\t----\t-----------")
|
|
for _, e := range exitCodeDescriptions {
|
|
fmt.Fprintf(tw, "%d\t%s\t%s\n", e.Code, e.Name, e.Desc)
|
|
}
|
|
_ = tw.Flush()
|
|
}
|
|
|
|
// Error returns a user friendly CLI error.
|
|
func Error(exitCode int, err error, format string, args ...any) error {
|
|
msg := fmt.Sprintf(format, args...)
|
|
if err != nil {
|
|
debug.LogN(1, "%s - stacktrace: %+v", msg, err)
|
|
}
|
|
|
|
return cli.Exit(msg, exitCode)
|
|
}
|