command: better UI for showing completion of steps

This commit is contained in:
Mitchell Hashimoto 2014-07-26 21:20:31 -07:00
parent 7564a0a21c
commit 0f45ebbdc3
2 changed files with 66 additions and 7 deletions

View File

@ -72,12 +72,10 @@ func (c *ApplyCommand) Run(args []string) int {
// Plan if we haven't already
if !planned {
if refresh {
c.Ui.Output("Refreshing Terraform state prior to plan...\n")
if _, err := ctx.Refresh(); err != nil {
c.Ui.Error(fmt.Sprintf("Error refreshing state: %s", err))
return 1
}
c.Ui.Output("")
}
if _, err := ctx.Plan(nil); err != nil {

View File

@ -18,21 +18,48 @@ type UiHook struct {
Colorize *colorstring.Colorize
Ui cli.Ui
once sync.Once
ui cli.Ui
l sync.Mutex
once sync.Once
resources map[string]uiResourceOp
ui cli.Ui
}
type uiResourceOp byte
const (
uiResourceUnknown uiResourceOp = iota
uiResourceCreate
uiResourceModify
uiResourceDestroy
)
func (h *UiHook) PreApply(
id string,
s *terraform.ResourceState,
d *terraform.ResourceDiff) (terraform.HookAction, error) {
h.once.Do(h.init)
operation := "Modifying..."
op := uiResourceModify
if d.Destroy {
operation = "Destroying..."
op = uiResourceDestroy
} else if s.ID == "" {
op = uiResourceCreate
}
h.l.Lock()
h.resources[id] = op
h.l.Unlock()
var operation string
switch op {
case uiResourceModify:
operation = "Modifying..."
case uiResourceDestroy:
operation = "Destroying..."
case uiResourceCreate:
operation = "Creating..."
case uiResourceUnknown:
return terraform.HookActionContinue, nil
}
attrBuf := new(bytes.Buffer)
@ -85,6 +112,38 @@ func (h *UiHook) PreApply(
return terraform.HookActionContinue, nil
}
func (h *UiHook) PostApply(
id string,
s *terraform.ResourceState,
applyerr error) (terraform.HookAction, error) {
h.l.Lock()
op := h.resources[id]
delete(h.resources, id)
h.l.Unlock()
var msg string
switch op {
case uiResourceModify:
msg = "Modifications complete"
case uiResourceDestroy:
msg = "Destruction complete"
case uiResourceCreate:
msg = "Creation complete"
case uiResourceUnknown:
return terraform.HookActionContinue, nil
}
if applyerr != nil {
msg = fmt.Sprintf("Error: %s", applyerr)
}
h.ui.Output(h.Colorize.Color(fmt.Sprintf(
"[reset][bold]%s: %s[reset_bold]",
id, msg)))
return terraform.HookActionContinue, nil
}
func (h *UiHook) PreDiff(
id string, s *terraform.ResourceState) (terraform.HookAction, error) {
return terraform.HookActionContinue, nil
@ -95,7 +154,7 @@ func (h *UiHook) PreRefresh(
h.once.Do(h.init)
h.ui.Output(h.Colorize.Color(fmt.Sprintf(
"[reset][bold]%s: Refreshing (ID: %s)",
"[reset][bold]%s: Refreshing state... (ID: %s)",
id, s.ID)))
return terraform.HookActionContinue, nil
}
@ -105,6 +164,8 @@ func (h *UiHook) init() {
panic("colorize not given")
}
h.resources = make(map[string]uiResourceOp)
// Wrap the ui so that it is safe for concurrency regardless of the
// underlying reader/writer that is in place.
h.ui = &cli.ConcurrentUi{Ui: h.Ui}