add file comment generation and hashing for reproducible output in proto_generator
This commit is contained in:
@@ -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=
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user