From 9ea547ef3ef0e947ef1cbbb591d78f8bfafe9ee0 Mon Sep 17 00:00:00 2001 From: lucor Date: Wed, 26 Jan 2022 19:56:01 +0100 Subject: [PATCH 1/9] makefile: wip --- Makefile | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ba5fdbe --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ + +VERSION ?= 0.15.0 + +build: + go build -ldflags "-w -s" -o ./bin/paw ./cmd/paw + go build -ldflags "-w -s" -o ./bin/paw-cli ./cmd/paw-cli + +darwin: + fyne-cross darwin --arch="*" ./cmd/paw + +freebsd: + fyne-cross freebsd --arch="*" ./cmd/paw + + +LINUX_ARCH = amd64 arm64 arm +linux: + @for arch in $(LINUX_ARCH); \ + do \ + echo "Packaging $$arch"; \ + fyne-cross linux --arch=$$arch -ldflags "-X main.Version=${VERSION}" ./cmd/paw; \ + golicense fyne-cross/bin/linux-$$arch/paw; \ + xz -d fyne-cross/dist/linux-$$arch/paw.tar.xz; \ + tar -rf fyne-cross/dist/linux-$$arch/paw.tar third-party-licenses.md LICENSE; \ + gzip -c fyne-cross/dist/linux-$$arch/paw.tar > dist/paw-${VERSION}-linux-$$arch.tar.gz; \ + rm third-party-licenses.md; \ + done + +WINDOWS_ARCH = amd64 +windows: + @for arch in $(WINDOWS_ARCH); \ + do \ + echo "Packaging $$arch"; \ + #fyne-cross linux --arch=$$arch -ldflags "-X main.Version=${VERSION}" ./cmd/paw; \ + golicense fyne-cross/bin/windows-$$arch/paw.exe; \ + cp fyne-cross/dist/windows-$$arch/paw.exe.zip dist/paw-${VERSION}-windows-$$arch.zip; \ + zip dist/paw-${VERSION}-windows-$$arch.zip third-party-licenses.md LICENSE; \ + rm third-party-licenses.md; \ + done From 2896ce558562902a8f397c749b198a50d8c84b0e Mon Sep 17 00:00:00 2001 From: lucor Date: Fri, 28 Jan 2022 20:39:48 +0100 Subject: [PATCH 2/9] all: updates messages to printed correctly on stdout and stderr --- cmd/paw-cli/main.go | 14 +++++++------- internal/cli/cli.go | 8 +++++--- internal/cli/cmd_add.go | 3 +-- internal/cli/cmd_edit.go | 3 +-- internal/cli/cmd_init.go | 3 +-- internal/cli/cmd_list.go | 3 +-- internal/cli/cmd_pwgen.go | 3 +-- internal/cli/cmd_rm.go | 3 +-- internal/cli/cmd_show.go | 22 +++++++++++----------- 9 files changed, 29 insertions(+), 33 deletions(-) diff --git a/cmd/paw-cli/main.go b/cmd/paw-cli/main.go index 50c3c94..4582334 100644 --- a/cmd/paw-cli/main.go +++ b/cmd/paw-cli/main.go @@ -1,7 +1,7 @@ package main import ( - "log" + "fmt" "os" "lucor.dev/paw/internal/cli" @@ -12,12 +12,10 @@ import ( var Version string func main() { - - log.SetFlags(0) - s, err := paw.NewOSStorage() if err != nil { - log.Fatal(err) + fmt.Fprintf(os.Stderr, "[✗] %s\n", err) + os.Exit(1) } // Define the command to use @@ -58,12 +56,14 @@ func main() { // and will exit in case of error err = cmd.Parse(os.Args[2:]) if err != nil { - log.Fatalf("[✗] %s", err) + fmt.Fprintf(os.Stderr, "[✗] %s\n", err) + os.Exit(1) } // Finally run the command err = cmd.Run(s) if err != nil { - log.Fatalf("[✗] %s", err) + fmt.Fprintf(os.Stderr, "[✗] %s\n", err) + os.Exit(1) } } diff --git a/internal/cli/cli.go b/internal/cli/cli.go index d4c8283..1f18e38 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -4,7 +4,6 @@ import ( "bufio" "fmt" "io" - "log" "os" "path/filepath" "strconv" @@ -12,6 +11,7 @@ import ( "text/template" "golang.org/x/term" + "lucor.dev/paw/internal/paw" ) @@ -47,11 +47,13 @@ func printUsage(textTemplate string, data interface{}) { func printTemplate(w io.Writer, textTemplate string, data interface{}) { tpl, err := template.New("tpl").Parse(textTemplate) if err != nil { - log.Fatalf("Could not parse the template: %s", err) + fmt.Fprintf(os.Stderr, "[✗] could not parse the template: %s\n", err) + os.Exit(1) } err = tpl.Execute(w, data) if err != nil { - log.Fatalf("Could not execute the template: %s", err) + fmt.Fprintf(os.Stderr, "[✗] could not execute the template: %s\n", err) + os.Exit(1) } } diff --git a/internal/cli/cmd_add.go b/internal/cli/cmd_add.go index ba5f87c..cb2d4b2 100644 --- a/internal/cli/cmd_add.go +++ b/internal/cli/cmd_add.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "log" "os" "lucor.dev/paw/internal/paw" @@ -100,7 +99,7 @@ func (cmd *AddCmd) Run(s paw.Storage) error { if err != nil { return err } - log.Printf("[✓] item %q added", cmd.itemName) + fmt.Printf("[✓] item %q added\n", cmd.itemName) return nil } diff --git a/internal/cli/cmd_edit.go b/internal/cli/cmd_edit.go index 8e46fd3..454500e 100644 --- a/internal/cli/cmd_edit.go +++ b/internal/cli/cmd_edit.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "log" "os" "lucor.dev/paw/internal/paw" @@ -101,7 +100,7 @@ func (cmd *EditCmd) Run(s paw.Storage) error { if err != nil { return err } - log.Printf("[✓] item %q modified", cmd.itemName) + fmt.Printf("[✓] item %q modified\n", cmd.itemName) return nil } diff --git a/internal/cli/cmd_init.go b/internal/cli/cmd_init.go index 04524b8..7d53489 100644 --- a/internal/cli/cmd_init.go +++ b/internal/cli/cmd_init.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "log" "os" "lucor.dev/paw/internal/paw" @@ -68,6 +67,6 @@ func (cmd *InitCmd) Run(s paw.Storage) error { if err != nil { return err } - log.Printf("[✓] vault %q created", cmd.vaultName) + fmt.Printf("[✓] vault %q created\n", cmd.vaultName) return nil } diff --git a/internal/cli/cmd_list.go b/internal/cli/cmd_list.go index ef96f17..5668a8a 100644 --- a/internal/cli/cmd_list.go +++ b/internal/cli/cmd_list.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "log" "os" "lucor.dev/paw/internal/paw" @@ -88,7 +87,7 @@ func (cmd *ListCmd) Run(s paw.Storage) error { } if len(n.Child) == 0 { - log.Printf("vault %q is empty", cmd.vaultName) + fmt.Printf("vault %q is empty\n", cmd.vaultName) return nil } diff --git a/internal/cli/cmd_pwgen.go b/internal/cli/cmd_pwgen.go index bc00cc6..45549c8 100644 --- a/internal/cli/cmd_pwgen.go +++ b/internal/cli/cmd_pwgen.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "log" "os" "lucor.dev/paw/internal/paw" @@ -61,7 +60,7 @@ func (cmd *PwGenCmd) Run(s paw.Storage) error { return err } - log.Println(password.Value) + fmt.Println(password.Value) return nil } diff --git a/internal/cli/cmd_rm.go b/internal/cli/cmd_rm.go index 93215eb..74f02e7 100644 --- a/internal/cli/cmd_rm.go +++ b/internal/cli/cmd_rm.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "log" "os" "lucor.dev/paw/internal/paw" @@ -98,6 +97,6 @@ func (cmd *RemoveCmd) Run(s paw.Storage) error { return err } - log.Printf("[✓] item %q removed", cmd.itemName) + fmt.Printf("[✓] item %q removed\n", cmd.itemName) return nil } diff --git a/internal/cli/cmd_show.go b/internal/cli/cmd_show.go index f7daa9f..0d25bb1 100644 --- a/internal/cli/cmd_show.go +++ b/internal/cli/cmd_show.go @@ -1,7 +1,7 @@ package cli import ( - "log" + "fmt" "os" "time" @@ -48,7 +48,7 @@ func (cmd *ShowCmd) Parse(args []string) error { os.Exit(0) } - itemPath, err := parseItemPath(args[0], itemPathOptions{fullPath: true}) + itemPath, err := parseItemPath(flagSet.Arg(0), itemPathOptions{fullPath: true}) if err != nil { return err } @@ -81,24 +81,24 @@ func (cmd *ShowCmd) Run(s paw.Storage) error { switch cmd.itemType { case paw.LoginItemType: v := item.(*paw.Login) - log.Printf("URL: %s", v.URL) - log.Printf("Username: %s", v.Username) - log.Printf("Password: %s", v.Password.Value) + fmt.Printf("URL: %s\n", v.URL) + fmt.Printf("Username: %s\n", v.Username) + fmt.Printf("Password: %s\n", v.Password.Value) if v.Note != nil { - log.Printf("Note: %s", v.Note.Value) + fmt.Printf("Note: %s\n", v.Note.Value) } case paw.PasswordItemType: v := item.(*paw.Password) - log.Printf("Password: %s", v.Value) + fmt.Printf("Password: %s\n", v.Value) if v.Note != nil { - log.Printf("Note: %s", v.Note.Value) + fmt.Printf("Note: %s\n", v.Note.Value) } case paw.NoteItemType: v := item.(*paw.Note) - log.Printf("Note: %s", v.Value) + fmt.Printf("Note: %s\n", v.Value) } - log.Printf("Created: %s", item.GetMetadata().Created.Format(time.RFC1123)) - log.Printf("Modified: %s", item.GetMetadata().Modified.Format(time.RFC1123)) + fmt.Printf("Created: %s\n", item.GetMetadata().Created.Format(time.RFC1123)) + fmt.Printf("Modified: %s\n", item.GetMetadata().Modified.Format(time.RFC1123)) return nil } From e492e76231fd862b66becde40d095af40d1563f0 Mon Sep 17 00:00:00 2001 From: lucor Date: Fri, 28 Jan 2022 20:40:32 +0100 Subject: [PATCH 3/9] cli: list command will show an hint message if no vaults are found --- internal/cli/cmd_list.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/cli/cmd_list.go b/internal/cli/cmd_list.go index 5668a8a..d266121 100644 --- a/internal/cli/cmd_list.go +++ b/internal/cli/cmd_list.go @@ -140,6 +140,9 @@ func (cmd *ListCmd) vaults(s paw.Storage) (tree.Node, error) { if err != nil { return n, err } + if len(vaults) == 0 { + return n, fmt.Errorf("no vaults found. To create one: paw-cli init VAULT") + } for _, v := range vaults { if cmd.vaultName != "" && cmd.vaultName != v { continue From 7f201e1473a871d700cac75591dcea7c5be08cc3 Mon Sep 17 00:00:00 2001 From: lucor Date: Fri, 28 Jan 2022 20:44:10 +0100 Subject: [PATCH 4/9] cli: add the "-c, --clip" option to copy password to clipboard --- CHANGELOG.md | 4 ++++ go.mod | 1 + go.sum | 16 +++++++++++++ internal/cli/clipboard.go | 49 +++++++++++++++++++++++++++++++++++++++ internal/cli/cmd_show.go | 38 ++++++++++++++++++++++++++++-- 5 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 internal/cli/clipboard.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 517e3ac..e5e7f9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog - Paw +## Unreleased + +- cli: add the "-c, --clip" option to copy password to clipboard + ## 0.15.0 - 26 January 2022 - cli: add CLI application #3 diff --git a/go.mod b/go.mod index 8676ee2..be64aa1 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( filippo.io/age v1.0.0 fyne.io/fyne/v2 v2.1.2 github.com/stretchr/testify v1.7.0 + golang.design/x/clipboard v0.6.0 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/image v0.0.0-20211028202545-6944b10bf410 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum index ba469a6..9cea153 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,7 @@ fyne.io/fyne/v2 v2.1.2 h1:avp9CvLAUdvE7fDMtH1tVKyjxEWHWcpow6aI6L7Kvvw= fyne.io/fyne/v2 v2.1.2/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -54,14 +55,27 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.8 h1:Nw158Q8QN+CPgTmVRByhVwapp8Mm1e2blinhmx4wx5E= github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.design/x/clipboard v0.6.0 h1:+U/e2KDBdpIjkRdxO8GwlD6dKD3Jx5zlNNzQjxte4A0= +golang.design/x/clipboard v0.6.0/go.mod h1:ep0pB+/4DGJK3ayLxweWJFHhHGGv3npJJHMXAjtLTUM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 h1:estk1glOnSVeJ9tdEZZc5mAMDZk5lNJNyJ6DvrBkTEU= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 h1:3In5TnfvnuXTF/uflgpYxSCEGP2NdYT37KsPh3VjZYU= +golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554/go.mod h1:jFTmtFYCV0MFtXBU+J5V/+5AUeVS0ON/0WkE/KSrl6E= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -89,7 +103,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/cli/clipboard.go b/internal/cli/clipboard.go new file mode 100644 index 0000000..c992f87 --- /dev/null +++ b/internal/cli/clipboard.go @@ -0,0 +1,49 @@ +package cli + +import ( + "bytes" + "context" + "fmt" + "time" + + "golang.design/x/clipboard" +) + +const ( + clipboardWatchInterval = 10 * time.Millisecond + clipboardWriteTimeout = 1 * time.Second +) + +func writeToClipboard(ctx context.Context, data []byte) error { + last := clipboard.Read(clipboard.FmtText) + if bytes.Equal(last, data) { + // data is the same in clipboard no need to write + return nil + } + + clipboard.Write(clipboard.FmtText, data) + + ti := time.NewTicker(clipboardWatchInterval) + defer ti.Stop() + + for { + select { + case <-ctx.Done(): + return fmt.Errorf("unable to write data to clipboard: timeout reached") + case <-ti.C: + b := clipboard.Read(clipboard.FmtText) + if b == nil { + continue + } + if bytes.Equal(last, b) { + // clipboard data not changed + continue + } + if !bytes.Equal(b, data) { + // clipboard data changed but with unexpected content + return fmt.Errorf("clipboard has been overwritten by others and data is lost") + } + return nil + } + } +} diff --git a/internal/cli/cmd_show.go b/internal/cli/cmd_show.go index 0d25bb1..db3445a 100644 --- a/internal/cli/cmd_show.go +++ b/internal/cli/cmd_show.go @@ -1,16 +1,20 @@ package cli import ( + "context" "fmt" "os" "time" + "golang.design/x/clipboard" + "lucor.dev/paw/internal/paw" ) // Show shows an item details type ShowCmd struct { itemPath + clipboard bool } // Name returns the one word command name @@ -30,6 +34,7 @@ func (cmd *ShowCmd) Usage() { {{ . }} Options: + -c, --clip Do not print the password but instead copy to the clipboard -h, --help Displays this help and exit ` printUsage(template, cmd.Description()) @@ -42,12 +47,22 @@ func (cmd *ShowCmd) Parse(args []string) error { return err } + flagSet.BoolVar(&cmd.clipboard, "c", false, "") + flagSet.BoolVar(&cmd.clipboard, "clip", false, "") + flagSet.Parse(args) if flags.Help || len(flagSet.Args()) != 1 { cmd.Usage() os.Exit(0) } + if cmd.clipboard { + err := clipboard.Init() + if err != nil { + return err + } + } + itemPath, err := parseItemPath(flagSet.Arg(0), itemPathOptions{fullPath: true}) if err != nil { return err @@ -78,18 +93,27 @@ func (cmd *ShowCmd) Run(s paw.Storage) error { return err } + var pclip []byte switch cmd.itemType { case paw.LoginItemType: v := item.(*paw.Login) fmt.Printf("URL: %s\n", v.URL) fmt.Printf("Username: %s\n", v.Username) - fmt.Printf("Password: %s\n", v.Password.Value) + if !cmd.clipboard { + fmt.Printf("Password: %s\n", v.Password.Value) + } else { + pclip = []byte(v.Password.Value) + } if v.Note != nil { fmt.Printf("Note: %s\n", v.Note.Value) } case paw.PasswordItemType: v := item.(*paw.Password) - fmt.Printf("Password: %s\n", v.Value) + if !cmd.clipboard { + fmt.Printf("Password: %s\n", v.Value) + } else { + pclip = []byte(v.Value) + } if v.Note != nil { fmt.Printf("Note: %s\n", v.Note.Value) } @@ -100,5 +124,15 @@ func (cmd *ShowCmd) Run(s paw.Storage) error { fmt.Printf("Created: %s\n", item.GetMetadata().Created.Format(time.RFC1123)) fmt.Printf("Modified: %s\n", item.GetMetadata().Modified.Format(time.RFC1123)) + + if pclip != nil { + ctx, cancel := context.WithTimeout(context.Background(), clipboardWriteTimeout) + defer cancel() + err := writeToClipboard(ctx, pclip) + if err != nil { + return nil + } + fmt.Println("[✓] password copied to clipboard") + } return nil } From 8eb5be58f7d2d6d481d968def6ee66304105e9ce Mon Sep 17 00:00:00 2001 From: lucor Date: Fri, 18 Feb 2022 09:07:40 +0100 Subject: [PATCH 5/9] makefile: delete file --- Makefile | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 Makefile diff --git a/Makefile b/Makefile deleted file mode 100644 index ba5fdbe..0000000 --- a/Makefile +++ /dev/null @@ -1,38 +0,0 @@ - -VERSION ?= 0.15.0 - -build: - go build -ldflags "-w -s" -o ./bin/paw ./cmd/paw - go build -ldflags "-w -s" -o ./bin/paw-cli ./cmd/paw-cli - -darwin: - fyne-cross darwin --arch="*" ./cmd/paw - -freebsd: - fyne-cross freebsd --arch="*" ./cmd/paw - - -LINUX_ARCH = amd64 arm64 arm -linux: - @for arch in $(LINUX_ARCH); \ - do \ - echo "Packaging $$arch"; \ - fyne-cross linux --arch=$$arch -ldflags "-X main.Version=${VERSION}" ./cmd/paw; \ - golicense fyne-cross/bin/linux-$$arch/paw; \ - xz -d fyne-cross/dist/linux-$$arch/paw.tar.xz; \ - tar -rf fyne-cross/dist/linux-$$arch/paw.tar third-party-licenses.md LICENSE; \ - gzip -c fyne-cross/dist/linux-$$arch/paw.tar > dist/paw-${VERSION}-linux-$$arch.tar.gz; \ - rm third-party-licenses.md; \ - done - -WINDOWS_ARCH = amd64 -windows: - @for arch in $(WINDOWS_ARCH); \ - do \ - echo "Packaging $$arch"; \ - #fyne-cross linux --arch=$$arch -ldflags "-X main.Version=${VERSION}" ./cmd/paw; \ - golicense fyne-cross/bin/windows-$$arch/paw.exe; \ - cp fyne-cross/dist/windows-$$arch/paw.exe.zip dist/paw-${VERSION}-windows-$$arch.zip; \ - zip dist/paw-${VERSION}-windows-$$arch.zip third-party-licenses.md LICENSE; \ - rm third-party-licenses.md; \ - done From 487c4321aab4300a9f40577b0e90f727cb003bec Mon Sep 17 00:00:00 2001 From: lucor Date: Fri, 18 Feb 2022 09:12:56 +0100 Subject: [PATCH 6/9] all: fix regression about setting item date This commit updates a regression was not allowing to set correctly the modified field on edit. This was also preventing to edit an item using the GUI. Fixes #10 --- internal/cli/cmd_edit.go | 3 +++ internal/cli/cmd_show.go | 2 +- internal/paw/item_metadata.go | 4 ++++ internal/ui/vault_view.go | 5 ++++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/internal/cli/cmd_edit.go b/internal/cli/cmd_edit.go index 454500e..1b4ad99 100644 --- a/internal/cli/cmd_edit.go +++ b/internal/cli/cmd_edit.go @@ -3,6 +3,7 @@ package cli import ( "fmt" "os" + "time" "lucor.dev/paw/internal/paw" ) @@ -88,6 +89,8 @@ func (cmd *EditCmd) Run(s paw.Storage) error { return fmt.Errorf("unsupported item type: %q", cmd.itemType) } + item.GetMetadata().Modified = time.Now() + err = s.StoreItem(vault, item) if err != nil { return err diff --git a/internal/cli/cmd_show.go b/internal/cli/cmd_show.go index db3445a..2aa6419 100644 --- a/internal/cli/cmd_show.go +++ b/internal/cli/cmd_show.go @@ -122,8 +122,8 @@ func (cmd *ShowCmd) Run(s paw.Storage) error { fmt.Printf("Note: %s\n", v.Value) } - fmt.Printf("Created: %s\n", item.GetMetadata().Created.Format(time.RFC1123)) fmt.Printf("Modified: %s\n", item.GetMetadata().Modified.Format(time.RFC1123)) + fmt.Printf("Created: %s\n", item.GetMetadata().Created.Format(time.RFC1123)) if pclip != nil { ctx, cancel := context.WithTimeout(context.Background(), clipboardWriteTimeout) diff --git a/internal/paw/item_metadata.go b/internal/paw/item_metadata.go index dee908e..72e786a 100644 --- a/internal/paw/item_metadata.go +++ b/internal/paw/item_metadata.go @@ -34,6 +34,10 @@ func (m *Metadata) GetMetadata() *Metadata { return m } +func (m *Metadata) IsEmpty() bool { + return m.Name == "" +} + func (m *Metadata) String() string { return m.Name } diff --git a/internal/ui/vault_view.go b/internal/ui/vault_view.go index 6f82544..478c82a 100644 --- a/internal/ui/vault_view.go +++ b/internal/ui/vault_view.go @@ -11,6 +11,7 @@ import ( "strings" "sync" "sync/atomic" + "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" @@ -326,8 +327,10 @@ func (vw *vaultView) editItemView(ctx context.Context, fyneItem FyneItem) fyne.C var reloadItems bool var isNew bool - if metadata.Created == metadata.Modified { + if item.GetMetadata().IsEmpty() { isNew = true + } else { + metadata.Modified = time.Now() } if isNew && vw.vault.HasItem(editItem) { From 8cf618eef482cb28c121f4760927ca63083b084a Mon Sep 17 00:00:00 2001 From: lucor Date: Mon, 28 Feb 2022 19:01:15 +0100 Subject: [PATCH 7/9] gui: update filter to be case insensitive --- internal/paw/vault.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/paw/vault.go b/internal/paw/vault.go index b15c74d..ea2bf55 100644 --- a/internal/paw/vault.go +++ b/internal/paw/vault.go @@ -100,7 +100,7 @@ func (v *Vault) Range(f func(id string, meta *Metadata) bool) { func (v *Vault) FilterItemMetadata(opts *VaultFilterOptions) []*Metadata { metadata := []*Metadata{} - nameFilter := opts.Name + nameFilter := strings.ToLower(opts.Name) for t, itemMetadataByType := range v.ItemMetadata { if opts.ItemType != 0 && (opts.ItemType&t) == 0 { @@ -108,7 +108,7 @@ func (v *Vault) FilterItemMetadata(opts *VaultFilterOptions) []*Metadata { } for _, itemMetadata := range itemMetadataByType { - if nameFilter != "" && !strings.Contains(itemMetadata.Name, nameFilter) { + if nameFilter != "" && !strings.Contains(strings.ToLower(itemMetadata.Name), nameFilter) { continue } metadata = append(metadata, itemMetadata) From c38f2e2a778ec989eac612b1f01051011a974fa7 Mon Sep 17 00:00:00 2001 From: lucor Date: Mon, 28 Feb 2022 19:01:49 +0100 Subject: [PATCH 8/9] deps: update fyne to v2.1.3 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index be64aa1..802c349 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( filippo.io/age v1.0.0 - fyne.io/fyne/v2 v2.1.2 + fyne.io/fyne/v2 v2.1.3 github.com/stretchr/testify v1.7.0 golang.design/x/clipboard v0.6.0 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 diff --git a/go.sum b/go.sum index 9cea153..dbdde74 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ filippo.io/age v1.0.0 h1:V6q14n0mqYU3qKFkZ6oOaF9oXneOviS3ubXsSVBRSzc= filippo.io/age v1.0.0/go.mod h1:PaX+Si/Sd5G8LgfCwldsSba3H1DDQZhIhFGkhbHaBq8= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -fyne.io/fyne/v2 v2.1.2 h1:avp9CvLAUdvE7fDMtH1tVKyjxEWHWcpow6aI6L7Kvvw= -fyne.io/fyne/v2 v2.1.2/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ= +fyne.io/fyne/v2 v2.1.3 h1:I5qSeENAcq67hmO5Z2hI7sEJm9bdLMDJx59Fv8qJkX0= +fyne.io/fyne/v2 v2.1.3/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= From d32c70c68cbd469560ed5ecc94e64a4dc352767e Mon Sep 17 00:00:00 2001 From: lucor Date: Mon, 28 Feb 2022 19:08:03 +0100 Subject: [PATCH 9/9] changelog: release v0.16.0 --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5e7f9c..2197225 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,13 @@ # Changelog - Paw -## Unreleased +## 0.16.0 - 28 February 2022 +- all: fix regression about setting item date - cli: add the "-c, --clip" option to copy password to clipboard +- cli: update messages to printed correctly on stdout and stderr +- cli:list command will show an hint message if no vaults are found +- cli,deps: add golang.design/x/clipboard +- gui,deps: update fyne.io/fyne to v2.1.3 ## 0.15.0 - 26 January 2022