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/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 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
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 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
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
|
package v1_21_11
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/admin-else/strom/nbt"
|
"github.com/admin-else/strom/nbt"
|
||||||
"github.com/admin-else/strom/proto_base"
|
"github.com/admin-else/strom/proto_base"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArmorTrimMaterial struct {
|
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
|
package v1_21_8
|
||||||
|
|
||||||
import (
|
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
|
package v1_21_9
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
+48
-2
@@ -1,12 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime/debug"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -319,7 +321,34 @@ func (g *Generator) GenerateProtocol(protocol Protocol, version string) (err err
|
|||||||
return
|
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{}
|
protocol := Protocol{}
|
||||||
err = data.LoadVersionedJson(version, "protocol", &protocol)
|
err = data.LoadVersionedJson(version, "protocol", &protocol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -329,6 +358,15 @@ func Generate(version string, w io.Writer) (packetInfos []PacketInfo, err error)
|
|||||||
g := &Generator{Protocol: protocol}
|
g := &Generator{Protocol: protocol}
|
||||||
|
|
||||||
g.File = NewFile("v" + strings.ReplaceAll(version, ".", "_"))
|
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"))
|
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.RegisterNatives()
|
||||||
g.RegisterDecoderNatives()
|
g.RegisterDecoderNatives()
|
||||||
@@ -354,7 +392,15 @@ func generateVersion(v string) (packetInfos []PacketInfo, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer f.Close()
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/format"
|
"go/format"
|
||||||
"go/token"
|
"go/token"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewStruct() (s *ast.StructType) {
|
func NewStruct() (s *ast.StructType) {
|
||||||
@@ -357,8 +359,42 @@ func AppendDecl(file *ast.File, decl ast.Decl) {
|
|||||||
file.Decls = append(file.Decls, 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 {
|
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 {
|
func IfErrNil() *ast.IfStmt {
|
||||||
|
|||||||
Reference in New Issue
Block a user