command/apply: improved output, still not done

This commit is contained in:
Mitchell Hashimoto 2014-07-12 17:03:55 -07:00
parent e0d3098d50
commit c615afc097
3 changed files with 67 additions and 4 deletions

View File

@ -71,6 +71,7 @@ func (c *ApplyCommand) Run(args []string) int {
return 1
}
// Start the apply in a goroutine so that we can be interrupted.
var state *terraform.State
var applyErr error
doneCh := make(chan struct{})
@ -79,6 +80,8 @@ func (c *ApplyCommand) Run(args []string) int {
state, applyErr = ctx.Apply()
}()
// Wait for the apply to finish or for us to be interrupted so
// we can handle it properly.
err = nil
select {
case <-c.ShutdownCh:

View File

@ -81,7 +81,7 @@ func FormatPlan(p *terraform.Plan, c *colorstring.Colorize) string {
}
buf.WriteString(fmt.Sprintf(
" %s:%s %#v => %#v%s\n",
" %s:%s %#v => %#v%s\n",
attrK,
strings.Repeat(" ", keyLen-len(attrK)),
attrDiff.Old,

View File

@ -1,17 +1,22 @@
package command
import (
"bytes"
"fmt"
"sort"
"strings"
"sync"
"github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/cli"
"github.com/mitchellh/colorstring"
)
type UiHook struct {
terraform.NilHook
Ui cli.Ui
Colorize *colorstring.Colorize
Ui cli.Ui
once sync.Once
ui cli.Ui
@ -23,7 +28,55 @@ func (h *UiHook) PreApply(
d *terraform.ResourceDiff) (terraform.HookAction, error) {
h.once.Do(h.init)
h.ui.Output(fmt.Sprintf("%s: Applying...", id))
operation := "Modifying..."
if d.Destroy {
operation = "Destroying..."
} else if s.ID == "" {
operation = "Creating..."
}
attrBuf := new(bytes.Buffer)
// Get all the attributes that are changing, and sort them. Also
// determine the longest key so that we can align them all.
keyLen := 0
keys := make([]string, 0, len(d.Attributes))
for key, _ := range d.Attributes {
// Skip the ID since we do that specially
if key == "id" {
continue
}
keys = append(keys, key)
if len(key) > keyLen {
keyLen = len(key)
}
}
sort.Strings(keys)
// Go through and output each attribute
for _, attrK := range keys {
attrDiff := d.Attributes[attrK]
v := attrDiff.New
if attrDiff.NewComputed {
v = "<computed>"
}
attrBuf.WriteString(fmt.Sprintf(
" %s:%s %#v => %#v\n",
attrK,
strings.Repeat(" ", keyLen-len(attrK)),
attrDiff.Old,
v))
}
h.ui.Output(h.Colorize.Color(fmt.Sprintf(
"[bold]%s: %s[reset_bold]\n %s",
id,
operation,
strings.TrimSpace(attrBuf.String()))))
return terraform.HookActionContinue, nil
}
@ -36,11 +89,18 @@ func (h *UiHook) PreRefresh(
id string, s *terraform.ResourceState) (terraform.HookAction, error) {
h.once.Do(h.init)
h.ui.Output(fmt.Sprintf("%s: Refreshing state (ID: %s)", id, s.ID))
//h.ui.Output(fmt.Sprintf("%s: Refreshing state (ID: %s)", id, s.ID))
return terraform.HookActionContinue, nil
}
func (h *UiHook) init() {
if h.Colorize == nil {
h.Colorize = &colorstring.Colorize{
Colors: colorstring.DefaultColors,
Reset: true,
}
}
// 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}