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:
parent
32379da4f5
commit
14762df98b
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue