Merge pull request #4479 from ashb/ui-ask-whole-line
Use bufio.Scanner in BasicUi.Ask so we can read whole lines
This commit is contained in:
commit
866e06195b
14
packer/ui.go
14
packer/ui.go
|
@ -1,6 +1,7 @@
|
||||||
package packer
|
package packer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -64,6 +65,7 @@ type BasicUi struct {
|
||||||
ErrorWriter io.Writer
|
ErrorWriter io.Writer
|
||||||
l sync.Mutex
|
l sync.Mutex
|
||||||
interrupted bool
|
interrupted bool
|
||||||
|
scanner *bufio.Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
// MachineReadableUi is a UI that only outputs machine-readable output
|
// MachineReadableUi is a UI that only outputs machine-readable output
|
||||||
|
@ -174,6 +176,9 @@ func (rw *BasicUi) Ask(query string) (string, error) {
|
||||||
return "", errors.New("interrupted")
|
return "", errors.New("interrupted")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rw.scanner == nil {
|
||||||
|
rw.scanner = bufio.NewScanner(rw.Reader)
|
||||||
|
}
|
||||||
sigCh := make(chan os.Signal, 1)
|
sigCh := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigCh, os.Interrupt)
|
signal.Notify(sigCh, os.Interrupt)
|
||||||
defer signal.Stop(sigCh)
|
defer signal.Stop(sigCh)
|
||||||
|
@ -188,10 +193,13 @@ func (rw *BasicUi) Ask(query string) (string, error) {
|
||||||
result := make(chan string, 1)
|
result := make(chan string, 1)
|
||||||
go func() {
|
go func() {
|
||||||
var line string
|
var line string
|
||||||
if _, err := fmt.Fscanln(rw.Reader, &line); err != nil {
|
if rw.scanner.Scan() {
|
||||||
log.Printf("ui: scan err: %s", err)
|
line = rw.scanner.Text()
|
||||||
|
}
|
||||||
|
if err := rw.scanner.Err(); err != nil {
|
||||||
|
log.Printf("ui: scan err: %s", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result <- line
|
result <- line
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,12 @@ func readWriter(ui *BasicUi) (result string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset the input Reader than add some input to it.
|
||||||
|
func writeReader(ui *BasicUi, input string) {
|
||||||
|
buffer := ui.Reader.(*bytes.Buffer)
|
||||||
|
buffer.WriteString(input)
|
||||||
|
}
|
||||||
|
|
||||||
func readErrorWriter(ui *BasicUi) (result string) {
|
func readErrorWriter(ui *BasicUi) (result string) {
|
||||||
buffer := ui.ErrorWriter.(*bytes.Buffer)
|
buffer := ui.ErrorWriter.(*bytes.Buffer)
|
||||||
result = buffer.String()
|
result = buffer.String()
|
||||||
|
@ -192,6 +198,45 @@ func TestBasicUi_Say(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBasicUi_Ask(t *testing.T) {
|
||||||
|
|
||||||
|
var actual, expected string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
var testCases = []struct {
|
||||||
|
Prompt, Input, Answer string
|
||||||
|
}{
|
||||||
|
{"[c]ontinue or [a]bort", "c\n", "c"},
|
||||||
|
{"[c]ontinue or [a]bort", "c", "c"},
|
||||||
|
// Empty input shouldn't give an error
|
||||||
|
{"Name", "Joe Bloggs\n", "Joe Bloggs"},
|
||||||
|
{"Name", "Joe Bloggs", "Joe Bloggs"},
|
||||||
|
{"Name", "\n", ""},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
// Because of the internal bufio we can't eaily reset the input, so create a new one each time
|
||||||
|
bufferUi := testUi()
|
||||||
|
writeReader(bufferUi, testCase.Input)
|
||||||
|
|
||||||
|
actual, err = bufferUi.Ask(testCase.Prompt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if actual != testCase.Answer {
|
||||||
|
t.Fatalf("bad answer: %#v", actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual = readWriter(bufferUi)
|
||||||
|
expected = testCase.Prompt + " "
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad prompt: %#v", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestMachineReadableUi_ImplUi(t *testing.T) {
|
func TestMachineReadableUi_ImplUi(t *testing.T) {
|
||||||
var raw interface{}
|
var raw interface{}
|
||||||
raw = &MachineReadableUi{}
|
raw = &MachineReadableUi{}
|
||||||
|
|
Loading…
Reference in New Issue