Skip to content

Commit 60d3cc8

Browse files
jwasingerholiman
andauthored
cmd/puppeth: use geth's prompt to read input (#23718)
* cmd/puppeth: use geth's prompt to read input * remove wizard.in * cmd/puppeth: fix compilation errors * reset prompt (don't exit) on receiving ctrl-c * make promptInput spin until the user enters a value or interrupts (ctrl-d) * make promptInput use parameter Co-authored-by: Martin Holst Swende <[email protected]>
1 parent c36f8fe commit 60d3cc8

File tree

2 files changed

+33
-90
lines changed

2 files changed

+33
-90
lines changed

cmd/puppeth/wizard.go

Lines changed: 33 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package main
1818

1919
import (
20-
"bufio"
2120
"encoding/json"
2221
"fmt"
2322
"io/ioutil"
@@ -32,8 +31,10 @@ import (
3231
"sync"
3332

3433
"github.com/ethereum/go-ethereum/common"
34+
"github.com/ethereum/go-ethereum/console/prompt"
3535
"github.com/ethereum/go-ethereum/core"
3636
"github.com/ethereum/go-ethereum/log"
37+
"github.com/peterh/liner"
3738
"golang.org/x/crypto/ssh/terminal"
3839
)
3940

@@ -76,29 +77,35 @@ type wizard struct {
7677
servers map[string]*sshClient // SSH connections to servers to administer
7778
services map[string][]string // Ethereum services known to be running on servers
7879

79-
in *bufio.Reader // Wrapper around stdin to allow reading user input
80-
lock sync.Mutex // Lock to protect configs during concurrent service discovery
80+
lock sync.Mutex // Lock to protect configs during concurrent service discovery
81+
}
82+
83+
// prompts the user for input with the given prompt string. Returns when a value is entered.
84+
// Causes the wizard to exit if ctrl-d is pressed
85+
func promptInput(p string) string {
86+
for {
87+
text, err := prompt.Stdin.PromptInput(p)
88+
if err != nil {
89+
if err != liner.ErrPromptAborted {
90+
log.Crit("Failed to read user input", "err", err)
91+
}
92+
} else {
93+
return text
94+
}
95+
}
8196
}
8297

8398
// read reads a single line from stdin, trimming if from spaces.
8499
func (w *wizard) read() string {
85-
fmt.Printf("> ")
86-
text, err := w.in.ReadString('\n')
87-
if err != nil {
88-
log.Crit("Failed to read user input", "err", err)
89-
}
100+
text := promptInput("> ")
90101
return strings.TrimSpace(text)
91102
}
92103

93104
// readString reads a single line from stdin, trimming if from spaces, enforcing
94105
// non-emptyness.
95106
func (w *wizard) readString() string {
96107
for {
97-
fmt.Printf("> ")
98-
text, err := w.in.ReadString('\n')
99-
if err != nil {
100-
log.Crit("Failed to read user input", "err", err)
101-
}
108+
text := promptInput("> ")
102109
if text = strings.TrimSpace(text); text != "" {
103110
return text
104111
}
@@ -108,11 +115,7 @@ func (w *wizard) readString() string {
108115
// readDefaultString reads a single line from stdin, trimming if from spaces. If
109116
// an empty line is entered, the default value is returned.
110117
func (w *wizard) readDefaultString(def string) string {
111-
fmt.Printf("> ")
112-
text, err := w.in.ReadString('\n')
113-
if err != nil {
114-
log.Crit("Failed to read user input", "err", err)
115-
}
118+
text := promptInput("> ")
116119
if text = strings.TrimSpace(text); text != "" {
117120
return text
118121
}
@@ -124,11 +127,7 @@ func (w *wizard) readDefaultString(def string) string {
124127
// value is returned.
125128
func (w *wizard) readDefaultYesNo(def bool) bool {
126129
for {
127-
fmt.Printf("> ")
128-
text, err := w.in.ReadString('\n')
129-
if err != nil {
130-
log.Crit("Failed to read user input", "err", err)
131-
}
130+
text := promptInput("> ")
132131
if text = strings.ToLower(strings.TrimSpace(text)); text == "" {
133132
return def
134133
}
@@ -146,11 +145,7 @@ func (w *wizard) readDefaultYesNo(def bool) bool {
146145
// interpret it as a URL (http, https or file).
147146
func (w *wizard) readURL() *url.URL {
148147
for {
149-
fmt.Printf("> ")
150-
text, err := w.in.ReadString('\n')
151-
if err != nil {
152-
log.Crit("Failed to read user input", "err", err)
153-
}
148+
text := promptInput("> ")
154149
uri, err := url.Parse(strings.TrimSpace(text))
155150
if err != nil {
156151
log.Error("Invalid input, expected URL", "err", err)
@@ -164,11 +159,7 @@ func (w *wizard) readURL() *url.URL {
164159
// to parse into an integer.
165160
func (w *wizard) readInt() int {
166161
for {
167-
fmt.Printf("> ")
168-
text, err := w.in.ReadString('\n')
169-
if err != nil {
170-
log.Crit("Failed to read user input", "err", err)
171-
}
162+
text := promptInput("> ")
172163
if text = strings.TrimSpace(text); text == "" {
173164
continue
174165
}
@@ -186,11 +177,7 @@ func (w *wizard) readInt() int {
186177
// returned.
187178
func (w *wizard) readDefaultInt(def int) int {
188179
for {
189-
fmt.Printf("> ")
190-
text, err := w.in.ReadString('\n')
191-
if err != nil {
192-
log.Crit("Failed to read user input", "err", err)
193-
}
180+
text := promptInput("> ")
194181
if text = strings.TrimSpace(text); text == "" {
195182
return def
196183
}
@@ -208,11 +195,7 @@ func (w *wizard) readDefaultInt(def int) int {
208195
// default value is returned.
209196
func (w *wizard) readDefaultBigInt(def *big.Int) *big.Int {
210197
for {
211-
fmt.Printf("> ")
212-
text, err := w.in.ReadString('\n')
213-
if err != nil {
214-
log.Crit("Failed to read user input", "err", err)
215-
}
198+
text := promptInput("> ")
216199
if text = strings.TrimSpace(text); text == "" {
217200
return def
218201
}
@@ -225,38 +208,11 @@ func (w *wizard) readDefaultBigInt(def *big.Int) *big.Int {
225208
}
226209
}
227210

228-
/*
229-
// readFloat reads a single line from stdin, trimming if from spaces, enforcing it
230-
// to parse into a float.
231-
func (w *wizard) readFloat() float64 {
232-
for {
233-
fmt.Printf("> ")
234-
text, err := w.in.ReadString('\n')
235-
if err != nil {
236-
log.Crit("Failed to read user input", "err", err)
237-
}
238-
if text = strings.TrimSpace(text); text == "" {
239-
continue
240-
}
241-
val, err := strconv.ParseFloat(strings.TrimSpace(text), 64)
242-
if err != nil {
243-
log.Error("Invalid input, expected float", "err", err)
244-
continue
245-
}
246-
return val
247-
}
248-
}
249-
*/
250-
251211
// readDefaultFloat reads a single line from stdin, trimming if from spaces, enforcing
252212
// it to parse into a float. If an empty line is entered, the default value is returned.
253213
func (w *wizard) readDefaultFloat(def float64) float64 {
254214
for {
255-
fmt.Printf("> ")
256-
text, err := w.in.ReadString('\n')
257-
if err != nil {
258-
log.Crit("Failed to read user input", "err", err)
259-
}
215+
text := promptInput("> ")
260216
if text = strings.TrimSpace(text); text == "" {
261217
return def
262218
}
@@ -285,12 +241,7 @@ func (w *wizard) readPassword() string {
285241
// it to an Ethereum address.
286242
func (w *wizard) readAddress() *common.Address {
287243
for {
288-
// Read the address from the user
289-
fmt.Printf("> 0x")
290-
text, err := w.in.ReadString('\n')
291-
if err != nil {
292-
log.Crit("Failed to read user input", "err", err)
293-
}
244+
text := promptInput("> 0x")
294245
if text = strings.TrimSpace(text); text == "" {
295246
return nil
296247
}
@@ -311,11 +262,7 @@ func (w *wizard) readAddress() *common.Address {
311262
func (w *wizard) readDefaultAddress(def common.Address) common.Address {
312263
for {
313264
// Read the address from the user
314-
fmt.Printf("> 0x")
315-
text, err := w.in.ReadString('\n')
316-
if err != nil {
317-
log.Crit("Failed to read user input", "err", err)
318-
}
265+
text := promptInput("> 0x")
319266
if text = strings.TrimSpace(text); text == "" {
320267
return def
321268
}
@@ -334,8 +281,9 @@ func (w *wizard) readJSON() string {
334281
var blob json.RawMessage
335282

336283
for {
337-
fmt.Printf("> ")
338-
if err := json.NewDecoder(w.in).Decode(&blob); err != nil {
284+
text := promptInput("> ")
285+
reader := strings.NewReader(text)
286+
if err := json.NewDecoder(reader).Decode(&blob); err != nil {
339287
log.Error("Invalid JSON, please try again", "err", err)
340288
continue
341289
}
@@ -351,10 +299,7 @@ func (w *wizard) readIPAddress() string {
351299
for {
352300
// Read the IP address from the user
353301
fmt.Printf("> ")
354-
text, err := w.in.ReadString('\n')
355-
if err != nil {
356-
log.Crit("Failed to read user input", "err", err)
357-
}
302+
text := promptInput("> ")
358303
if text = strings.TrimSpace(text); text == "" {
359304
return ""
360305
}

cmd/puppeth/wizard_intro.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package main
1818

1919
import (
20-
"bufio"
2120
"encoding/json"
2221
"fmt"
2322
"io/ioutil"
@@ -38,7 +37,6 @@ func makeWizard(network string) *wizard {
3837
},
3938
servers: make(map[string]*sshClient),
4039
services: make(map[string][]string),
41-
in: bufio.NewReader(os.Stdin),
4240
}
4341
}
4442

0 commit comments

Comments
 (0)