Replace clipboard package (#868) (#1721)

* Replace clipboard package

Fixes #868

* Raise error when clipboard.Write fails

* Call clipboard.Write when Init successes

* Flash error rather than panic

* Refactor copying into clipboard

* Refactor cpCmd to remove wrappers

* Use clipboardWrite instead of cpCmd
mine
Takumi Sue 2022-09-22 04:27:42 +09:00 committed by GitHub
parent bd677cc01b
commit 6c9d06a2a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 51 deletions

5
go.mod
View File

@ -6,7 +6,6 @@ replace github.com/gdamore/tcell/v2 => github.com/derailed/tcell/v2 v2.3.1-rc.2
require (
github.com/adrg/xdg v0.4.0
github.com/atotto/clipboard v0.1.4
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/cenkalti/backoff/v4 v4.1.3
github.com/derailed/popeye v0.10.1
@ -24,6 +23,7 @@ require (
github.com/sahilm/fuzzy v0.1.0
github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.8.0
golang.design/x/clipboard v0.6.2
golang.org/x/text v0.3.7
gopkg.in/yaml.v2 v2.4.0
helm.sh/helm/v3 v3.9.2
@ -146,6 +146,9 @@ require (
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 // indirect
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect
golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect

10
go.sum
View File

@ -109,8 +109,6 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aws/aws-sdk-go v1.38.49 h1:E31vxjCe6a5I+mJLmUGaZobiWmg9KdWaud9IfceYeYQ=
github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
@ -792,6 +790,8 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
golang.design/x/clipboard v0.6.2 h1:a3Np4qfKnLWwfFJQhUWU3IDeRfmVuqWl+QPtP4CSYGw=
golang.design/x/clipboard v0.6.2/go.mod h1:kqBSweBP0/im4SZGGjLrppH0D400Hnfo5WbFKSNK8N4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -812,15 +812,19 @@ golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
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-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -835,6 +839,8 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
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.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=

View File

@ -5,7 +5,6 @@ import (
"fmt"
"strings"
"github.com/atotto/clipboard"
"github.com/derailed/k9s/internal/config"
"github.com/derailed/k9s/internal/model"
"github.com/derailed/k9s/internal/ui"
@ -125,7 +124,7 @@ func (d *Details) bindKeys() {
tcell.KeyEnter: ui.NewSharedKeyAction("Filter", d.filterCmd, false),
tcell.KeyEscape: ui.NewKeyAction("Back", d.resetCmd, false),
tcell.KeyCtrlS: ui.NewKeyAction("Save", d.saveCmd, false),
ui.KeyC: ui.NewKeyAction("Copy", d.cpCmd, true),
ui.KeyC: ui.NewKeyAction("Copy", cpCmd(d.app.Flash(), d.text), true),
ui.KeyF: ui.NewKeyAction("Toggle FullScreen", d.toggleFullScreenCmd, true),
ui.KeyN: ui.NewKeyAction("Next Match", d.nextCmd, true),
ui.KeyShiftN: ui.NewKeyAction("Prev Match", d.prevCmd, true),
@ -292,15 +291,6 @@ func (d *Details) saveCmd(evt *tcell.EventKey) *tcell.EventKey {
return nil
}
func (d *Details) cpCmd(evt *tcell.EventKey) *tcell.EventKey {
d.app.Flash().Info("Content copied to clipboard...")
if err := clipboard.WriteAll(d.text.GetText(true)); err != nil {
d.app.Flash().Err(err)
}
return nil
}
func (d *Details) updateTitle() {
if d.title == "" {
return

View File

@ -13,8 +13,10 @@ import (
"github.com/derailed/k9s/internal/model"
"github.com/derailed/k9s/internal/render"
"github.com/derailed/k9s/internal/ui"
"github.com/derailed/tview"
"github.com/gdamore/tcell/v2"
"github.com/rs/zerolog/log"
"golang.design/x/clipboard"
)
func parsePFAnn(s string) (string, string, bool) {
@ -214,3 +216,24 @@ func decorateCpuMemHeaderRows(app *App, data *render.TableData) *render.TableDat
return data
}
func clipboardWrite(text string) error {
if err := clipboard.Init(); err != nil {
return err
}
if clipboard.Write(clipboard.FmtText, []byte(text)) == nil {
return errors.New("unable to write to clipboard")
}
return nil
}
func cpCmd(flash *model.Flash, v *tview.TextView) func(*tcell.EventKey) *tcell.EventKey {
return func(evt *tcell.EventKey) *tcell.EventKey {
if err := clipboardWrite(v.GetText(true)); err != nil {
flash.Err(err)
return evt
}
flash.Info("Content copied to clipboard...")
return nil
}
}

View File

@ -6,7 +6,6 @@ import (
"strconv"
"strings"
"github.com/atotto/clipboard"
"github.com/derailed/k9s/internal"
"github.com/derailed/k9s/internal/config"
"github.com/derailed/k9s/internal/model"
@ -136,7 +135,7 @@ func (v *LiveView) bindKeys() {
tcell.KeyEnter: ui.NewSharedKeyAction("Filter", v.filterCmd, false),
tcell.KeyEscape: ui.NewKeyAction("Back", v.resetCmd, false),
tcell.KeyCtrlS: ui.NewKeyAction("Save", v.saveCmd, false),
ui.KeyC: ui.NewKeyAction("Copy", v.cpCmd, true),
ui.KeyC: ui.NewKeyAction("Copy", cpCmd(v.app.Flash(), v.text), true),
ui.KeyF: ui.NewKeyAction("Toggle FullScreen", v.toggleFullScreenCmd, true),
ui.KeyR: ui.NewKeyAction("Toggle Auto-Refresh", v.toggleRefreshCmd, true),
ui.KeyN: ui.NewKeyAction("Next Match", v.nextCmd, true),
@ -341,15 +340,6 @@ func (v *LiveView) saveCmd(evt *tcell.EventKey) *tcell.EventKey {
return nil
}
func (v *LiveView) cpCmd(evt *tcell.EventKey) *tcell.EventKey {
v.app.Flash().Info("Content copied to clipboard...")
if err := clipboard.WriteAll(v.text.GetText(true)); err != nil {
v.app.Flash().Err(err)
}
return nil
}
func (v *LiveView) updateTitle() {
if v.title == "" {
return

View File

@ -10,7 +10,6 @@ import (
"sync"
"time"
"github.com/atotto/clipboard"
"github.com/derailed/k9s/internal/client"
"github.com/derailed/k9s/internal/color"
"github.com/derailed/k9s/internal/config"
@ -252,7 +251,7 @@ func (l *Log) bindKeys() {
ui.KeyT: ui.NewKeyAction("Toggle Timestamp", l.toggleTimestampCmd, true),
ui.KeyW: ui.NewKeyAction("Toggle Wrap", l.toggleTextWrapCmd, true),
tcell.KeyCtrlS: ui.NewKeyAction("Save", l.SaveCmd, true),
ui.KeyC: ui.NewKeyAction("Copy", l.cpCmd, true),
ui.KeyC: ui.NewKeyAction("Copy", cpCmd(l.app.Flash(), l.logs.TextView), true),
})
if l.model.HasDefaultContainer() {
l.logs.Actions().Set(ui.KeyActions{
@ -406,14 +405,6 @@ func (l *Log) SaveCmd(*tcell.EventKey) *tcell.EventKey {
return nil
}
func (l *Log) cpCmd(*tcell.EventKey) *tcell.EventKey {
l.app.Flash().Info("Content copied to clipboard...")
if err := clipboard.WriteAll(l.logs.GetText(true)); err != nil {
l.app.Flash().Err(err)
}
return nil
}
func ensureDir(dir string) error {
return os.MkdirAll(dir, 0744)
}

View File

@ -3,7 +3,6 @@ package view
import (
"context"
"github.com/atotto/clipboard"
"github.com/derailed/k9s/internal/config"
"github.com/derailed/k9s/internal/model"
"github.com/derailed/k9s/internal/ui"
@ -70,7 +69,7 @@ func (l *Logger) bindKeys() {
l.actions.Set(ui.KeyActions{
tcell.KeyEscape: ui.NewKeyAction("Back", l.resetCmd, false),
tcell.KeyCtrlS: ui.NewKeyAction("Save", l.saveCmd, false),
ui.KeyC: ui.NewKeyAction("Copy", l.cpCmd, true),
ui.KeyC: ui.NewKeyAction("Copy", cpCmd(l.app.Flash(), l.TextView), true),
ui.KeySlash: ui.NewSharedKeyAction("Filter Mode", l.activateCmd, false),
tcell.KeyDelete: ui.NewSharedKeyAction("Erase", l.eraseCmd, false),
})
@ -160,12 +159,3 @@ func (l *Logger) saveCmd(evt *tcell.EventKey) *tcell.EventKey {
return nil
}
func (l *Logger) cpCmd(evt *tcell.EventKey) *tcell.EventKey {
l.app.Flash().Info("Content copied to clipboard...")
if err := clipboard.WriteAll(l.GetText(true)); err != nil {
l.app.Flash().Err(err)
}
return nil
}

View File

@ -5,7 +5,6 @@ import (
"strings"
"time"
"github.com/atotto/clipboard"
"github.com/derailed/k9s/internal"
"github.com/derailed/k9s/internal/client"
"github.com/derailed/k9s/internal/model"
@ -207,12 +206,12 @@ func (t *Table) cpCmd(evt *tcell.EventKey) *tcell.EventKey {
if path == "" {
return evt
}
_, n := client.Namespaced(path)
log.Debug().Msgf("Copied selection to clipboard %q", n)
t.app.Flash().Info("Current selection copied to clipboard...")
if err := clipboard.WriteAll(n); err != nil {
err := clipboardWrite(n)
if err != nil {
t.app.Flash().Err(err)
} else {
t.app.Flash().Info("Current selection copied to clipboard...")
}
return nil