[cloud] refactor integration context and add code documentation
This commit is contained in:
parent
791c36c504
commit
0b8bb29a61
|
@ -355,7 +355,13 @@ in order to capture the filesystem context the remote workspace expects:
|
||||||
|
|
||||||
// Await pre-apply run tasks
|
// Await pre-apply run tasks
|
||||||
if len(r.TaskStage) > 0 {
|
if len(r.TaskStage) > 0 {
|
||||||
context := NewIntegrationContext(stopCtx, cancelCtx, b, op, r)
|
context := &IntegrationContext{
|
||||||
|
B: b,
|
||||||
|
StopContext: stopCtx,
|
||||||
|
CancelContext: cancelCtx,
|
||||||
|
Op: op,
|
||||||
|
Run: r,
|
||||||
|
}
|
||||||
|
|
||||||
if stageID := getTaskStageIDByName(r.TaskStage, "pre_apply"); stageID != nil {
|
if stageID := getTaskStageIDByName(r.TaskStage, "pre_apply"); stageID != nil {
|
||||||
err = b.runTasks(context, context.BeginOutput("Run Tasks (pre-apply)"), *stageID)
|
err = b.runTasks(context, context.BeginOutput("Run Tasks (pre-apply)"), *stageID)
|
||||||
|
|
|
@ -49,7 +49,6 @@ func summarizeTaskResults(taskResults []*tfe.TaskResult) *taskResultSummary {
|
||||||
|
|
||||||
func (b *Cloud) runTasksWithTaskResults(context *IntegrationContext, output IntegrationOutputWriter, fetchTaskStage taskStageReadFunc) error {
|
func (b *Cloud) runTasksWithTaskResults(context *IntegrationContext, output IntegrationOutputWriter, fetchTaskStage taskStageReadFunc) error {
|
||||||
return context.Poll(func(i int) (bool, error) {
|
return context.Poll(func(i int) (bool, error) {
|
||||||
// TODO: get the stage that corresponds to an argument passed to this function
|
|
||||||
stage, err := fetchTaskStage(b, context.StopContext)
|
stage, err := fetchTaskStage(b, context.StopContext)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -132,7 +132,7 @@ func TestCloud_runTasksWithTaskResults(t *testing.T) {
|
||||||
|
|
||||||
for caseName, c := range cases {
|
for caseName, c := range cases {
|
||||||
c.writer.output.Reset()
|
c.writer.output.Reset()
|
||||||
err := b.runTasksWithTaskResults(c.writer.ctx, c.writer, func(b *Cloud, stopCtx context.Context) (*tfe.TaskStage, error) {
|
err := b.runTasksWithTaskResults(c.context, writer, func(b *Cloud, stopCtx context.Context) (*tfe.TaskStage, error) {
|
||||||
return &tfe.TaskStage{
|
return &tfe.TaskStage{
|
||||||
TaskResults: c.taskResults,
|
TaskResults: c.taskResults,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -8,8 +8,11 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/go-tfe"
|
"github.com/hashicorp/go-tfe"
|
||||||
"github.com/hashicorp/terraform/internal/backend"
|
"github.com/hashicorp/terraform/internal/backend"
|
||||||
|
"github.com/mitchellh/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// IntegrationOutputWriter is an interface used to to write output tailored for
|
||||||
|
// Terraform Cloud integrations
|
||||||
type IntegrationOutputWriter interface {
|
type IntegrationOutputWriter interface {
|
||||||
End()
|
End()
|
||||||
OutputElapsed(message string, maxMessage int)
|
OutputElapsed(message string, maxMessage int)
|
||||||
|
@ -17,8 +20,8 @@ type IntegrationOutputWriter interface {
|
||||||
SubOutput(str string)
|
SubOutput(str string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IntegrationContext is a set of data that is useful when performing Terraform Cloud integration operations
|
||||||
type IntegrationContext struct {
|
type IntegrationContext struct {
|
||||||
started time.Time
|
|
||||||
B *Cloud
|
B *Cloud
|
||||||
StopContext context.Context
|
StopContext context.Context
|
||||||
CancelContext context.Context
|
CancelContext context.Context
|
||||||
|
@ -26,22 +29,15 @@ type IntegrationContext struct {
|
||||||
Run *tfe.Run
|
Run *tfe.Run
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// integrationCLIOutput implements IntegrationOutputWriter
|
||||||
type integrationCLIOutput struct {
|
type integrationCLIOutput struct {
|
||||||
ctx *IntegrationContext
|
CLI cli.Ui
|
||||||
|
Colorizer Colorer
|
||||||
|
started time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ IntegrationOutputWriter = (*integrationCLIOutput)(nil) // Compile time check
|
var _ IntegrationOutputWriter = (*integrationCLIOutput)(nil) // Compile time check
|
||||||
|
|
||||||
func NewIntegrationContext(stopCtx, cancelCtx context.Context, b *Cloud, op *backend.Operation, r *tfe.Run) *IntegrationContext {
|
|
||||||
return &IntegrationContext{
|
|
||||||
B: b,
|
|
||||||
StopContext: stopCtx,
|
|
||||||
CancelContext: cancelCtx,
|
|
||||||
Op: op,
|
|
||||||
Run: r,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *IntegrationContext) Poll(every func(i int) (bool, error)) error {
|
func (s *IntegrationContext) Poll(every func(i int) (bool, error)) error {
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
select {
|
select {
|
||||||
|
@ -60,48 +56,47 @@ func (s *IntegrationContext) Poll(every func(i int) (bool, error)) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BeginOutput writes a preamble to the CLI and creates a new IntegrationOutputWriter interface
|
||||||
|
// to write the remaining CLI output to. Use IntegrationOutputWriter.End() to complete integration
|
||||||
|
// output
|
||||||
func (s *IntegrationContext) BeginOutput(name string) IntegrationOutputWriter {
|
func (s *IntegrationContext) BeginOutput(name string) IntegrationOutputWriter {
|
||||||
var result IntegrationOutputWriter = &integrationCLIOutput{
|
var result IntegrationOutputWriter = &integrationCLIOutput{
|
||||||
ctx: s,
|
CLI: s.B.CLI,
|
||||||
|
Colorizer: s.B.Colorize(),
|
||||||
|
started: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
s.started = time.Now()
|
result.Output("\n[bold]" + name + ":\n")
|
||||||
|
|
||||||
if s.HasCLI() {
|
|
||||||
s.B.CLI.Output("\n------------------------------------------------------------------------\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Output("[bold]" + name + ":\n")
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationContext) HasCLI() bool {
|
// End writes the termination output for the integration
|
||||||
return s.B.CLI != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *integrationCLIOutput) End() {
|
func (s *integrationCLIOutput) End() {
|
||||||
if !s.ctx.HasCLI() {
|
if s.CLI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.ctx.B.CLI.Output("\n------------------------------------------------------------------------\n")
|
s.CLI.Output("\n------------------------------------------------------------------------\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Output writes a string after colorizing it using any [colorstrings](https://github.com/mitchellh/colorstring) it contains
|
||||||
func (s *integrationCLIOutput) Output(str string) {
|
func (s *integrationCLIOutput) Output(str string) {
|
||||||
if !s.ctx.HasCLI() {
|
if s.CLI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.ctx.B.CLI.Output(s.ctx.B.Colorize().Color(str))
|
s.CLI.Output(s.Colorizer.Color(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubOutput writes a string prefixed by a "│ " after colorizing it using any [colorstrings](https://github.com/mitchellh/colorstring) it contains
|
||||||
func (s *integrationCLIOutput) SubOutput(str string) {
|
func (s *integrationCLIOutput) SubOutput(str string) {
|
||||||
if !s.ctx.HasCLI() {
|
if s.CLI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.ctx.B.CLI.Output(s.ctx.B.Colorize().Color(fmt.Sprintf("[reset]│ %s", str)))
|
s.CLI.Output(s.Colorizer.Color(fmt.Sprintf("[reset]│ %s", str)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OutputElapsed writes a string followed by the amount of time that has elapsed since calling BeginOutput.
|
||||||
// Example pending output; the variable spacing (50 chars) allows up to 99 tasks (two digits) in each category:
|
// Example pending output; the variable spacing (50 chars) allows up to 99 tasks (two digits) in each category:
|
||||||
// ---------------
|
// ---------------
|
||||||
// 13 tasks still pending, 0 passed, 0 failed ...
|
// 13 tasks still pending, 0 passed, 0 failed ...
|
||||||
|
@ -109,9 +104,9 @@ func (s *integrationCLIOutput) SubOutput(str string) {
|
||||||
// 13 tasks still pending, 0 passed, 0 failed ... (19s elapsed)
|
// 13 tasks still pending, 0 passed, 0 failed ... (19s elapsed)
|
||||||
// 13 tasks still pending, 0 passed, 0 failed ... (33s elapsed)
|
// 13 tasks still pending, 0 passed, 0 failed ... (33s elapsed)
|
||||||
func (s *integrationCLIOutput) OutputElapsed(message string, maxMessage int) {
|
func (s *integrationCLIOutput) OutputElapsed(message string, maxMessage int) {
|
||||||
if !s.ctx.HasCLI() {
|
if s.CLI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
elapsed := time.Since(s.ctx.started).Truncate(1 * time.Second)
|
elapsed := time.Since(s.started).Truncate(1 * time.Second)
|
||||||
s.ctx.B.CLI.Output(fmt.Sprintf("%-"+strconv.FormatInt(int64(maxMessage), 10)+"s", message) + s.ctx.B.Colorize().Color(fmt.Sprintf("[dim](%s elapsed)", elapsed)))
|
s.CLI.Output(fmt.Sprintf("%-"+strconv.FormatInt(int64(maxMessage), 10)+"s", message) + s.Colorizer.Color(fmt.Sprintf("[dim](%s elapsed)", elapsed)))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue