From 693d52e992c306e17a91aedce3e7e1b3b92be697 Mon Sep 17 00:00:00 2001 From: Nicolas Dumazet Date: Mon, 13 Jan 2025 23:12:35 +0100 Subject: [PATCH] Expose a public `plugin.NewClientUI()` This would allow `age` library users to create the needed inputs to interact with the `plugin` module. --- cmd/age/tui.go | 56 +-------------------------------------------- plugin/client.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 55 deletions(-) diff --git a/cmd/age/tui.go b/cmd/age/tui.go index 1110a40d..9b44b6a7 100644 --- a/cmd/age/tui.go +++ b/cmd/age/tui.go @@ -15,13 +15,11 @@ package main import ( "bytes" - "errors" "fmt" "io" "os" "filippo.io/age/armor" - "filippo.io/age/internal/logger" "filippo.io/age/internal/term" "filippo.io/age/plugin" ) @@ -33,59 +31,7 @@ func printfToTerminal(format string, v ...interface{}) error { }) } -var pluginTerminalUI = &plugin.ClientUI{ - DisplayMessage: func(name, message string) error { - logger.Global.Printf("%s plugin: %s", name, message) - return nil - }, - RequestValue: func(name, message string, _ bool) (s string, err error) { - defer func() { - if err != nil { - logger.Global.Warningf("could not read value for age-plugin-%s: %v", name, err) - } - }() - secret, err := term.ReadSecret(message) - if err != nil { - return "", err - } - return string(secret), nil - }, - Confirm: func(name, message, yes, no string) (choseYes bool, err error) { - defer func() { - if err != nil { - logger.Global.Warningf("could not read value for age-plugin-%s: %v", name, err) - } - }() - if no == "" { - message += fmt.Sprintf(" (press enter for %q)", yes) - _, err := term.ReadSecret(message) - if err != nil { - return false, err - } - return true, nil - } - message += fmt.Sprintf(" (press [1] for %q or [2] for %q)", yes, no) - for { - selection, err := term.ReadCharacter(message) - if err != nil { - return false, err - } - switch selection { - case '1': - return true, nil - case '2': - return false, nil - case '\x03': // CTRL-C - return false, errors.New("user cancelled prompt") - default: - logger.Global.Warningf("reading value for age-plugin-%s: invalid selection %q", name, selection) - } - } - }, - WaitTimer: func(name string) { - logger.Global.Printf("waiting on %s plugin...", name) - }, -} +var pluginTerminalUI = plugin.NewClientUI() func bufferTerminalInput(in io.Reader) (io.Reader, error) { buf := &bytes.Buffer{} diff --git a/plugin/client.go b/plugin/client.go index 051ec40b..8eccc554 100644 --- a/plugin/client.go +++ b/plugin/client.go @@ -9,6 +9,7 @@ package plugin import ( "bufio" + "errors" "fmt" "io" "math/rand" @@ -22,6 +23,8 @@ import ( "filippo.io/age" "filippo.io/age/internal/format" + "filippo.io/age/internal/logger" + "filippo.io/age/internal/term" ) type Recipient struct { @@ -321,6 +324,62 @@ type ClientUI struct { WaitTimer func(name string) } +func NewClientUI() *ClientUI { + return &ClientUI{ + DisplayMessage: func(name, message string) error { + logger.Global.Printf("%s plugin: %s", name, message) + return nil + }, + RequestValue: func(name, message string, _ bool) (s string, err error) { + defer func() { + if err != nil { + logger.Global.Warningf("could not read value for age-plugin-%s: %v", name, err) + } + }() + secret, err := term.ReadSecret(message) + if err != nil { + return "", err + } + return string(secret), nil + }, + Confirm: func(name, message, yes, no string) (choseYes bool, err error) { + defer func() { + if err != nil { + logger.Global.Warningf("could not read value for age-plugin-%s: %v", name, err) + } + }() + if no == "" { + message += fmt.Sprintf(" (press enter for %q)", yes) + _, err := term.ReadSecret(message) + if err != nil { + return false, err + } + return true, nil + } + message += fmt.Sprintf(" (press [1] for %q or [2] for %q)", yes, no) + for { + selection, err := term.ReadCharacter(message) + if err != nil { + return false, err + } + switch selection { + case '1': + return true, nil + case '2': + return false, nil + case '\x03': // CTRL-C + return false, errors.New("user cancelled prompt") + default: + logger.Global.Warningf("reading value for age-plugin-%s: invalid selection %q", name, selection) + } + } + }, + WaitTimer: func(name string) { + logger.Global.Printf("waiting on %s plugin...", name) + }, + } +} + func (c *ClientUI) handle(name string, conn *clientConnection, s *format.Stanza) (ok bool, err error) { switch s.Type { case "msg":