From f7104c0ad658fb4d7824d97a2f1f2e6ec2ee888f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 28 Feb 2019 14:38:42 -0800 Subject: [PATCH 1/3] Support go 1.12 go 1.12 changed the stack trace of a function call during global variable initialization to contain a function called "PKG.init.ializers". Fix callerName to split the package path and function name on the first "." after the last "/", and look for functions called "init.ializers" or functions with the prefix "init." Change-Id: Ic2190837a8c4cde075f727bd69dd18d517a0ebc0 --- package_ctx.go | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/package_ctx.go b/package_ctx.go index 0c64e45..e0a03c8 100644 --- a/package_ctx.go +++ b/package_ctx.go @@ -18,6 +18,7 @@ import ( "errors" "fmt" "reflect" + "regexp" "runtime" "strings" "sync" @@ -137,12 +138,17 @@ func checkCalledFromInit() { panic("not called from an init func") } - if funcName == "init" || strings.HasPrefix(funcName, "init·") { + if funcName == "init" || strings.HasPrefix(funcName, "init·") || + funcName == "init.ializers" || strings.HasPrefix(funcName, "init.") { return } } } +// A regex to find a package path within a function name. It finds the shortest string that is +// followed by '.' and doesn't have any '/'s left. +var pkgPathRe = regexp.MustCompile(`^(.*?)\.([^/]+)$`) + // callerName returns the package path and function name of the calling // function. The skip argument has the same meaning as the skip argument of // runtime.Callers. @@ -153,25 +159,13 @@ func callerName(skip int) (pkgPath, funcName string, ok bool) { return "", "", false } - f := runtime.FuncForPC(pc[0]) - fullName := f.Name() - - lastDotIndex := strings.LastIndex(fullName, ".") - if lastDotIndex == -1 { - panic("unable to distinguish function name from package") + f := runtime.FuncForPC(pc[0]).Name() + s := pkgPathRe.FindStringSubmatch(f) + if len(s) < 3 { + panic(fmt.Errorf("failed to extract package path and function name from %q", f)) } - if fullName[lastDotIndex-1] == ')' { - // The caller is a method on some type, so it's name looks like - // "pkg/path.(type).method". We need to go back one dot farther to get - // to the package name. - lastDotIndex = strings.LastIndex(fullName[:lastDotIndex], ".") - } - - pkgPath = fullName[:lastDotIndex] - funcName = fullName[lastDotIndex+1:] - ok = true - return + return s[1], s[2], true } // pkgPathToName makes a Ninja-friendly name out of a Go package name by From 16b01609cee56ee32bca9935665a77f56aae4bf5 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 28 Feb 2019 14:42:04 -0800 Subject: [PATCH 2/3] Run go 1.11 and go 1.12 in travis Change-Id: If8d53ca83fb97cc6b68e3e5f4025119bb3ea2502 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3397bfd..6abd686 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,8 @@ language: go go: - 1.9 - "1.10" + - "1.11" + - "1.12" cache: directories: From d28b304d30eb34a1167c92edcccfb913763dfde9 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 1 Mar 2019 13:43:09 -0800 Subject: [PATCH 3/3] Add more OtherModule* methods Add OtherModuleDir, OtherModuleSubDir, and OtherModuleType to ModuleContext and TopDownMutatorContext, and add ModuleType to BaseModuleContext. Change-Id: If5c873a2620ef10333c0bdba5ab89d4256e5fdf2 --- module_ctx.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/module_ctx.go b/module_ctx.go index 9dbf43d..d127c0e 100644 --- a/module_ctx.go +++ b/module_ctx.go @@ -123,6 +123,7 @@ type DynamicDependerModule interface { type BaseModuleContext interface { ModuleName() string ModuleDir() string + ModuleType() string Config() interface{} ContainsProperty(name string) bool @@ -154,6 +155,9 @@ type ModuleContext interface { BaseModuleContext OtherModuleName(m Module) string + OtherModuleDir(m Module) string + OtherModuleSubDir(m Module) string + OtherModuleType(m Module) string OtherModuleErrorf(m Module, fmt string, args ...interface{}) OtherModuleDependencyTag(m Module) DependencyTag @@ -199,6 +203,10 @@ func (d *baseModuleContext) ModuleName() string { return d.module.Name() } +func (d *baseModuleContext) ModuleType() string { + return d.module.typeName +} + func (d *baseModuleContext) ContainsProperty(name string) bool { _, ok := d.module.propertyPos[name] return ok @@ -291,6 +299,21 @@ func (m *baseModuleContext) OtherModuleName(logicModule Module) string { return module.Name() } +func (m *baseModuleContext) OtherModuleDir(logicModule Module) string { + module := m.context.moduleInfo[logicModule] + return filepath.Dir(module.relBlueprintsFile) +} + +func (m *baseModuleContext) OtherModuleSubDir(logicModule Module) string { + module := m.context.moduleInfo[logicModule] + return module.variantName +} + +func (m *baseModuleContext) OtherModuleType(logicModule Module) string { + module := m.context.moduleInfo[logicModule] + return module.typeName +} + func (m *baseModuleContext) OtherModuleErrorf(logicModule Module, format string, args ...interface{}) { @@ -559,6 +582,9 @@ type TopDownMutatorContext interface { baseMutatorContext OtherModuleName(m Module) string + OtherModuleDir(m Module) string + OtherModuleSubDir(m Module) string + OtherModuleType(m Module) string OtherModuleErrorf(m Module, fmt string, args ...interface{}) OtherModuleDependencyTag(m Module) DependencyTag