diff options
author | Dan Willemsen <dwillemsen@google.com> | 2016-01-13 16:43:18 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2016-01-13 16:43:18 -0800 |
commit | 3a89d1ce9fe7a5160ee87ee11f99edbf540020fc (patch) | |
tree | e27b4933194b4872d6825dfa30bdc7f055377574 | |
parent | 2fb2b42e67ed82e4da50b2b68de4c109591e0ffd (diff) | |
parent | 24d81001677743c3ebffe32a2a48c7036974d1fb (diff) | |
download | blueprint-nougat-mr1.1-release.tar.gz |
Merge remote-tracking branch 'aosp/upstream'android-n-preview-1android-cts_7.1_r1android-cts-7.1_r9android-cts-7.1_r8android-cts-7.1_r7android-cts-7.1_r6android-cts-7.1_r5android-cts-7.1_r4android-cts-7.1_r3android-cts-7.1_r29android-cts-7.1_r28android-cts-7.1_r27android-cts-7.1_r26android-cts-7.1_r25android-cts-7.1_r24android-cts-7.1_r23android-cts-7.1_r22android-cts-7.1_r21android-cts-7.1_r20android-cts-7.1_r2android-cts-7.1_r19android-cts-7.1_r18android-cts-7.1_r17android-cts-7.1_r16android-cts-7.1_r15android-cts-7.1_r14android-cts-7.1_r13android-cts-7.1_r12android-cts-7.1_r11android-cts-7.1_r10android-cts-7.1_r1android-7.1.2_r9android-7.1.2_r8android-7.1.2_r6android-7.1.2_r5android-7.1.2_r4android-7.1.2_r39android-7.1.2_r38android-7.1.2_r37android-7.1.2_r36android-7.1.2_r33android-7.1.2_r32android-7.1.2_r30android-7.1.2_r3android-7.1.2_r29android-7.1.2_r28android-7.1.2_r27android-7.1.2_r25android-7.1.2_r24android-7.1.2_r23android-7.1.2_r2android-7.1.2_r19android-7.1.2_r18android-7.1.2_r17android-7.1.2_r16android-7.1.2_r15android-7.1.2_r14android-7.1.2_r13android-7.1.2_r12android-7.1.2_r11android-7.1.2_r10android-7.1.2_r1android-7.1.1_r9android-7.1.1_r8android-7.1.1_r7android-7.1.1_r61android-7.1.1_r60android-7.1.1_r6android-7.1.1_r59android-7.1.1_r58android-7.1.1_r57android-7.1.1_r56android-7.1.1_r55android-7.1.1_r54android-7.1.1_r53android-7.1.1_r52android-7.1.1_r51android-7.1.1_r50android-7.1.1_r49android-7.1.1_r48android-7.1.1_r47android-7.1.1_r46android-7.1.1_r45android-7.1.1_r44android-7.1.1_r43android-7.1.1_r42android-7.1.1_r41android-7.1.1_r40android-7.1.1_r4android-7.1.1_r39android-7.1.1_r38android-7.1.1_r35android-7.1.1_r33android-7.1.1_r32android-7.1.1_r31android-7.1.1_r3android-7.1.1_r28android-7.1.1_r27android-7.1.1_r26android-7.1.1_r25android-7.1.1_r24android-7.1.1_r23android-7.1.1_r22android-7.1.1_r21android-7.1.1_r20android-7.1.1_r2android-7.1.1_r17android-7.1.1_r16android-7.1.1_r15android-7.1.1_r14android-7.1.1_r13android-7.1.1_r12android-7.1.1_r11android-7.1.1_r10android-7.1.1_r1android-7.1.0_r7android-7.1.0_r6android-7.1.0_r5android-7.1.0_r4android-7.1.0_r3android-7.1.0_r2android-7.1.0_r1nougat-mr2.3-releasenougat-mr2.2-releasenougat-mr2.1-releasenougat-mr2-security-releasenougat-mr2-releasenougat-mr2-pixel-releasenougat-mr2-devnougat-mr1.8-releasenougat-mr1.7-releasenougat-mr1.6-releasenougat-mr1.5-releasenougat-mr1.4-releasenougat-mr1.3-releasenougat-mr1.2-releasenougat-mr1.1-releasenougat-mr1-volantis-releasenougat-mr1-security-releasenougat-mr1-releasenougat-mr1-flounder-releasenougat-mr1-devnougat-mr1-cts-releasenougat-dr1-releasenougat-devbrillo-m10-releasebrillo-m10-dev
* aosp/upstream:
docs: Allow propery structs to contain non-struct ptrs
Catch panics in build logic
Colorize errors
-rw-r--r-- | bootstrap/bpdoc/bpdoc.go | 10 | ||||
-rw-r--r-- | bootstrap/command.go | 9 | ||||
-rw-r--r-- | context.go | 220 | ||||
-rw-r--r-- | module_ctx.go | 17 | ||||
-rw-r--r-- | singleton_ctx.go | 10 | ||||
-rw-r--r-- | splice_modules_test.go | 4 |
6 files changed, 233 insertions, 37 deletions
diff --git a/bootstrap/bpdoc/bpdoc.go b/bootstrap/bpdoc/bpdoc.go index d4b52a5..f96d37e 100644 --- a/bootstrap/bpdoc/bpdoc.go +++ b/bootstrap/bpdoc/bpdoc.go @@ -501,13 +501,11 @@ func nestedPropertyStructs(s reflect.Value) map[string]reflect.Value { } elem = elem.Elem() } - if elem.Kind() != reflect.Struct { - panic(fmt.Errorf("can't get type of field %q: points to a "+ - "non-struct", field.Name)) + if elem.Kind() == reflect.Struct { + nestPoint := prefix + proptools.PropertyNameForField(field.Name) + ret[nestPoint] = elem + walk(elem, nestPoint+".") } - nestPoint := prefix + proptools.PropertyNameForField(field.Name) - ret[nestPoint] = elem - walk(elem, nestPoint+".") } default: panic(fmt.Errorf("unexpected kind for property struct field %q: %s", diff --git a/bootstrap/command.go b/bootstrap/command.go index 65d6f46..69b2271 100644 --- a/bootstrap/command.go +++ b/bootstrap/command.go @@ -177,12 +177,15 @@ func fatalf(format string, args ...interface{}) { } func fatalErrors(errs []error) { + red := "\x1b[31m" + unred := "\x1b[0m" + for _, err := range errs { - switch err.(type) { + switch err := err.(type) { case *blueprint.Error: - _, _ = fmt.Printf("%s\n", err.Error()) + fmt.Printf("%serror:%s %s\n", red, unred, err.Error()) default: - _, _ = fmt.Printf("internal error: %s\n", err) + fmt.Printf("%sinternal error:%s %s\n", red, unred, err) } } os.Exit(1) @@ -157,6 +157,14 @@ type moduleInfo struct { actionDefs localBuildActions } +func (module *moduleInfo) String() string { + s := fmt.Sprintf("module %q", module.properties.Name) + if module.variantName != "" { + s += fmt.Sprintf(" variant %q", module.variantName) + } + return s +} + // A Variation is a way that a variant of a module differs from other variants of the same module. // For example, two variants of the same module might have Variation{"arch","arm"} and // Variation{"arch","arm64"} @@ -1122,13 +1130,20 @@ func blueprintDepsMutator(ctx BottomUpMutatorContext) { ctx.AddDependency(ctx.Module(), ctx.moduleInfo().properties.Deps...) if dynamicDepender, ok := ctx.Module().(DynamicDependerModule); ok { - dynamicDeps := dynamicDepender.DynamicDependencies(ctx) + func() { + defer func() { + if r := recover(); r != nil { + ctx.error(newPanicErrorf(r, "DynamicDependencies for %s", ctx.moduleInfo())) + } + }() + dynamicDeps := dynamicDepender.DynamicDependencies(ctx) - if ctx.Failed() { - return - } + if ctx.Failed() { + return + } - ctx.AddDependency(ctx.Module(), dynamicDeps...) + ctx.AddDependency(ctx.Module(), dynamicDeps...) + }() } } @@ -1516,7 +1531,20 @@ func (c *Context) runEarlyMutators(config interface{}) (errs []error) { }, name: mutator.name, } - mutator.mutator(mctx) + func() { + defer func() { + if r := recover(); r != nil { + in := fmt.Sprintf("early mutator %q for %s", mutator.name, module) + if err, ok := r.(panicError); ok { + err.addIn(in) + mctx.error(err) + } else { + mctx.error(newPanicErrorf(r, in)) + } + } + }() + mutator.mutator(mctx) + }() if len(mctx.errs) > 0 { errs = append(errs, mctx.errs...) return errs @@ -1576,8 +1604,21 @@ func (c *Context) runTopDownMutator(config interface{}, }, name: name, } + func() { + defer func() { + if r := recover(); r != nil { + in := fmt.Sprintf("top down mutator %q for %s", name, module) + if err, ok := r.(panicError); ok { + err.addIn(in) + mctx.error(err) + } else { + mctx.error(newPanicErrorf(r, in)) + } + } + }() + mutator(mctx) + }() - mutator(mctx) if len(mctx.errs) > 0 { errs = append(errs, mctx.errs...) return errs @@ -1609,7 +1650,20 @@ func (c *Context) runBottomUpMutator(config interface{}, reverseDeps: reverseDeps, } - mutator(mctx) + func() { + defer func() { + if r := recover(); r != nil { + in := fmt.Sprintf("bottom up mutator %q for %s", name, module) + if err, ok := r.(panicError); ok { + err.addIn(in) + mctx.error(err) + } else { + mctx.error(newPanicErrorf(r, in)) + } + } + }() + mutator(mctx) + }() if len(mctx.errs) > 0 { errs = append(errs, mctx.errs...) return errs @@ -1726,7 +1780,20 @@ func (c *Context) generateModuleBuildActions(config interface{}, handledMissingDeps: module.missingDeps == nil, } - mctx.module.logicModule.GenerateBuildActions(mctx) + func() { + defer func() { + if r := recover(); r != nil { + in := fmt.Sprintf("GenerateBuildActions for %s", module) + if err, ok := r.(panicError); ok { + err.addIn(in) + mctx.error(err) + } else { + mctx.error(newPanicErrorf(r, in)) + } + } + }() + mctx.module.logicModule.GenerateBuildActions(mctx) + }() if len(mctx.errs) > 0 { errsCh <- mctx.errs @@ -1781,7 +1848,20 @@ func (c *Context) generateSingletonBuildActions(config interface{}, scope: scope, } - info.singleton.GenerateBuildActions(sctx) + func() { + defer func() { + if r := recover(); r != nil { + in := fmt.Sprintf("GenerateBuildActions for singleton %s", info.name) + if err, ok := r.(panicError); ok { + err.addIn(in) + sctx.error(err) + } else { + sctx.error(newPanicErrorf(r, in)) + } + } + }() + info.singleton.GenerateBuildActions(sctx) + }() if len(sctx.errs) > 0 { errs = append(errs, sctx.errs...) @@ -1849,6 +1929,14 @@ func (c *Context) walkDeps(topModule *moduleInfo, visit func(Module, Module) bool) { visited := make(map[*moduleInfo]bool) + var visiting *moduleInfo + + defer func() { + if r := recover(); r != nil { + panic(newPanicErrorf(r, "WalkDeps(%s, %s) for dependency %s", + topModule, funcName(visit), visiting)) + } + }() var walk func(module *moduleInfo) walk = func(module *moduleInfo) { @@ -1856,6 +1944,7 @@ func (c *Context) walkDeps(topModule *moduleInfo, for _, moduleDep := range module.directDeps { if !visited[moduleDep] { + visiting = moduleDep if visit(moduleDep.logicModule, module.logicModule) { walk(moduleDep) } @@ -1866,8 +1955,18 @@ func (c *Context) walkDeps(topModule *moduleInfo, walk(topModule) } +type innerPanicError error + func (c *Context) visitDepsDepthFirst(topModule *moduleInfo, visit func(Module)) { visited := make(map[*moduleInfo]bool) + var visiting *moduleInfo + + defer func() { + if r := recover(); r != nil { + panic(newPanicErrorf(r, "VisitDepsDepthFirst(%s, %s) for dependency %s", + topModule, funcName(visit), visiting)) + } + }() var walk func(module *moduleInfo) walk = func(module *moduleInfo) { @@ -1879,6 +1978,7 @@ func (c *Context) visitDepsDepthFirst(topModule *moduleInfo, visit func(Module)) } if module != topModule { + visiting = module visit(module.logicModule) } } @@ -1890,6 +1990,14 @@ func (c *Context) visitDepsDepthFirstIf(topModule *moduleInfo, pred func(Module) visit func(Module)) { visited := make(map[*moduleInfo]bool) + var visiting *moduleInfo + + defer func() { + if r := recover(); r != nil { + panic(newPanicErrorf(r, "VisitDepsDepthFirstIf(%s, %s, %s) for dependency %s", + topModule, funcName(pred), funcName(visit), visiting)) + } + }() var walk func(module *moduleInfo) walk = func(module *moduleInfo) { @@ -1902,6 +2010,7 @@ func (c *Context) visitDepsDepthFirstIf(topModule *moduleInfo, pred func(Module) if module != topModule { if pred(module.logicModule) { + visiting = module visit(module.logicModule) } } @@ -1911,7 +2020,16 @@ func (c *Context) visitDepsDepthFirstIf(topModule *moduleInfo, pred func(Module) } func (c *Context) visitDirectDeps(module *moduleInfo, visit func(Module)) { - for _, dep := range module.directDeps { + var dep *moduleInfo + + defer func() { + if r := recover(); r != nil { + panic(newPanicErrorf(r, "VisitDirectDeps(%s, %s) for dependency %s", + module, funcName(visit), dep)) + } + }() + + for _, dep = range module.directDeps { visit(dep.logicModule) } } @@ -1919,7 +2037,16 @@ func (c *Context) visitDirectDeps(module *moduleInfo, visit func(Module)) { func (c *Context) visitDirectDepsIf(module *moduleInfo, pred func(Module) bool, visit func(Module)) { - for _, dep := range module.directDeps { + var dep *moduleInfo + + defer func() { + if r := recover(); r != nil { + panic(newPanicErrorf(r, "VisitDirectDepsIf(%s, %s, %s) for dependency %s", + module, funcName(pred), funcName(visit), dep)) + } + }() + + for _, dep = range module.directDeps { if pred(dep.logicModule) { visit(dep.logicModule) } @@ -1940,9 +2067,18 @@ func (c *Context) sortedModuleNames() []string { } func (c *Context) visitAllModules(visit func(Module)) { + var module *moduleInfo + + defer func() { + if r := recover(); r != nil { + panic(newPanicErrorf(r, "VisitAllModules(%s) for %s", + funcName(visit), module)) + } + }() + for _, moduleName := range c.sortedModuleNames() { group := c.moduleGroups[moduleName] - for _, module := range group.modules { + for _, module = range group.modules { visit(module.logicModule) } } @@ -1951,6 +2087,15 @@ func (c *Context) visitAllModules(visit func(Module)) { func (c *Context) visitAllModulesIf(pred func(Module) bool, visit func(Module)) { + var module *moduleInfo + + defer func() { + if r := recover(); r != nil { + panic(newPanicErrorf(r, "VisitAllModulesIf(%s, %s) for %s", + funcName(pred), funcName(visit), module)) + } + }() + for _, moduleName := range c.sortedModuleNames() { group := c.moduleGroups[moduleName] for _, module := range group.modules { @@ -1961,6 +2106,23 @@ func (c *Context) visitAllModulesIf(pred func(Module) bool, } } +func (c *Context) visitAllModuleVariants(module *moduleInfo, + visit func(Module)) { + + var variant *moduleInfo + + defer func() { + if r := recover(); r != nil { + panic(newPanicErrorf(r, "VisitAllModuleVariants(%s, %s) for %s", + module, funcName(visit), variant)) + } + }() + + for _, variant = range module.group.modules { + visit(variant.logicModule) + } +} + func (c *Context) requireNinjaVersion(major, minor, micro int) { if major != 1 { panic("ninja version with major version != 1 not supported") @@ -2236,9 +2398,7 @@ func (c *Context) FinalModule(module Module) Module { func (c *Context) VisitAllModuleVariants(module Module, visit func(Module)) { - for _, module := range c.moduleInfo[module].group.modules { - visit(module.logicModule) - } + c.visitAllModuleVariants(c.moduleInfo[module], visit) } // WriteBuildFile writes the Ninja manifeset text for the generated build @@ -2739,6 +2899,34 @@ func beforeInModuleList(a, b *moduleInfo, list []*moduleInfo) bool { panic(fmt.Errorf("element %v not found in list %v", missing, list)) } +type panicError struct { + panic interface{} + stack []byte + in string +} + +func newPanicErrorf(panic interface{}, in string, a ...interface{}) error { + buf := make([]byte, 4096) + count := runtime.Stack(buf, false) + return panicError{ + panic: panic, + in: fmt.Sprintf(in, a...), + stack: buf[:count], + } +} + +func (p panicError) Error() string { + return fmt.Sprintf("panic in %s\n%s\n%s\n", p.in, p.panic, p.stack) +} + +func (p *panicError) addIn(in string) { + p.in += " in " + in +} + +func funcName(f interface{}) string { + return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name() +} + var fileHeaderTemplate = `****************************************************************************** *** This file is generated and should not be edited *** ****************************************************************************** diff --git a/module_ctx.go b/module_ctx.go index 754c2d2..381b54a 100644 --- a/module_ctx.go +++ b/module_ctx.go @@ -119,6 +119,7 @@ type BaseModuleContext interface { Failed() bool moduleInfo() *moduleInfo + error(err error) } type DynamicDependerModuleContext BottomUpMutatorContext @@ -180,10 +181,16 @@ func (d *baseModuleContext) Config() interface{} { return d.config } +func (d *baseModuleContext) error(err error) { + if err != nil { + d.errs = append(d.errs, err) + } +} + func (d *baseModuleContext) Errorf(pos scanner.Position, format string, args ...interface{}) { - d.errs = append(d.errs, &Error{ + d.error(&Error{ Err: fmt.Errorf(format, args...), Pos: pos, }) @@ -192,7 +199,7 @@ func (d *baseModuleContext) Errorf(pos scanner.Position, func (d *baseModuleContext) ModuleErrorf(format string, args ...interface{}) { - d.errs = append(d.errs, &Error{ + d.error(&Error{ Err: fmt.Errorf(format, args...), Pos: d.module.pos, }) @@ -209,7 +216,7 @@ func (d *baseModuleContext) PropertyErrorf(property, format string, format = property + ": " + format - d.errs = append(d.errs, &Error{ + d.error(&Error{ Err: fmt.Errorf(format, args...), Pos: pos, }) @@ -320,9 +327,7 @@ func (m *moduleContext) FinalModule() Module { } func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) { - for _, module := range m.module.group.modules { - visit(module.logicModule) - } + m.context.visitAllModuleVariants(m.module, visit) } func (m *moduleContext) GetMissingDependencies() []string { diff --git a/singleton_ctx.go b/singleton_ctx.go index 07e5108..a2d6109 100644 --- a/singleton_ctx.go +++ b/singleton_ctx.go @@ -91,15 +91,21 @@ func (s *singletonContext) BlueprintFile(logicModule Module) string { return s.context.BlueprintFile(logicModule) } +func (s *singletonContext) error(err error) { + if err != nil { + s.errs = append(s.errs, err) + } +} + func (s *singletonContext) ModuleErrorf(logicModule Module, format string, args ...interface{}) { - s.errs = append(s.errs, s.context.ModuleErrorf(logicModule, format, args...)) + s.error(s.context.ModuleErrorf(logicModule, format, args...)) } func (s *singletonContext) Errorf(format string, args ...interface{}) { // TODO: Make this not result in the error being printed as "internal error" - s.errs = append(s.errs, fmt.Errorf(format, args...)) + s.error(fmt.Errorf(format, args...)) } func (s *singletonContext) Failed() bool { diff --git a/splice_modules_test.go b/splice_modules_test.go index 091f5bf..cfe905a 100644 --- a/splice_modules_test.go +++ b/splice_modules_test.go @@ -28,10 +28,6 @@ var ( testModuleF = &moduleInfo{variantName: "testModuleF"} ) -func (m *moduleInfo) String() string { - return m.variantName -} - var spliceModulesTestCases = []struct { in []*moduleInfo replace *moduleInfo |