in astro/sessions.go [168:246]
func (s *Session) applyWithGraph(boundExecutions []*boundExecution) (<-chan string, <-chan *Result, error) {
logger.Trace.Println("astro session: running apply with graph")
// Convert unboundExecutions to executionSet
executions := make(executionSet, len(boundExecutions))
for i, e := range boundExecutions {
executions[i] = e
}
// Generate dep graph
graph, err := executions.graph()
if err != nil {
return nil, nil, err
}
numberOfExecutions := len(executions)
// Needs to be big enough to buffer log lines from below for tests that
// don't consume from the channel.
status := make(chan string, numberOfExecutions*10)
results := make(chan *Result, numberOfExecutions)
// Walk the graph and execute
go func() {
defer close(results)
graph.Walk(func(vertex dag.Vertex) error {
// skip if we've reached the root
if _, ok := vertex.(graphNodeRoot); ok {
return nil
}
b := vertex.(*boundExecution)
terraform, err := s.newTerraformSession(b)
if err != nil {
results <- &Result{
id: b.ID(),
err: err,
}
return err
}
for _, hook := range b.ModuleConfig().Hooks.PreModuleRun {
status <- fmt.Sprintf("[%s] Running PreModuleRun hook...", b.ID())
if err := runCommandkAndSetEnvironment(s.path, hook); err != nil {
results <- &Result{
id: b.ID(),
err: fmt.Errorf("error running PreModuleRun hook: %v", err),
}
return err
}
}
status <- fmt.Sprintf("[%s] Initializing...", b.ID())
if result, err := terraform.Init(); err != nil {
results <- &Result{
id: b.ID(),
terraformResult: result,
err: err,
}
return err
}
status <- fmt.Sprintf("[%s] Applying...", b.ID())
result, err := terraform.Apply()
results <- &Result{
id: b.ID(),
terraformResult: result,
err: err,
}
// This will cause any executions that depend on this one
// to be skipped.
return err
})
}()
return status, results, nil
}