mirror of
https://github.com/rwinkhart/MUTN.git
synced 2026-08-28 04:46:41 -04:00
Port to latest libmutton development version; address JetBrains warnings
This commit is contained in:
@@ -30,7 +30,7 @@ After installing, please review the [usage guide](https://github.com/rwinkhart/M
|
||||
- [ ] Re-implement init menu
|
||||
- [ ] Implement tweak menu
|
||||
### Release v0.4.0
|
||||
- [ ] Switch to fully-compliant Markdown (do not preserve new lines)
|
||||
- [ ] Switch to fully compliant Markdown (do not preserve new lines)
|
||||
- [ ] Evaluate defaulting to building w/Bean over Glamour
|
||||
- [ ] Verify having Glamour in go.mod does not impact binary size/speed (drop it if it does)
|
||||
### Release v0.5.0
|
||||
|
||||
@@ -6,7 +6,7 @@ require (
|
||||
github.com/Trojan2021/BEAN v0.0.0-20241210230804-8f294833b514
|
||||
github.com/charmbracelet/glamour v0.7.0
|
||||
github.com/rwinkhart/go-boilerplate v0.0.0-20250529185306-e2e64d7fa43b
|
||||
github.com/rwinkhart/libmutton v0.3.2-0.20250529233550-74b8261bc88f
|
||||
github.com/rwinkhart/libmutton v0.3.2-0.20250530020557-a1c47b06a13e
|
||||
golang.org/x/term v0.32.0
|
||||
)
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@ github.com/rwinkhart/go-boilerplate v0.0.0-20250529185306-e2e64d7fa43b h1:ENgsUl
|
||||
github.com/rwinkhart/go-boilerplate v0.0.0-20250529185306-e2e64d7fa43b/go.mod h1:cnzIF45I0FCOvE4YIB+26pLCUx2kWyY2llKYZruNaRY=
|
||||
github.com/rwinkhart/go-winio-easy-pipe-handles v0.0.0-20250407031321-96994a0e8410 h1:NhHwFM3Pgm6zRUfFKvi0p5ndjfFbVWsRwmmhyFlG4PE=
|
||||
github.com/rwinkhart/go-winio-easy-pipe-handles v0.0.0-20250407031321-96994a0e8410/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/rwinkhart/libmutton v0.3.2-0.20250529233550-74b8261bc88f h1:HL3z/oTAqssmILfA3Z0IAscK1sbxFp8/g9GnhHSNLSY=
|
||||
github.com/rwinkhart/libmutton v0.3.2-0.20250529233550-74b8261bc88f/go.mod h1:uIz4AJcXW7ZHvvoPlLNWQofTBIbFa1UJ2JI6O+FSQ60=
|
||||
github.com/rwinkhart/libmutton v0.3.2-0.20250530020557-a1c47b06a13e h1:b+4AzdZj5gEbIg8riqP5W4Y5LG7tIZTbiV69af846jI=
|
||||
github.com/rwinkhart/libmutton v0.3.2-0.20250530020557-a1c47b06a13e/go.mod h1:uIz4AJcXW7ZHvvoPlLNWQofTBIbFa1UJ2JI6O+FSQ60=
|
||||
github.com/rwinkhart/peercred-mini v0.1.0 h1:TiS6u8cEWzW55S9X4iVpU72Iuy/NG6rMUJMtUEVEFLw=
|
||||
github.com/rwinkhart/peercred-mini v0.1.0/go.mod h1:+x4Mxc2veE+YePSOpcUasjimh7n799c1KraLuQwHR20=
|
||||
github.com/rwinkhart/rcw v0.2.0 h1:/rFgJ+20OSThipKAX5KPwW2xbPpgh1zl49THmEkkPis=
|
||||
|
||||
@@ -44,7 +44,10 @@ func main() {
|
||||
case "show", "-s":
|
||||
cli.EntryReaderDecrypt(targetLocation, false)
|
||||
case "copy":
|
||||
core.CopyArgument(targetLocation, 0)
|
||||
err := core.CopyArgument(targetLocation, 0)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to copy passphrase to clipboard: "+err.Error(), global.ErrorClipboard, true)
|
||||
}
|
||||
case "edit":
|
||||
cli.EditEntryField(targetLocation, true, 0)
|
||||
case "gen":
|
||||
@@ -52,7 +55,10 @@ func main() {
|
||||
case "add":
|
||||
cli.AddEntry(targetLocation, true, 0)
|
||||
case "shear":
|
||||
syncclient.ShearRemoteFromClient(args[1], false) // pass the incomplete path as the server and all clients (reading from the deletions directory) will have a different home directory
|
||||
err := syncclient.ShearRemoteFromClient(args[1], false) // pass the incomplete path as the server and all clients (reading from the deletions directory) will have a different home directory
|
||||
if err != nil {
|
||||
back.PrintError("Failed to shear target: "+err.Error(), back.ErrorWrite, true)
|
||||
}
|
||||
default:
|
||||
cli.HelpMain()
|
||||
}
|
||||
@@ -88,7 +94,10 @@ func main() {
|
||||
default:
|
||||
cli.HelpCopy()
|
||||
}
|
||||
core.CopyArgument(targetLocation, field)
|
||||
err := core.CopyArgument(targetLocation, field)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to copy field to clipboard: "+err.Error(), global.ErrorClipboard, true)
|
||||
}
|
||||
case "edit":
|
||||
var field int // indicates which (numbered) field to edit
|
||||
switch args[3] {
|
||||
@@ -151,7 +160,10 @@ func main() {
|
||||
case "note", "-n":
|
||||
cli.AddEntry(targetLocation, true, 2)
|
||||
case "folder", "-f":
|
||||
syncclient.AddFolderRemoteFromClient(args[1], false) // pass the incomplete path as the server will have a different home directory
|
||||
err := syncclient.AddFolderRemoteFromClient(args[1], false) // pass the incomplete path as the server will have a different home directory
|
||||
if err != nil {
|
||||
back.PrintError("Failed to add folder: "+err.Error(), back.ErrorWrite, true)
|
||||
}
|
||||
default:
|
||||
cli.HelpAdd()
|
||||
}
|
||||
@@ -164,13 +176,18 @@ func main() {
|
||||
} else {
|
||||
switch args[1] {
|
||||
case "clipclear":
|
||||
core.ClipClearArgument()
|
||||
err := core.ClipClearArgument()
|
||||
if err != nil {
|
||||
back.PrintError("Failure occurred in clipboard clearing process: "+err.Error(), global.ErrorClipboard, true)
|
||||
}
|
||||
case "startrcwd":
|
||||
crypt.RCWDArgument()
|
||||
case "sync":
|
||||
syncclient.RunJob(true, false)
|
||||
_, err := syncclient.RunJob(true, false)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to sync entries: "+err.Error(), global.ErrorSyncProcess, true)
|
||||
}
|
||||
case "init":
|
||||
const fallbackEditor = "vi" // TODO "edit" for Windows
|
||||
var rcwPass []byte
|
||||
for { // get master passphrase
|
||||
rcwPass = front.InputHidden("Master passphrase:")
|
||||
@@ -181,7 +198,7 @@ func main() {
|
||||
break
|
||||
}
|
||||
err := core.LibmuttonInit(front.Input,
|
||||
[][3]string{{"MUTN", "textEditor", cmp.Or(front.Input("Text editor (leave blank for $EDITOR, falls back to \""+fallbackEditor+"\"):"), os.Getenv("EDITOR"), fallbackEditor)}},
|
||||
[][3]string{{"MUTN", "textEditor", cmp.Or(front.Input("Text editor (leave blank for $EDITOR, falls back to \""+cli.FallbackEditor+"\"):"), os.Getenv("EDITOR"), cli.FallbackEditor)}},
|
||||
rcwPass, false)
|
||||
if err != nil {
|
||||
back.PrintError("Initialization failed: "+err.Error(), 0, true)
|
||||
|
||||
+5
-1
@@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"github.com/rwinkhart/go-boilerplate/back"
|
||||
"github.com/rwinkhart/go-boilerplate/front"
|
||||
"github.com/rwinkhart/libmutton/core"
|
||||
)
|
||||
@@ -9,7 +10,10 @@ import (
|
||||
// Requires: entryType (0 = standard password entry, 1 = auto-generated password entry, 2 = note-only entry).
|
||||
func AddEntry(targetLocation string, hideSecrets bool, entryType uint8) {
|
||||
// ensure targetLocation is valid
|
||||
core.EntryAddPrecheck(targetLocation)
|
||||
_, err := core.EntryAddPrecheck(targetLocation)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to add entry: "+err.Error(), back.ErrorWrite, true)
|
||||
}
|
||||
|
||||
var unencryptedEntry []string
|
||||
|
||||
|
||||
+12
-3
@@ -17,7 +17,10 @@ import (
|
||||
func RenameCli(oldLocationIncomplete string) {
|
||||
// prompt user for new location and rename
|
||||
newLocationIncomplete := front.Input("New location:")
|
||||
syncclient.RenameRemoteFromClient(oldLocationIncomplete, newLocationIncomplete, false)
|
||||
err := syncclient.RenameRemoteFromClient(oldLocationIncomplete, newLocationIncomplete, false)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to rename entry: "+err.Error(), back.ErrorWrite, true)
|
||||
}
|
||||
|
||||
// exit is done from sync.RenameRemoteFromClient
|
||||
}
|
||||
@@ -25,7 +28,10 @@ func RenameCli(oldLocationIncomplete string) {
|
||||
// EditEntryField edits a field of an entry at targetLocation (user input).
|
||||
func EditEntryField(targetLocation string, hideSecrets bool, field int) {
|
||||
// fetch old entry data (with all required lines present)
|
||||
unencryptedEntry := core.GetOldEntryData(targetLocation, field)
|
||||
unencryptedEntry, err := core.GetOldEntryData(targetLocation, field)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to fetch entry data: "+err.Error(), back.ErrorRead, true)
|
||||
}
|
||||
|
||||
// edit the field
|
||||
switch field {
|
||||
@@ -57,7 +63,10 @@ func EditEntryField(targetLocation string, hideSecrets bool, field int) {
|
||||
// GenUpdate generates a new password for an entry at targetLocation (user input).
|
||||
func GenUpdate(targetLocation string, hideSecrets bool) {
|
||||
// fetch old entry data
|
||||
unencryptedEntry := core.GetOldEntryData(targetLocation, 0)
|
||||
unencryptedEntry, err := core.GetOldEntryData(targetLocation, 0)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to fetch entry data: "+err.Error(), back.ErrorRead, true)
|
||||
}
|
||||
|
||||
// generate a new password
|
||||
unencryptedEntry[0] = inputPasswordGen()
|
||||
|
||||
@@ -79,7 +79,10 @@ func printFileEntry(entry string, lastSlash, charCounter, indent int, colorAlter
|
||||
|
||||
// EntryListGen generates and displays the full libmutton entry list.
|
||||
func EntryListGen() {
|
||||
fileList, dirList := synccommon.WalkEntryDir()
|
||||
fileList, dirList, err := synccommon.WalkEntryDir()
|
||||
if err != nil {
|
||||
back.PrintError("Failed to generate entry list: "+err.Error(), back.ErrorRead, true)
|
||||
}
|
||||
|
||||
// print header bar w/total entry count
|
||||
fmt.Print("\n"+ansiBlackOnWhite, len(fileList), " libmutton entries:"+back.AnsiReset)
|
||||
|
||||
+10
-2
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/rwinkhart/go-boilerplate/back"
|
||||
"github.com/rwinkhart/libmutton/crypt"
|
||||
"github.com/rwinkhart/libmutton/global"
|
||||
"github.com/rwinkhart/libmutton/syncclient"
|
||||
)
|
||||
|
||||
@@ -65,7 +66,10 @@ fieldLoop:
|
||||
}
|
||||
|
||||
if syncEnabled {
|
||||
syncclient.RunJob(false, false)
|
||||
_, err := syncclient.RunJob(false, false)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to sync entries: "+err.Error(), global.ErrorSyncProcess, true)
|
||||
}
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
@@ -74,7 +78,11 @@ fieldLoop:
|
||||
// EntryReaderDecrypt is a wrapper for EntryReader that first decrypts an RCW-wrapped file before sending it to EntryReader.
|
||||
func EntryReaderDecrypt(targetLocation string, hideSecrets bool) {
|
||||
if isFile, _ := back.TargetIsFile(targetLocation, true, 2); isFile {
|
||||
EntryReader(crypt.DecryptFileToSlice(targetLocation), hideSecrets, false) // never sync if decrypting straight to EntryReader, as this means the entry could not have been modified
|
||||
decBytes, err := crypt.DecryptFileToSlice(targetLocation)
|
||||
if err != nil {
|
||||
back.PrintError("Failed to decrypt entry: "+err.Error(), global.ErrorDecryption, true)
|
||||
}
|
||||
EntryReader(decBytes, hideSecrets, false) // never sync if decrypting straight to EntryReader, as this means the entry could not have been modified
|
||||
}
|
||||
// do not exit, as this is the job of EntryReader
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
|
||||
package cli
|
||||
|
||||
const fallbackEditor = "vi" // vi is pre-installed on most UNIX-like systems
|
||||
const FallbackEditor = "vi" // vi is pre-installed on most UNIX-like systems
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
|
||||
package cli
|
||||
|
||||
const fallbackEditor = "edit" // "edit" is the Microsoft-developed CLI text editor
|
||||
const FallbackEditor = "edit" // "edit" is the Microsoft-developed CLI text editor
|
||||
|
||||
@@ -31,7 +31,10 @@ func inputPasswordGen() string {
|
||||
func writeEntryCLI(targetLocation string, unencryptedEntry []string, hideSecrets bool) {
|
||||
if core.EntryIsNotEmpty(unencryptedEntry) {
|
||||
// write the entry to the target location
|
||||
core.WriteEntry(targetLocation, []byte(strings.Join(unencryptedEntry, "\n")))
|
||||
err := core.WriteEntry(targetLocation, []byte(strings.Join(unencryptedEntry, "\n")))
|
||||
if err != nil {
|
||||
back.PrintError("Failed to write entry: "+err.Error(), back.ErrorWrite, true)
|
||||
}
|
||||
// preview the entry
|
||||
fmt.Println(back.AnsiBold + "\nEntry Preview:" + back.AnsiReset)
|
||||
EntryReader(unencryptedEntry, hideSecrets, true)
|
||||
|
||||
Reference in New Issue
Block a user