github.com/ezbercih/terraform@v0.1.1-0.20140729011846-3c33865e0839/command/format_plan.go (about)

     1  package command
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/hashicorp/terraform/terraform"
    10  	"github.com/mitchellh/colorstring"
    11  )
    12  
    13  // FormatPlan takes a plan and returns a
    14  func FormatPlan(p *terraform.Plan, c *colorstring.Colorize) string {
    15  	if p.Diff == nil || p.Diff.Empty() {
    16  		return "This plan does nothing."
    17  	}
    18  
    19  	if c == nil {
    20  		c = &colorstring.Colorize{
    21  			Colors: colorstring.DefaultColors,
    22  			Reset:  false,
    23  		}
    24  	}
    25  
    26  	buf := new(bytes.Buffer)
    27  
    28  	// We want to output the resources in sorted order to make things
    29  	// easier to scan through, so get all the resource names and sort them.
    30  	names := make([]string, 0, len(p.Diff.Resources))
    31  	for name, _ := range p.Diff.Resources {
    32  		names = append(names, name)
    33  	}
    34  	sort.Strings(names)
    35  
    36  	// Go through each sorted name and start building the output
    37  	for _, name := range names {
    38  		rdiff := p.Diff.Resources[name]
    39  
    40  		// Determine the color for the text (green for adding, yellow
    41  		// for change, red for delete), and symbol, and output the
    42  		// resource header.
    43  		color := "yellow"
    44  		symbol := "~"
    45  		if rdiff.RequiresNew() && rdiff.Destroy {
    46  			color = "green"
    47  			symbol = "-/+"
    48  		} else if rdiff.RequiresNew() {
    49  			color = "green"
    50  			symbol = "+"
    51  		} else if rdiff.Destroy {
    52  			color = "red"
    53  			symbol = "-"
    54  		}
    55  		buf.WriteString(c.Color(fmt.Sprintf(
    56  			"[%s]%s %s\n",
    57  			color, symbol, name)))
    58  
    59  		// Get all the attributes that are changing, and sort them. Also
    60  		// determine the longest key so that we can align them all.
    61  		keyLen := 0
    62  		keys := make([]string, 0, len(rdiff.Attributes))
    63  		for key, _ := range rdiff.Attributes {
    64  			// Skip the ID since we do that specially
    65  			if key == "id" {
    66  				continue
    67  			}
    68  
    69  			keys = append(keys, key)
    70  			if len(key) > keyLen {
    71  				keyLen = len(key)
    72  			}
    73  		}
    74  		sort.Strings(keys)
    75  
    76  		// Go through and output each attribute
    77  		for _, attrK := range keys {
    78  			attrDiff := rdiff.Attributes[attrK]
    79  
    80  			v := attrDiff.New
    81  			if attrDiff.NewComputed {
    82  				v = "<computed>"
    83  			}
    84  
    85  			newResource := ""
    86  			if attrDiff.RequiresNew && rdiff.Destroy {
    87  				newResource = " (forces new resource)"
    88  			}
    89  
    90  			buf.WriteString(fmt.Sprintf(
    91  				"    %s:%s %#v => %#v%s\n",
    92  				attrK,
    93  				strings.Repeat(" ", keyLen-len(attrK)),
    94  				attrDiff.Old,
    95  				v,
    96  				newResource))
    97  		}
    98  
    99  		// Write the reset color so we don't overload the user's terminal
   100  		buf.WriteString(c.Color("[reset]\n"))
   101  	}
   102  
   103  	return strings.TrimSpace(buf.String())
   104  }