Exit early from generateModuleBuildActions on error
generateModuleBuildActions was continuing to call GenerateBuildActions
on all modules even after one returned an error. This could cause a
later module to panic because it was missing information that was
supposed to be generated by the module that returned an error, hiding
the earlier error message.
If a module returns an error, stop triggering any new goroutines to
call GenerateBuildActions on later modules.
diff --git a/context.go b/context.go
index da4643a..d64d7d2 100644
--- a/context.go
+++ b/context.go
@@ -955,9 +955,10 @@
return nil
}
-func (c *Context) parallelVisitAllBottomUp(visit func(group *moduleGroup)) {
+func (c *Context) parallelVisitAllBottomUp(visit func(group *moduleGroup) bool) {
doneCh := make(chan *moduleGroup)
count := 0
+ cancel := false
for _, group := range c.moduleGroupsSorted {
group.waitingCount = group.depsCount
@@ -966,7 +967,10 @@
visitOne := func(group *moduleGroup) {
count++
go func() {
- visit(group)
+ ret := visit(group)
+ if ret {
+ cancel = true
+ }
doneCh <- group
}()
}
@@ -980,10 +984,12 @@
for count > 0 {
select {
case doneGroup := <-doneCh:
- for _, parent := range doneGroup.reverseDeps {
- parent.waitingCount--
- if parent.waitingCount == 0 {
- visitOne(parent)
+ if !cancel {
+ for _, parent := range doneGroup.reverseDeps {
+ parent.waitingCount--
+ if parent.waitingCount == 0 {
+ visitOne(parent)
+ }
}
}
count--
@@ -1286,7 +1292,7 @@
}
}()
- c.parallelVisitAllBottomUp(func(group *moduleGroup) {
+ c.parallelVisitAllBottomUp(func(group *moduleGroup) bool {
// The parent scope of the moduleContext's local scope gets overridden to be that of the
// calling Go package on a per-call basis. Since the initial parent scope doesn't matter we
// just set it to nil.
@@ -1307,7 +1313,7 @@
if len(mctx.errs) > 0 {
errsCh <- mctx.errs
- break
+ return true
}
depsCh <- mctx.ninjaFileDeps
@@ -1316,9 +1322,10 @@
&mctx.actionDefs, liveGlobals)
if len(newErrs) > 0 {
errsCh <- newErrs
- break
+ return true
}
}
+ return false
})
cancelCh <- struct{}{}