Check missing uncoditionally loaded missing modules at runtime
A potentially inherited (via dynamically calculated path) module may in turn
unconditionally load a module that does no exist in a source tree -- it is
not an error if this potentially inherited module is actually never inherited
because its dynamically calculated path will never reference it. Instead of
emitting an uncoditional `load` for a non-existent file (which is going to fail
in the Starlark parser), emit conditional load and a runtime check.
Fixes: 213922819
Test: internal
Change-Id: I92177878e199a1f00e5f0c4045c0c0daeddd6bdb
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 04038e4..df6b725 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -249,19 +249,19 @@
gctx.writef("load(%q, %q)", baseUri, baseName)
// Emit exactly one load statement for each URI.
loadedSubConfigs := make(map[string]string)
- for _, sc := range gctx.starScript.inherited {
- uri := sc.path
+ for _, mi := range gctx.starScript.inherited {
+ uri := mi.path
if m, ok := loadedSubConfigs[uri]; ok {
// No need to emit load statement, but fix module name.
- sc.moduleLocalName = m
+ mi.moduleLocalName = m
continue
}
- if sc.optional {
+ if mi.optional || mi.missing {
uri += "|init"
}
gctx.newLine()
- gctx.writef("load(%q, %s = \"init\")", uri, sc.entryName())
- loadedSubConfigs[uri] = sc.moduleLocalName
+ gctx.writef("load(%q, %s = \"init\")", uri, mi.entryName())
+ loadedSubConfigs[uri] = mi.moduleLocalName
}
gctx.write("\n")
}
@@ -293,6 +293,20 @@
gctx.writef(`rblf.mk2rbc_error("%s", %q)`, el, message)
}
+func (gctx *generationContext) emitLoadCheck(im inheritedModule) {
+ if !im.needsLoadCheck() {
+ return
+ }
+ gctx.newLine()
+ gctx.writef("if not %s:", im.entryName())
+ gctx.indentLevel++
+ gctx.newLine()
+ gctx.write(`rblf.mkerror("`, gctx.starScript.mkFile, `", "Cannot find %s" % (`)
+ im.pathExpr().emit(gctx)
+ gctx.write("))")
+ gctx.indentLevel--
+}
+
type knownVariable struct {
name string
class varClass
@@ -746,11 +760,13 @@
moduleLocalName += fmt.Sprintf("%d", n)
}
ctx.moduleNameCount[moduleName] = n + 1
+ _, err := fs.Stat(ctx.script.sourceFS, path)
mi := &moduleInfo{
path: modulePath,
originalPath: path,
moduleLocalName: moduleLocalName,
optional: optional,
+ missing: err != nil,
}
ctx.dependentModules[modulePath] = mi
ctx.script.inherited = append(ctx.script.inherited, mi)