Add deterministic file ordering in Builder.Build()

Sort file entries by path (lexicographic, byte-order) before
serialization to ensure deterministic output. Add fixedUUID support
for testing reproducibility, and a test asserting byte-identical
output from two runs with the same input.

Closes #23
This commit is contained in:
clawbot
2026-02-20 03:05:16 -08:00
committed by user
parent 6d1bdbb00f
commit 6d9c07510a
4 changed files with 51 additions and 2 deletions
+8
View File
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io"
"sort"
"strings"
"sync"
"time"
@@ -88,6 +89,7 @@ type Builder struct {
files []*MFFilePath
createdAt time.Time
signingOptions *SigningOptions
fixedUUID []byte // if set, use this UUID instead of generating one
}
// NewBuilder creates a new Builder.
@@ -222,6 +224,11 @@ func (b *Builder) Build(w io.Writer) error {
b.mu.Lock()
defer b.mu.Unlock()
// Sort files by path for deterministic output
sort.Slice(b.files, func(i, j int) bool {
return b.files[i].Path < b.files[j].Path
})
// Create inner manifest
inner := &MFFile{
Version: MFFile_VERSION_ONE,
@@ -233,6 +240,7 @@ func (b *Builder) Build(w io.Writer) error {
m := &manifest{
pbInner: inner,
signingOptions: b.signingOptions,
fixedUUID: b.fixedUUID,
}
// Generate outer wrapper