add file comment generation and hashing for reproducible output in proto_generator

This commit is contained in:
adman
2026-05-29 01:14:56 +02:00
parent 624e8ad4de
commit efeb5ecda6
6 changed files with 95 additions and 7 deletions
-2
View File
@@ -2,7 +2,5 @@ github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9L
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+4 -2
View File
@@ -1,12 +1,14 @@
// Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.21.11/protocol.json (sha256:5d0fffae79fe3d99919d16f79ed22d4c76d80fcddf92868b93abda1f55867dd8)
// version: (devel) (go1.26.3-X:nodwarf5)
package v1_21_11
import (
"encoding/binary"
"io"
"github.com/admin-else/strom/nbt"
"github.com/admin-else/strom/proto_base"
"github.com/google/uuid"
"io"
)
type ArmorTrimMaterial struct {
+3
View File
@@ -1,3 +1,6 @@
// Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.21.8/protocol.json (sha256:627f4138d1a6e4a6fff1cde6008c95a72cd580728aafca8ba62ad0ef21c88f61)
// version: (devel) (go1.26.3-X:nodwarf5)
package v1_21_8
import (
+3
View File
@@ -1,3 +1,6 @@
// Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.21.9/protocol.json (sha256:5c5c5947ac583745cb1ea9a8b2fa654f0356349f37fa0248ba2e44baf4e5c485)
// version: (devel) (go1.26.3-X:nodwarf5)
package v1_21_9
import (
+48 -2
View File
@@ -1,12 +1,14 @@
package main
import (
"crypto/sha256"
"errors"
"fmt"
"go/ast"
"go/token"
"io"
"os"
"runtime/debug"
"slices"
"strconv"
"strings"
@@ -319,7 +321,34 @@ func (g *Generator) GenerateProtocol(protocol Protocol, version string) (err err
return
}
func Generate(version string, w io.Writer) (packetInfos []PacketInfo, err error) {
func ToolVersion() string {
info, ok := debug.ReadBuildInfo()
if !ok {
return "devel"
}
return info.Main.Version
}
func GoVersion() string {
info, ok := debug.ReadBuildInfo()
if !ok {
return "unknown"
}
return info.GoVersion
}
func HashFile(path string) (string, error) {
// Read from embedded filesystem since minecraft-data is embedded via go:embed
b, err := data.MinecraftData.ReadFile(path)
if err != nil {
return "", err
}
h := sha256.New()
h.Write(b)
return fmt.Sprintf("sha256:%x", h.Sum(nil)), nil
}
func Generate(version string, w io.Writer, sourceHash string) (packetInfos []PacketInfo, err error) {
protocol := Protocol{}
err = data.LoadVersionedJson(version, "protocol", &protocol)
if err != nil {
@@ -329,6 +358,15 @@ func Generate(version string, w io.Writer) (packetInfos []PacketInfo, err error)
g := &Generator{Protocol: protocol}
g.File = NewFile("v" + strings.ReplaceAll(version, ".", "_"))
// Add file header comment for IDE recognition and reproducibility
sourcePath := "minecraft-data/" + data.Paths.Data[version]["protocol"] + "/protocol.json"
toolVersion := ToolVersion()
goVersion := GoVersion()
comment := fmt.Sprintf("Code generated by strom. DO NOT EDIT.\nsource: %s (%s)\nversion: %s (%s)",
sourcePath, sourceHash, toolVersion, goVersion)
AddFileComment(g.File, comment)
AppendDecl(g.File, Import("encoding/binary", "io", "github.com/admin-else/strom/proto_base", "github.com/admin-else/strom/nbt", "github.com/google/uuid"))
g.RegisterNatives()
g.RegisterDecoderNatives()
@@ -354,7 +392,15 @@ func generateVersion(v string) (packetInfos []PacketInfo, err error) {
return
}
defer f.Close()
packetInfos, err = Generate(v, f)
// Compute hash of source protocol.json for reproducibility
sourcePath := "minecraft-data/" + data.Paths.Data[v]["protocol"] + "/protocol.json"
sourceHash, err := HashFile(sourcePath)
if err != nil {
return
}
packetInfos, err = Generate(v, f, sourceHash)
if err != nil {
return
}
+37 -1
View File
@@ -1,11 +1,13 @@
package main
import (
"bytes"
"fmt"
"go/ast"
"go/format"
"go/token"
"io"
"strings"
)
func NewStruct() (s *ast.StructType) {
@@ -357,8 +359,42 @@ func AppendDecl(file *ast.File, decl ast.Decl) {
file.Decls = append(file.Decls, decl)
}
// AddFileComment adds a comment block at the top of the file
func AddFileComment(f *ast.File, comment string) {
f.Doc = &ast.CommentGroup{}
lines := strings.Split(comment, "\n")
for _, line := range lines {
f.Doc.List = append(f.Doc.List, &ast.Comment{Text: "// " + line})
}
}
func PrintToFile(f *ast.File, w io.Writer) error {
return format.Node(w, token.NewFileSet(), f)
// Extract doc comment header if present
var header string
if f.Doc != nil {
for _, c := range f.Doc.List {
header += c.Text + "\n"
}
f.Doc = nil // Clear so go/format doesn't print it
}
// Format the file
var buf bytes.Buffer
if err := format.Node(&buf, token.NewFileSet(), f); err != nil {
return err
}
// Find where "package " starts in formatted output
formatted := buf.String()
pkgIndex := strings.Index(formatted, "package ")
if pkgIndex < 0 {
pkgIndex = 0
}
// Write header, then formatted content starting from package
w.Write([]byte(header))
w.Write([]byte(formatted[pkgIndex:]))
return nil
}
func IfErrNil() *ast.IfStmt {