Flip the summarization polarity

This change shows detailed output -- resources, their properties, and
a full articulation of plan steps -- and permits summarization with the
--summary (or -s) flag.
This commit is contained in:
joeduffy 2017-02-25 07:55:22 -08:00
parent 32379da4f5
commit 14762df98b
4 changed files with 41 additions and 41 deletions

View file

@ -7,8 +7,8 @@ import (
) )
func newCreateCmd() *cobra.Command { func newCreateCmd() *cobra.Command {
var detail bool
var dryRun bool var dryRun bool
var summary bool
var output string var output string
var cmd = &cobra.Command{ var cmd = &cobra.Command{
Use: "create [blueprint] [-- [args]]", Use: "create [blueprint] [-- [args]]",
@ -24,20 +24,20 @@ func newCreateCmd() *cobra.Command {
"a path to a Nut elsewhere can be provided as the [blueprint] argument.", "a path to a Nut elsewhere can be provided as the [blueprint] argument.",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
apply(cmd, args, "", applyOptions{ apply(cmd, args, "", applyOptions{
Delete: false, Delete: false,
Detail: detail, DryRun: dryRun,
DryRun: dryRun, Summary: summary,
Output: output, Output: output,
}) })
}, },
} }
cmd.PersistentFlags().BoolVarP(
&detail, "all", "a", false,
"Display detailed output during the application of changes")
cmd.PersistentFlags().BoolVarP( cmd.PersistentFlags().BoolVarP(
&dryRun, "dry-run", "n", false, &dryRun, "dry-run", "n", false,
"Don't actually create resources; just print out the planned creations") "Don't actually create resources; just print out the planned creations")
cmd.PersistentFlags().BoolVarP(
&summary, "summary", "s", false,
"Only display summarization of resources and plan operations")
cmd.PersistentFlags().StringVarP( cmd.PersistentFlags().StringVarP(
&output, "output", "o", "", &output, "output", "o", "",
"Serialize the resulting snapshot to a specific file, instead of the standard location") "Serialize the resulting snapshot to a specific file, instead of the standard location")

View file

@ -7,8 +7,8 @@ import (
) )
func newDeleteCmd() *cobra.Command { func newDeleteCmd() *cobra.Command {
var detail bool
var dryRun bool var dryRun bool
var summary bool
var cmd = &cobra.Command{ var cmd = &cobra.Command{
Use: "delete [snapshot]", Use: "delete [snapshot]",
Short: "Delete an existing environment and its resources", Short: "Delete an existing environment and its resources",
@ -18,19 +18,19 @@ func newDeleteCmd() *cobra.Command {
"existing snapshot file. After running to completion, this environment will be gone.", "existing snapshot file. After running to completion, this environment will be gone.",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
applyExisting(cmd, args, applyOptions{ applyExisting(cmd, args, applyOptions{
Delete: true, Delete: true,
Detail: detail, DryRun: dryRun,
DryRun: dryRun, Summary: summary,
}) })
}, },
} }
cmd.PersistentFlags().BoolVarP(
&detail, "all", "a", false,
"Display detailed output during the application of changes")
cmd.PersistentFlags().BoolVarP( cmd.PersistentFlags().BoolVarP(
&dryRun, "dry-run", "n", false, &dryRun, "dry-run", "n", false,
"Don't actually delete resources; just print out the planned deletions") "Don't actually delete resources; just print out the planned deletions")
cmd.PersistentFlags().BoolVarP(
&summary, "summary", "s", false,
"Only display summarization of resources and plan operations")
return cmd return cmd
} }

View file

@ -165,14 +165,14 @@ func apply(cmd *cobra.Command, args []string, existing string, opts applyOptions
} else if opts.DryRun { } else if opts.DryRun {
// If no output file was requested, or "-", print to stdout; else write to that file. // If no output file was requested, or "-", print to stdout; else write to that file.
if opts.Output == "" || opts.Output == "-" { if opts.Output == "" || opts.Output == "-" {
printPlan(result.Plan, opts.Detail) printPlan(result.Plan, opts.Summary)
} else { } else {
saveSnapshot(result.Snap, opts.Output) saveSnapshot(result.Snap, opts.Output)
} }
} else { } else {
// Create an object to track progress and perform the actual operations. // Create an object to track progress and perform the actual operations.
start := time.Now() start := time.Now()
progress := newProgress(opts.Detail) progress := newProgress(opts.Summary)
if err, _, _ := result.Plan.Apply(progress); err != nil { if err, _, _ := result.Plan.Apply(progress); err != nil {
// TODO: we want richer diagnostics in the event that a plan apply fails. For instance, we want to // TODO: we want richer diagnostics in the event that a plan apply fails. For instance, we want to
// know precisely what step failed, we want to know whether it was catastrophic, etc. We also // know precisely what step failed, we want to know whether it was catastrophic, etc. We also
@ -322,10 +322,10 @@ func saveSnapshot(snap resource.Snapshot, file string) {
} }
type applyOptions struct { type applyOptions struct {
Delete bool // true if we are deleting resources. Delete bool // true if we are deleting resources.
DryRun bool // true if we should just print the plan without performing it. DryRun bool // true if we should just print the plan without performing it.
Detail bool // true if we should print detailed information about resources and operations. Summary bool // true if we should only summarize resources and operations.
Output string // the place to store the output, if any. Output string // the place to store the output, if any.
} }
// applyProgress pretty-prints the plan application process as it goes. // applyProgress pretty-prints the plan application process as it goes.
@ -333,14 +333,14 @@ type applyProgress struct {
Steps int Steps int
Ops map[resource.StepOp]int Ops map[resource.StepOp]int
MaybeCorrupt bool MaybeCorrupt bool
Detail bool Summary bool
} }
func newProgress(detailed bool) *applyProgress { func newProgress(summary bool) *applyProgress {
return &applyProgress{ return &applyProgress{
Steps: 0, Steps: 0,
Ops: make(map[resource.StepOp]int), Ops: make(map[resource.StepOp]int),
Detail: detailed, Summary: summary,
} }
} }
@ -349,7 +349,7 @@ func (prog *applyProgress) Before(step resource.Step) {
var b bytes.Buffer var b bytes.Buffer
stepnum := prog.Steps + 1 stepnum := prog.Steps + 1
b.WriteString(fmt.Sprintf("Applying step #%v [%v]\n", stepnum, step.Op())) b.WriteString(fmt.Sprintf("Applying step #%v [%v]\n", stepnum, step.Op()))
printStep(&b, step, !prog.Detail, " ") printStep(&b, step, prog.Summary, " ")
s := colors.Colorize(b.String()) s := colors.Colorize(b.String())
fmt.Printf(s) fmt.Printf(s)
} }
@ -382,14 +382,14 @@ func (prog *applyProgress) After(step resource.Step, err error, state resource.R
} }
} }
func printPlan(plan resource.Plan, detailed bool) { func printPlan(plan resource.Plan, summary bool) {
// Now walk the plan's steps and and pretty-print them out. // Now walk the plan's steps and and pretty-print them out.
step := plan.Steps() step := plan.Steps()
for step != nil { for step != nil {
var b bytes.Buffer var b bytes.Buffer
// Print this step information (resource and all its properties). // Print this step information (resource and all its properties).
printStep(&b, step, detailed, "") printStep(&b, step, summary, "")
// Now go ahead and emit the output to the console, and move on to the next step in the plan. // Now go ahead and emit the output to the console, and move on to the next step in the plan.
// TODO: it would be nice if, in the output, we showed the dependencies a la `git log --graph`. // TODO: it would be nice if, in the output, we showed the dependencies a la `git log --graph`.
@ -423,14 +423,14 @@ func opSuffix(op resource.StepOp) string {
const resourceDetailsIndent = " " // 4 spaces, plus space for "+ ", "- ", and " " leaders const resourceDetailsIndent = " " // 4 spaces, plus space for "+ ", "- ", and " " leaders
func printStep(b *bytes.Buffer, step resource.Step, details bool, indent string) { func printStep(b *bytes.Buffer, step resource.Step, summary bool, indent string) {
// First print out the operation's prefix. // First print out the operation's prefix.
b.WriteString(opPrefix(step.Op())) b.WriteString(opPrefix(step.Op()))
// Next print the resource moniker, properties, etc. // Next print the resource moniker, properties, etc.
printResourceHeader(b, step.Old(), step.New(), indent) printResourceHeader(b, step.Old(), step.New(), indent)
b.WriteString(opSuffix(step.Op())) b.WriteString(opSuffix(step.Op()))
printResourceProperties(b, step.Old(), step.New(), details, indent) printResourceProperties(b, step.Old(), step.New(), summary, indent)
// Finally make sure to reset the color. // Finally make sure to reset the color.
b.WriteString(colors.Reset) b.WriteString(colors.Reset)
@ -449,7 +449,7 @@ func printResourceHeader(b *bytes.Buffer, old resource.Resource, new resource.Re
} }
func printResourceProperties(b *bytes.Buffer, old resource.Resource, new resource.Resource, func printResourceProperties(b *bytes.Buffer, old resource.Resource, new resource.Resource,
details bool, indent string) { summary bool, indent string) {
indent += resourceDetailsIndent indent += resourceDetailsIndent
// Print out the moniker and, if present, the ID, as "pseudo-properties". // Print out the moniker and, if present, the ID, as "pseudo-properties".
@ -467,7 +467,7 @@ func printResourceProperties(b *bytes.Buffer, old resource.Resource, new resourc
} }
b.WriteString(fmt.Sprintf("%s[mk=%s]\n", indent, string(moniker))) b.WriteString(fmt.Sprintf("%s[mk=%s]\n", indent, string(moniker)))
if details { if !summary {
// Print all of the properties associated with this resource. // Print all of the properties associated with this resource.
if old == nil && new != nil { if old == nil && new != nil {
printObject(b, new.Properties(), indent) printObject(b, new.Properties(), indent)

View file

@ -7,8 +7,8 @@ import (
) )
func newUpdateCmd() *cobra.Command { func newUpdateCmd() *cobra.Command {
var detail bool
var dryRun bool var dryRun bool
var summary bool
var output string var output string
var cmd = &cobra.Command{ var cmd = &cobra.Command{
Use: "update [snapshot] [blueprint] [-- [args]]", Use: "update [snapshot] [blueprint] [-- [args]]",
@ -26,20 +26,20 @@ func newUpdateCmd() *cobra.Command {
"a path to a Nut elsewhere can be provided as the [blueprint] argument.", "a path to a Nut elsewhere can be provided as the [blueprint] argument.",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
applyExisting(cmd, args, applyOptions{ applyExisting(cmd, args, applyOptions{
Delete: false, Delete: false,
Detail: detail, DryRun: dryRun,
DryRun: dryRun, Summary: summary,
Output: output, Output: output,
}) })
}, },
} }
cmd.PersistentFlags().BoolVarP(
&detail, "all", "a", false,
"Display all detailed output during the application of changes")
cmd.PersistentFlags().BoolVarP( cmd.PersistentFlags().BoolVarP(
&dryRun, "dry-run", "n", false, &dryRun, "dry-run", "n", false,
"Don't actually update resources; just print out the planned updates") "Don't actually update resources; just print out the planned updates")
cmd.PersistentFlags().BoolVarP(
&summary, "summary", "s", false,
"Only display summarization of resources and plan operations")
cmd.PersistentFlags().StringVarP( cmd.PersistentFlags().StringVarP(
&output, "output", "o", "", &output, "output", "o", "",
"Serialize the resulting snapshot to a specific file, instead of overwriting the existing one") "Serialize the resulting snapshot to a specific file, instead of overwriting the existing one")