Callers expect to be given an updated set of counts for how many of each
action were completed, which we'll achieve by having the terraform.Hook
implementation keep track of those and then announce them based on what
it collected.
We can't use the plan for this directly because terraform.Context.Plan
seems to modify the plan it's given during its work, and on success the
plan ends up being totally empty.
Previously we had the progress messages directly inlined as events of the
PlanStackChanges operation, but that means that there's no common
interface type for progress events across both the plan and apply phases,
making it hard for Go implementations to share marshaling code between
the two phases.
Now we'll use a new StackChangeProgress message type to contain all of
the progress message situations. This makes constructing and using the
progress messages a little more verbose -- an extra layer of message --
but means that we can write code that works generically with the
StackChangeProgress generated struct and thus share it between the two
phases, leading to less code overall.
As of this commit we don't yet have the apply phase generating any
progress messages, but we'll extend it in a subsequent commit now that
it's possible to share more of that event-generating code between the
two phases.
We want to report the result of component expansion to the client as
early as possible, so that it can prepare to receive any following
information for each instance. This message is critical when a
component's expansion expression evaluates to an empty set: without this
message's confirmation of this case, it will be unable to determine that
the component will receive no plans for any instances until the plan
completes.
We also want to report a roll-up of the resource changes upon completion
of each component's plan and apply operations, so that a client can
summarize the operation changes without performing the roll-up operation
on all received change events.
Expand the existing hooks to emit events throughout the planning
process, providing enough information for the Terraform Cloud UI to
render a live-updating representation of the plan. We also sketch out
the equivalent hooks for the apply operation.