Commit dc5d2619 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer: Ui can return an error for Ask, returns one for interrupt

parent a73e71c3
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"log"
"time" "time"
) )
...@@ -27,7 +28,12 @@ func MultistepDebugFn(ui packer.Ui) multistep.DebugPauseFn { ...@@ -27,7 +28,12 @@ func MultistepDebugFn(ui packer.Ui) multistep.DebugPauseFn {
result := make(chan string, 1) result := make(chan string, 1)
go func() { go func() {
result <- ui.Ask(message) line, err := ui.Ask(message)
if err != nil {
log.Printf("Error asking for input: %s", err)
}
result <- line
}() }()
for { for {
......
...@@ -17,13 +17,9 @@ type UiServer struct { ...@@ -17,13 +17,9 @@ type UiServer struct {
ui packer.Ui ui packer.Ui
} }
func (u *Ui) Ask(query string) string { func (u *Ui) Ask(query string) (result string, err error) {
var result string err = u.client.Call("Ui.Ask", query, &result)
if err := u.client.Call("Ui.Ask", query, &result); err != nil { return
panic(err)
}
return result
} }
func (u *Ui) Error(message string) { func (u *Ui) Error(message string) {
...@@ -44,9 +40,9 @@ func (u *Ui) Say(message string) { ...@@ -44,9 +40,9 @@ func (u *Ui) Say(message string) {
} }
} }
func (u *UiServer) Ask(query string, reply *string) error { func (u *UiServer) Ask(query string, reply *string) (err error) {
*reply = u.ui.Ask(query) *reply, err = u.ui.Ask(query)
return nil return
} }
func (u *UiServer) Error(message *string, reply *interface{}) error { func (u *UiServer) Error(message *string, reply *interface{}) error {
......
...@@ -17,10 +17,10 @@ type testUi struct { ...@@ -17,10 +17,10 @@ type testUi struct {
sayMessage string sayMessage string
} }
func (u *testUi) Ask(query string) string { func (u *testUi) Ask(query string) (string, error) {
u.askCalled = true u.askCalled = true
u.askQuery = query u.askQuery = query
return "foo" return "foo", nil
} }
func (u *testUi) Error(message string) { func (u *testUi) Error(message string) {
...@@ -58,7 +58,8 @@ func TestUiRPC(t *testing.T) { ...@@ -58,7 +58,8 @@ func TestUiRPC(t *testing.T) {
uiClient := &Ui{client} uiClient := &Ui{client}
// Basic error and say tests // Basic error and say tests
result := uiClient.Ask("query") result, err := uiClient.Ask("query")
assert.Nil(err, "should not error")
assert.True(ui.askCalled, "ask should be called") assert.True(ui.askCalled, "ask should be called")
assert.Equal(ui.askQuery, "query", "should be correct") assert.Equal(ui.askQuery, "query", "should be correct")
assert.Equal(result, "foo", "should have correct result") assert.Equal(result, "foo", "should have correct result")
......
package packer package packer
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"log" "log"
...@@ -24,7 +25,7 @@ const ( ...@@ -24,7 +25,7 @@ const (
// world. This sort of control allows us to strictly control how output // world. This sort of control allows us to strictly control how output
// is formatted and various levels of output. // is formatted and various levels of output.
type Ui interface { type Ui interface {
Ask(string) string Ask(string) (string, error)
Say(string) Say(string)
Message(string) Message(string)
Error(string) Error(string)
...@@ -53,7 +54,7 @@ type ReaderWriterUi struct { ...@@ -53,7 +54,7 @@ type ReaderWriterUi struct {
l sync.Mutex l sync.Mutex
} }
func (u *ColoredUi) Ask(query string) string { func (u *ColoredUi) Ask(query string) (string, error) {
return u.Ui.Ask(u.colorize(query, u.Color, true)) return u.Ui.Ask(u.colorize(query, u.Color, true))
} }
...@@ -83,7 +84,7 @@ func (u *ColoredUi) colorize(message string, color UiColor, bold bool) string { ...@@ -83,7 +84,7 @@ func (u *ColoredUi) colorize(message string, color UiColor, bold bool) string {
return fmt.Sprintf("\033[%d;%d;40m%s\033[0m", attr, color, message) return fmt.Sprintf("\033[%d;%d;40m%s\033[0m", attr, color, message)
} }
func (u *PrefixedUi) Ask(query string) string { func (u *PrefixedUi) Ask(query string) (string, error) {
return u.Ui.Ask(fmt.Sprintf("%s: %s", u.SayPrefix, query)) return u.Ui.Ask(fmt.Sprintf("%s: %s", u.SayPrefix, query))
} }
...@@ -99,7 +100,7 @@ func (u *PrefixedUi) Error(message string) { ...@@ -99,7 +100,7 @@ func (u *PrefixedUi) Error(message string) {
u.Ui.Error(fmt.Sprintf("%s: %s", u.SayPrefix, message)) u.Ui.Error(fmt.Sprintf("%s: %s", u.SayPrefix, message))
} }
func (rw *ReaderWriterUi) Ask(query string) string { func (rw *ReaderWriterUi) Ask(query string) (string, error) {
rw.l.Lock() rw.l.Lock()
defer rw.l.Unlock() defer rw.l.Unlock()
...@@ -110,7 +111,7 @@ func (rw *ReaderWriterUi) Ask(query string) string { ...@@ -110,7 +111,7 @@ func (rw *ReaderWriterUi) Ask(query string) string {
log.Printf("ui: ask: %s", query) log.Printf("ui: ask: %s", query)
if query != "" { if query != "" {
if _, err := fmt.Fprint(rw.Writer, query+" "); err != nil { if _, err := fmt.Fprint(rw.Writer, query+" "); err != nil {
panic(err) return "", err
} }
} }
...@@ -124,18 +125,12 @@ func (rw *ReaderWriterUi) Ask(query string) string { ...@@ -124,18 +125,12 @@ func (rw *ReaderWriterUi) Ask(query string) string {
result <- line result <- line
}() }()
for {
select { select {
case line := <-result: case line := <-result:
return line return line, nil
case <-sigCh: case <-sigCh:
fmt.Fprint( return "", errors.New("interrupted")
rw.Writer,
"\nInterrupts are blocked while waiting for input. Press enter.")
}
} }
return ""
} }
func (rw *ReaderWriterUi) Say(message string) { func (rw *ReaderWriterUi) Say(message string) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment