commit c9f3e5560d737fc2159de8adac6dd843313b4790
parent b4af1807ab02cc244c85bb1dfd01991a10a559bc
Author: Sean Enck <sean@ttypty.com>
Date: Sat, 16 Jul 2022 11:27:08 -0400
fixing 'lb'
Diffstat:
6 files changed, 99 insertions(+), 55 deletions(-)
diff --git a/cmd/lb/main.go b/cmd/lb/main.go
@@ -12,7 +12,12 @@ import (
"time"
"github.com/enckse/lockbox/internal/cli"
- "github.com/enckse/lockbox/internal/clipboard"
+ "github.com/enckse/lockbox/internal/clip"
+ "github.com/enckse/lockbox/internal/colors"
+ "github.com/enckse/lockbox/internal/dump"
+ "github.com/enckse/lockbox/internal/encrypt"
+ "github.com/enckse/lockbox/internal/hooks"
+ "github.com/enckse/lockbox/internal/inputs"
"github.com/enckse/lockbox/internal/misc"
"github.com/enckse/lockbox/internal/store"
)
@@ -22,11 +27,11 @@ var (
libExec = ""
)
-func getEntry(store string, args []string, idx int) string {
+func getEntry(fs store.FileSystem, args []string, idx int) string {
if len(args) != idx+1 {
misc.Die("invalid entry given", errors.New("specific entry required"))
}
- return filepath.Join(store, args[idx]) + store.Extension
+ return fs.NewPath(args[idx])
}
func getExecutable() string {
@@ -43,7 +48,7 @@ func main() {
misc.Die("missing arguments", errors.New("requires subcommand"))
}
command := args[1]
- store := internal.GetStore()
+ fs := store.NewFileSystemStore()
switch command {
case "ls", "list", "find":
isFind := command == "find"
@@ -54,7 +59,7 @@ func main() {
}
searchTerm = args[2]
}
- files, err := internal.List(store, true)
+ files, err := fs.List(store.ViewOptions{Display: true})
if err != nil {
misc.Die("unable to list files", err)
}
@@ -84,9 +89,9 @@ func main() {
default:
misc.Die("too many arguments", errors.New("insert can only perform one operation"))
}
- isPipe := internal.IsInputFromPipe()
- entry := getEntry(store, args, idx)
- if internal.PathExists(entry) {
+ isPipe := inputs.IsInputFromPipe()
+ entry := getEntry(fs, args, idx)
+ if misc.PathExists(entry) {
if !isPipe {
if !confirm("overwrite existing") {
return
@@ -94,7 +99,7 @@ func main() {
}
} else {
dir := filepath.Dir(entry)
- if !internal.PathExists(dir) {
+ if !misc.PathExists(dir) {
if err := os.MkdirAll(dir, 0755); err != nil {
misc.Die("failed to create directory structure", err)
}
@@ -102,13 +107,13 @@ func main() {
}
var password string
if !options.Multi && !isPipe {
- input, err := internal.ConfirmInputsMatch("password")
+ input, err := inputs.ConfirmInputsMatch("password")
if err != nil {
misc.Die("password input failed", err)
}
password = input
} else {
- input, err := internal.Stdin(false)
+ input, err := inputs.Stdin(false)
if err != nil {
misc.Die("failed to read stdin", err)
}
@@ -117,7 +122,7 @@ func main() {
if password == "" {
misc.Die("empty password provided", errors.New("password can NOT be empty"))
}
- l, err := internal.NewLockbox(internal.LockboxOptions{File: entry})
+ l, err := encrypt.NewLockbox(encrypt.LockboxOptions{File: entry})
if err != nil {
misc.Die("unable to make lockbox model instance", err)
}
@@ -125,15 +130,15 @@ func main() {
misc.Die("failed to save password", err)
}
fmt.Println("")
- internal.Hooks(internal.InsertHook, internal.PostHookStep)
+ hooks.Run(hooks.Insert, hooks.PostStep)
case "rm":
- entry := getEntry(store, args, 2)
- if !internal.PathExists(entry) {
+ entry := getEntry(fs, args, 2)
+ if !misc.PathExists(entry) {
misc.Die("does not exists", errors.New("can not delete unknown entry"))
}
if confirm("remove entry") {
os.Remove(entry)
- internal.Hooks(internal.RemoveHook, internal.PostHookStep)
+ hooks.Run(hooks.Remove, hooks.PostStep)
}
case "show", "-c", "clip", "dump":
isDump := command == "dump"
@@ -147,12 +152,12 @@ func main() {
}
}
}
- inEntry := getEntry(store, args, startEntry)
+ inEntry := getEntry(fs, args, startEntry)
isShow := command == "show" || isDump
entries := []string{inEntry}
if strings.Contains(inEntry, "*") {
- if inEntry == getEntry(store, []string{"***"}, 0) {
- all, err := internal.List(store, false)
+ if inEntry == getEntry(fs, []string{"***"}, 0) {
+ all, err := fs.List(store.ViewOptions{})
if err != nil {
misc.Die("unable to get all files", err)
}
@@ -172,23 +177,23 @@ func main() {
}
sort.Strings(entries)
}
- startColor, endColor, err := internal.GetColor(internal.ColorRed)
+ coloring, err := colors.NewTerminal(colors.Red)
if err != nil {
misc.Die("unable to get color for terminal", err)
}
- dumpData := []Dump{}
- clip := clipboard.Commands{}
+ dumpData := []dump.ExportEntity{}
+ clipboard := clip.Commands{}
if !isShow {
- clip, err = clipboard.NewCommands()
+ clipboard, err = clip.NewCommands()
if err != nil {
misc.Die("unable to get clipboard", err)
}
}
for _, entry := range entries {
- if !internal.PathExists(entry) {
+ if !misc.PathExists(entry) {
misc.Die("invalid entry", errors.New("entry not found"))
}
- l, err := internal.NewLockbox(internal.LockboxOptions{File: entry})
+ l, err := encrypt.NewLockbox(encrypt.LockboxOptions{File: entry})
if err != nil {
misc.Die("unable to make lockbox model instance", err)
}
@@ -197,29 +202,25 @@ func main() {
misc.Die("unable to decrypt", err)
}
value := strings.TrimSpace(string(decrypt))
- dump := Dump{}
+ entity := dump.ExportEntity{}
if isShow {
if isGlob {
- fileName := strings.ReplaceAll(entry, store, "")
- if fileName[0] == '/' {
- fileName = fileName[1:]
- }
- fileName = strings.ReplaceAll(fileName, internal.Extension, "")
+ fileName := fs.CleanPath(entry)
if isDump {
- dump.Path = fileName
+ entity.Path = fileName
} else {
- fmt.Printf("%s%s:%s\n", startColor, fileName, endColor)
+ fmt.Printf("%s%s:%s\n", coloring.Start, fileName, coloring.End)
}
}
if isDump {
- dump.Value = value
- dumpData = append(dumpData, dump)
+ entity.Value = value
+ dumpData = append(dumpData, entity)
} else {
fmt.Println(value)
}
continue
}
- clip.CopyToClipboard(value, getExecutable())
+ clipboard.CopyTo(value, getExecutable())
}
if isDump {
if !options.Yes {
@@ -242,23 +243,23 @@ func main() {
}
case "clear":
idx := 0
- val, err := internal.Stdin(false)
+ val, err := inputs.Stdin(false)
if err != nil {
misc.Die("unable to read value to clear", err)
}
- clip, err := clipboard.NewCommands()
+ clipboard, err := clip.NewCommands()
if err != nil {
misc.Die("unable to get paste command", err)
}
var args []string
- if len(clip.Paste) > 1 {
- args = clip.Paste[1:]
+ if len(clipboard.Paste) > 1 {
+ args = clipboard.Paste[1:]
}
val = strings.TrimSpace(val)
- for idx < clipboard.MaxTime {
+ for idx < clip.MaxTime {
idx++
time.Sleep(1 * time.Second)
- out, err := exec.Command(clip.Paste[0], args...).Output()
+ out, err := exec.Command(clipboard.Paste[0], args...).Output()
if err != nil {
continue
}
@@ -268,7 +269,7 @@ func main() {
return
}
}
- clip.CopyToClipboard("", getExecutable())
+ clipboard.CopyTo("", getExecutable())
default:
lib := os.Getenv("LOCKBOX_LIBEXEC")
if lib == "" {
@@ -285,7 +286,7 @@ func main() {
}
func confirm(prompt string) bool {
- yesNo, err := internal.ConfirmYesNoPrompt(prompt)
+ yesNo, err := inputs.ConfirmYesNoPrompt(prompt)
if err != nil {
misc.Die("failed to get response", err)
}
diff --git a/internal/clip/clipboard.go b/internal/clip/clipboard.go
@@ -72,8 +72,8 @@ func NewCommands() (Commands, error) {
}
}
-// CopyToClipboard will copy to clipboard, if non-empty will clear later.
-func (c Commands) CopyToClipboard(value, executable string) {
+// CopyTo will copy to clipboard, if non-empty will clear later.
+func (c Commands) CopyTo(value, executable string) {
var args []string
if len(c.Copy) > 1 {
args = c.Copy[1:]
diff --git a/internal/encrypt/core.go b/internal/encrypt/core.go
@@ -1,4 +1,4 @@
-package internal
+package encrypt
import (
"crypto/rand"
diff --git a/internal/encrypt/core_test.go b/internal/encrypt/core_test.go
@@ -1,4 +1,4 @@
-package internal
+package encrypt
import (
"os"
diff --git a/internal/store/filesystem.go b/internal/store/filesystem.go
@@ -12,8 +12,7 @@ import (
)
const (
- // Extension is the lockbox file extension.
- Extension = ".lb"
+ extension = ".lb"
)
type (
@@ -28,8 +27,8 @@ type (
)
// NewFileSystemStore gets the lockbox directory (filesystem-based) store.
-func NewFileSystemStore() string {
- return os.Getenv("LOCKBOX_STORE")
+func NewFileSystemStore() FileSystem {
+ return FileSystem{path: os.Getenv("LOCKBOX_STORE")}
}
// List will get all lockbox files in a store.
@@ -42,12 +41,12 @@ func (s FileSystem) List(options ViewOptions) ([]string, error) {
if err != nil {
return err
}
- if strings.HasSuffix(path, Extension) {
+ if strings.HasSuffix(path, extension) {
usePath := path
if options.Display {
usePath = strings.TrimPrefix(usePath, s.path)
usePath = strings.TrimPrefix(usePath, "/")
- usePath = strings.TrimSuffix(usePath, Extension)
+ usePath = strings.TrimSuffix(usePath, extension)
}
results = append(results, usePath)
}
@@ -62,3 +61,23 @@ func (s FileSystem) List(options ViewOptions) ([]string, error) {
}
return results, nil
}
+
+// NewPath creates a new filesystem store path for an entry.
+func (s FileSystem) NewPath(file string) string {
+ return filepath.Join(s.path, file) + extension
+}
+
+// CleanPath will clean store and extension information from an entry.
+func (s FileSystem) CleanPath(fullPath string) string {
+ fileName := fullPath
+ if strings.HasPrefix(fullPath, s.path) {
+ fileName = fileName[len(s.path):]
+ }
+ if fileName[0] == '/' {
+ fileName = fileName[1:]
+ }
+ if strings.HasSuffix(fileName, extension) {
+ fileName = fileName[0 : len(fileName)-len(extension)]
+ }
+ return fileName
+}
diff --git a/internal/store/filesystem_test.go b/internal/store/filesystem_test.go
@@ -26,7 +26,7 @@ func TestList(t *testing.T) {
t.Errorf("unable to makedir: %v", err)
}
for _, path := range []string{"test", "test2", "aaa", "sub/aaaaajk", "sub/12lkjafav"} {
- if err := os.WriteFile(filepath.Join(testStore, path+Extension), []byte(""), 0644); err != nil {
+ if err := os.WriteFile(filepath.Join(testStore, path+extension), []byte(""), 0644); err != nil {
t.Errorf("failed to write %s: %v", path, err)
}
}
@@ -49,3 +49,27 @@ func TestList(t *testing.T) {
t.Errorf("not sorted: %v", res)
}
}
+
+func TestFileSystemFile(t *testing.T) {
+ f := FileSystem{path: "abc"}
+ p := f.NewPath("test")
+ if p != "abc/test.lb" {
+ t.Error("invalid join result")
+ }
+}
+
+func TestCleanPath(t *testing.T) {
+ f := FileSystem{path: "abc"}
+ c := f.CleanPath("xyz")
+ if c != "xyz" {
+ t.Error("invalid clean")
+ }
+ c = f.CleanPath("abc/xyz")
+ if c != "xyz" {
+ t.Error("invalid clean")
+ }
+ c = f.CleanPath("xyz.lb.lb")
+ if c != "xyz.lb" {
+ t.Error("invalid clean")
+ }
+}