check / check (push) Waiting to run
Error messages in mfer/ and internal/cli/ are lowercase except names and acronyms, carry no "failed to" or command-name prefix, and each wrap names only the operation and thing the wrapped error does not already name, so a stacked message names what failed once. Wraps around errors that already name their operation and path (os and afero path errors, url.Error, the builder's path errors, the gpg helpers' own errors) are dropped. gpg's stderr is appended to a gpg failure, and to the error for a signing key gpg did not report, only when gpg wrote some. errHTTPStatus reads "unexpected HTTP status"; both inner-not-set sentinels read "inner message not set". No sentinel, errors.Is result or exit status changes. Model: opus-5-5
76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
package mfer
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/multiformats/go-multihash"
|
|
)
|
|
|
|
var (
|
|
errOuterNotSet = errors.New("outer message not set")
|
|
errUUIDNotSet = errors.New("UUID not set")
|
|
errSHA256NotSet = errors.New("SHA256 hash not set")
|
|
)
|
|
|
|
// manifest holds the internal representation of a manifest file.
|
|
// Use NewManifestFromFile or NewManifestFromReader to load an existing
|
|
// manifest, or use Builder to create a new one.
|
|
//
|
|
// Whether this type should be exported is an open design question owned by
|
|
// the repository owner; see README design question 13.
|
|
type manifest struct {
|
|
pbInner *MFFile
|
|
pbOuter *MFFileOuter
|
|
output *bytes.Buffer
|
|
signingOptions *SigningOptions
|
|
fixedUUID []byte // if set, use this UUID instead of generating one
|
|
}
|
|
|
|
func (m *manifest) String() string {
|
|
count := 0
|
|
if m.pbInner != nil {
|
|
count = len(m.pbInner.GetFiles())
|
|
}
|
|
|
|
return fmt.Sprintf("<Manifest count=%d>", count)
|
|
}
|
|
|
|
// Files returns all file entries from a loaded manifest.
|
|
func (m *manifest) Files() []*MFFilePath {
|
|
if m.pbInner == nil {
|
|
return nil
|
|
}
|
|
|
|
return m.pbInner.GetFiles()
|
|
}
|
|
|
|
// signatureString generates the canonical string used for signing/verification.
|
|
// Format: MAGIC-UUID-MULTIHASH where UUID and multihash are hex-encoded.
|
|
// Requires pbOuter to be set with Uuid and Sha256 fields.
|
|
func (m *manifest) signatureString() (string, error) {
|
|
if m.pbOuter == nil {
|
|
return "", errOuterNotSet
|
|
}
|
|
|
|
if len(m.pbOuter.GetUuid()) == 0 {
|
|
return "", errUUIDNotSet
|
|
}
|
|
|
|
if len(m.pbOuter.GetSha256()) == 0 {
|
|
return "", errSHA256NotSet
|
|
}
|
|
|
|
mh, err := multihash.Encode(m.pbOuter.GetSha256(), multihash.SHA2_256)
|
|
if err != nil {
|
|
return "", fmt.Errorf("encode multihash: %w", err)
|
|
}
|
|
|
|
uuidStr := hex.EncodeToString(m.pbOuter.GetUuid())
|
|
mhStr := hex.EncodeToString(mh)
|
|
|
|
return fmt.Sprintf("%s-%s-%s", MAGIC, uuidStr, mhStr), nil
|
|
}
|