add --format flag for proto/JSON plan bundles (#8825)

This change adds a new flag for emitting plan bundles in the new protobuf wire format. `opa build --format=json|proto`. With `--format=proto`, the bundle contains `/plan.pb` and `/.manifest.pb` in place of `/plan.json`and `/.manifest`. Bundle Reader auto-detects both forms; mixed-format bundles are rejected at read, merge, and write time.

Signed-off-by: Sebastian Spaink <sebastianspaink@gmail.com>
This commit is contained in:
Sebastian Spaink
2026-07-06 12:50:33 -05:00
committed by GitHub
parent d7a9d913f8
commit f6092b9ce4
22 changed files with 6122 additions and 33 deletions
+5
View File
@@ -29,6 +29,11 @@ func TestManifestProtoConsistency(t *testing.T) {
{
Name: "Manifest",
GoType: reflect.TypeOf(bundle.Manifest{}),
// roots_set is wire-form bookkeeping: it preserves the
// nil-vs-explicit-empty distinction that Manifest.Roots
// (*[]string) carries on the Go side. No Go counterpart by
// design.
SkipProtoFields: []string{"roots_set"},
},
{
Name: "WasmResolver",
@@ -73,6 +73,11 @@ type MessageSpec struct {
// is intentionally absent from the proto because consumers consult
// their own registry for builtin signatures.
SkipGoFields []string
// SkipProtoFields names proto fields with no Go counterpart by design —
// wire-form bookkeeping that the Go side carries differently. For
// example, bundle.Manifest.roots_set distinguishes nil from explicit-
// empty on the wire; the Go side already carries that as Roots *[]string.
SkipProtoFields []string
}
// OneofSpec asserts that the named oneof on MessageName has exactly the
@@ -289,6 +294,14 @@ func checkMessage(t *testing.T, declared map[string]protoreflect.MessageDescript
}
}
skipProto := map[string]bool{}
for _, n := range m.SkipProtoFields {
skipProto[n] = true
if msg.Fields().ByName(protoreflect.Name(n)) == nil {
t.Errorf("%s: SkipProtoFields entry %q does not match any proto field on this message", m.Name, n)
}
}
// Validate FieldNameOverride entries point at real Go fields.
for goJSONName := range override {
if !goJSONNameExists(m.GoType, goJSONName) {
@@ -333,6 +346,9 @@ func checkMessage(t *testing.T, declared map[string]protoreflect.MessageDescript
if opaque[name] {
continue
}
if skipProto[name] {
continue
}
// Fields belonging to a oneof handled by an OneofSpec are
// validated there, not here. Skip them so the orphan check
// doesn't double-fire.