mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-09-05 16:47:22 -04:00
Implement utility function for formatting and printing errors
This commit is contained in:
@@ -13,8 +13,7 @@ import (
|
||||
func loadConfig() *ini.File {
|
||||
cfg, err := ini.Load(ConfigPath)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to load libmutton.ini:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorRead)
|
||||
PrintError("Failed to load libmutton.ini: "+err.Error(), ErrorRead, true)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
@@ -38,14 +37,12 @@ func ParseConfig(valuesRequested [][2]string, missingValueError string) ([]strin
|
||||
switch missingValueError {
|
||||
case "":
|
||||
err = fmt.Errorf("Failed to find value for key \"%s\" in section \"[%s]\" in libmutton.ini", pair[1], pair[0])
|
||||
fmt.Println(err.Error())
|
||||
case "0":
|
||||
Exit(0) // hard (expected) exit for CLI; GUI/TUI continue silently
|
||||
default:
|
||||
err = fmt.Errorf("%s", missingValueError)
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
Exit(ErrorRead) // hard exit for CLI; GUI/TUI continue silently
|
||||
PrintError(err.Error(), ErrorRead, false)
|
||||
// if interactive (soft exit), return nil and the error to be handled by the caller
|
||||
return nil, err
|
||||
}
|
||||
@@ -63,8 +60,7 @@ func GenDeviceIDList(errorOnFail bool) *[]fs.DirEntry {
|
||||
deviceIDList, err := os.ReadDir(ConfigDir + PathSeparator + "devices")
|
||||
if err != nil {
|
||||
if errorOnFail {
|
||||
fmt.Println(AnsiError+"Failed to read the devices directory:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorRead)
|
||||
PrintError("Failed to read the devices directory: "+err.Error(), ErrorRead, true)
|
||||
} else {
|
||||
return nil // a nil return value indicates that the devices directory could not be read/does not exist
|
||||
}
|
||||
@@ -113,7 +109,6 @@ func WriteConfig(valuesToWrite [][3]string, keysToPrune [][2]string, append bool
|
||||
// save to libmutton.ini
|
||||
err := cfg.SaveTo(ConfigPath)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to save libmutton.ini:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorWrite)
|
||||
PrintError("Failed to save libmutton.ini: "+err.Error(), ErrorWrite, true)
|
||||
}
|
||||
}
|
||||
|
||||
+5
-10
@@ -23,8 +23,7 @@ func CopyArgument(targetLocation string, field int) {
|
||||
|
||||
// ensure field is not empty
|
||||
if decryptedEntry[field] == "" {
|
||||
fmt.Println(AnsiError + "Field is empty" + AnsiReset)
|
||||
os.Exit(ErrorTargetNotFound)
|
||||
PrintError("Field is empty", ErrorTargetNotFound, true)
|
||||
}
|
||||
|
||||
if field != 2 {
|
||||
@@ -50,8 +49,7 @@ func CopyArgument(targetLocation string, field int) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fmt.Println(AnsiError + "Field does not exist in entry" + AnsiReset)
|
||||
os.Exit(ErrorTargetNotFound)
|
||||
PrintError("Field does not exist in entry", ErrorTargetNotFound, true)
|
||||
}
|
||||
|
||||
// copy field to clipboard, launch clipboard clearing process
|
||||
@@ -79,8 +77,7 @@ func clipClearProcess(assignedContents string) {
|
||||
clearClipboard := func() {
|
||||
err := cmdClear.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Failed to clear clipboard", ErrorClipboard, true)
|
||||
}
|
||||
Exit(0)
|
||||
}
|
||||
@@ -96,8 +93,7 @@ func clipClearProcess(assignedContents string) {
|
||||
|
||||
newContents, err := cmdPaste.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Failed to read clipboard contents", ErrorClipboard, true)
|
||||
}
|
||||
|
||||
if assignedContents == strings.TrimRight(string(newContents), "\r\n") {
|
||||
@@ -117,8 +113,7 @@ func GenTOTP(secret string, time time.Time, forSteam bool) string {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Error generating TOTP code" + AnsiReset)
|
||||
os.Exit(ErrorOther)
|
||||
PrintError("Error generating TOTP code", ErrorOther, true)
|
||||
}
|
||||
|
||||
return totpToken
|
||||
|
||||
+1
-4
@@ -3,8 +3,6 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
@@ -14,8 +12,7 @@ func copyString(continuous bool, copySubject string) {
|
||||
WriteToStdin(cmd, copySubject)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Failed to copy to clipboard: "+err.Error(), ErrorClipboard, true)
|
||||
}
|
||||
|
||||
if !continuous {
|
||||
|
||||
+1
-4
@@ -3,8 +3,6 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
@@ -14,8 +12,7 @@ func copyString(continuous bool, copySubject string) {
|
||||
WriteToStdin(cmd, copySubject)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Failed to copy to clipboard: "+err.Error(), ErrorClipboard, true)
|
||||
}
|
||||
|
||||
if !continuous {
|
||||
|
||||
+2
-5
@@ -3,7 +3,6 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
@@ -19,15 +18,13 @@ func copyString(continuous bool, copySubject string) {
|
||||
} else if _, envSet = os.LookupEnv("DISPLAY"); envSet {
|
||||
cmdCopy = exec.Command("xclip", "-sel", "c", "-t", "text/plain")
|
||||
} else {
|
||||
fmt.Println(AnsiError + "Clipboard platform could not be determined - Note that the clipboard does not function in a raw TTY" + AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Clipboard platform could not be determined", ErrorClipboard, true)
|
||||
}
|
||||
|
||||
WriteToStdin(cmdCopy, copySubject)
|
||||
err := cmdCopy.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Failed to copy to clipboard: "+err.Error(), ErrorClipboard, true)
|
||||
}
|
||||
|
||||
if !continuous {
|
||||
|
||||
+1
-3
@@ -4,7 +4,6 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
@@ -14,8 +13,7 @@ func copyString(continuous bool, copySubject string) {
|
||||
cmd := exec.Command("powershell.exe", "-c", fmt.Sprintf("echo '%s' | Set-Clipboard", strings.ReplaceAll(copySubject, "'", "''")))
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Failed to copy to clipboard: "+err.Error(), ErrorClipboard, true)
|
||||
}
|
||||
|
||||
if !continuous {
|
||||
|
||||
+2
-6
@@ -1,8 +1,6 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
@@ -18,8 +16,7 @@ func DecryptGPG(targetLocation string) []string {
|
||||
enableVirtualTerminalProcessing()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to decrypt \"" + targetLocation + "\" - Ensure it is a valid GPG-encrypted file and that you entered your passphrase correctly" + AnsiReset)
|
||||
os.Exit(ErrorDecryption)
|
||||
PrintError("Failed to decrypt \""+targetLocation+"\" - Ensure it is a valid GPG-encrypted file and that you entered your passphrase correctly", ErrorDecryption, true)
|
||||
}
|
||||
|
||||
return strings.Split(string(output), "\n")
|
||||
@@ -32,8 +29,7 @@ func EncryptGPG(input []string) []byte {
|
||||
WriteToStdin(cmd, strings.Join(input, "\n"))
|
||||
encryptedBytes, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to encrypt data - Ensure that your GPG key is valid and that you have a valid GPG ID set in libmutton.ini" + AnsiReset)
|
||||
os.Exit(ErrorEncryption)
|
||||
PrintError("Failed to encrypt data - Ensure that you have a valid GPG ID set in libmutton.ini", ErrorEncryption, true)
|
||||
}
|
||||
return encryptedBytes
|
||||
}
|
||||
|
||||
+4
-9
@@ -1,7 +1,6 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
@@ -45,8 +44,7 @@ func GpgKeyGen() string {
|
||||
cmd.Stdin = os.Stdin
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to generate GPG key:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorOther)
|
||||
PrintError("Failed to generate GPG key: "+err.Error(), ErrorOther, true)
|
||||
}
|
||||
|
||||
return "libmutton-" + unixTime + " (gpg-libmutton) <github.com/rwinkhart/libmutton>"
|
||||
@@ -58,8 +56,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
||||
// create EntryRoot
|
||||
err := os.MkdirAll(EntryRoot, 0700)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to create \""+EntryRoot+"\":", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorWrite)
|
||||
PrintError("Failed to create \""+EntryRoot+"\": "+err.Error(), ErrorWrite, true)
|
||||
}
|
||||
|
||||
// get old device ID before its potential removal
|
||||
@@ -77,8 +74,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
||||
if isAccessible {
|
||||
err = os.RemoveAll(ConfigDir)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to remove existing config directory:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorWrite)
|
||||
PrintError("Failed to remove existing config directory: "+err.Error(), ErrorWrite, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,8 +82,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
||||
// create config directory w/devices subdirectory
|
||||
err = os.MkdirAll(ConfigDir+PathSeparator+"devices", 0700)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to create \""+ConfigDir+"\":", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorWrite)
|
||||
PrintError("Failed to create \""+ConfigDir+"\": "+err.Error(), ErrorWrite, true)
|
||||
}
|
||||
|
||||
return oldDeviceID
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
@@ -16,8 +15,7 @@ func LaunchClipClearProcess(copySubject string) {
|
||||
WriteToStdin(cmd, copySubject)
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?" + AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?", ErrorClipboard, true)
|
||||
}
|
||||
os.Exit(0) // use os.Exit directly since this version of this function is only meant for non-interactive CLI implementations
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
@@ -17,8 +16,7 @@ func LaunchClipClearProcess(copySubject string, isWayland bool) {
|
||||
WriteToStdin(cmd, copySubject)
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?" + AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
PrintError("Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?", ErrorClipboard, true)
|
||||
}
|
||||
os.Exit(0) // use os.Exit directly since this version of this function is only meant for non-interactive CLI implementations
|
||||
}
|
||||
|
||||
+19
-12
@@ -18,21 +18,18 @@ func TargetIsFile(targetLocation string, errorOnFail bool, failCondition uint8)
|
||||
targetInfo, err := os.Stat(targetLocation)
|
||||
if err != nil {
|
||||
if errorOnFail {
|
||||
fmt.Println(AnsiError + "Failed to access \"" + targetLocation + "\" - Ensure it exists and has the correct permissions" + AnsiReset)
|
||||
os.Exit(ErrorTargetNotFound)
|
||||
PrintError("Failed to access \""+targetLocation+"\" - Ensure it exists and has the correct permissions", ErrorTargetNotFound, true)
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
if targetInfo.IsDir() {
|
||||
if errorOnFail && failCondition == 2 {
|
||||
fmt.Println(AnsiError + "\"" + targetLocation + "\" is a directory" + AnsiReset)
|
||||
os.Exit(ErrorTargetWrongType)
|
||||
PrintError("\""+targetLocation+"\" is a directory", ErrorTargetWrongType, true)
|
||||
}
|
||||
return false, true
|
||||
} else {
|
||||
if errorOnFail && failCondition == 1 {
|
||||
fmt.Println(AnsiError + "\"" + targetLocation + "\" is a file" + AnsiReset)
|
||||
os.Exit(ErrorTargetWrongType)
|
||||
PrintError("\""+targetLocation+"\" is a file", ErrorTargetWrongType, true)
|
||||
}
|
||||
return true, true
|
||||
}
|
||||
@@ -43,8 +40,7 @@ func WriteEntry(targetLocation string, entryData []string) {
|
||||
encryptedBytes := EncryptGPG(entryData)
|
||||
err := os.WriteFile(targetLocation, encryptedBytes, 0600)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to write to file:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorWrite)
|
||||
PrintError("Failed to write to file: "+err.Error(), ErrorWrite, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,8 +49,7 @@ func WriteEntry(targetLocation string, entryData []string) {
|
||||
func WriteToStdin(cmd *exec.Cmd, input string) {
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to access stdin for system command:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorOther)
|
||||
PrintError("Failed to access stdin for system command: "+err.Error(), ErrorOther, true)
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -69,8 +64,7 @@ func WriteToStdin(cmd *exec.Cmd, input string) {
|
||||
func CreateTempFile() *os.File {
|
||||
tempFile, err := os.CreateTemp("", "*.markdown")
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to create temporary file:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorWrite)
|
||||
PrintError("Failed to create temporary file: "+err.Error(), ErrorWrite, true)
|
||||
}
|
||||
return tempFile
|
||||
}
|
||||
@@ -182,3 +176,16 @@ func EntryIsNotEmpty(entryData []string) bool {
|
||||
func ExpandPathWithHome(path string) string {
|
||||
return strings.Replace(path, "~", Home, 1)
|
||||
}
|
||||
|
||||
// PrintError prints an error message in the standard libmutton format and exits with the specified exit code.
|
||||
// Requires: message (the error message to print),
|
||||
// exitCode (the exit code to use),
|
||||
// forceHardExit (if true, exit immediately; if false, allow soft exit for interactive clients).
|
||||
func PrintError(message string, exitCode int, forceHardExit bool) {
|
||||
fmt.Println(AnsiError + message + AnsiReset)
|
||||
if forceHardExit {
|
||||
os.Exit(exitCode)
|
||||
} else {
|
||||
Exit(exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user