39 lines
1.7 KiB
Go
39 lines
1.7 KiB
Go
package delivery
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// The holder's question before it stores a publish (novox/hq ADR 0605 §4, design 51 *Publishing*): did the builder
|
|
// number this version with this digest? Every registry seat's holder asks it the same way, so the asking lives here
|
|
// once (ADR 0627 §2), beside the builder's layouts; no holder writes it again.
|
|
//
|
|
// The builder answers it today only as its module's tool builder_versions: no seat in the seat set names the builder's
|
|
// role yet. Once one does, BuilderVersionsAddress becomes that seat's verb and nothing else changes for a holder.
|
|
const BuilderVersionsAddress = BuilderModule + ".builder_versions"
|
|
|
|
// AskFunc is the runtime's request and reply over the bus (mesh-sdk stdio.Ask), given by the holder so this package does
|
|
// not depend on the runtime.
|
|
type AskFunc func(address string, body any) (json.RawMessage, error)
|
|
|
|
// BuilderVersions asks the builder whether it numbered a version with a digest. It answers the holder's Check:
|
|
// recorded, and why not when it is not.
|
|
type BuilderVersions struct{ Ask AskFunc }
|
|
|
|
// Recorded asks the builder about name@version with digest. An answer without `recorded` is an error, never a yes.
|
|
func (b BuilderVersions) Recorded(name, version, digest string) (bool, string, error) {
|
|
raw, err := b.Ask(BuilderVersionsAddress, map[string]any{"name": name, "version": version, "digest": digest})
|
|
if err != nil {
|
|
return false, "", err
|
|
}
|
|
var a struct {
|
|
Recorded *bool `json:"recorded"`
|
|
Why string `json:"why"`
|
|
}
|
|
if err := json.Unmarshal(raw, &a); err != nil || a.Recorded == nil {
|
|
return false, "", fmt.Errorf("builder_versions answered no recorded: %s", raw)
|
|
}
|
|
return *a.Recorded, a.Why, nil
|
|
}
|