The view read the gate's state source and its history, fixed to the branch main. Each watched branch's source is now the seat mesh-delivery's verb source given that branch, asked again on its source-moved; the source row and the event delivered are per branch, a repository's reach is from the source of its modules' registration's first branch, laid over the reach the view's own state kept at its start, and view_tiers given no revision answers per branch. The manifest drops its read of mesh-delivery-gate.source and names the source answer's fields it relies on. Builds: design 47 G §507, §512, §532, §558, A-173, A-225 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
72 lines
2.8 KiB
Go
72 lines
2.8 KiB
Go
package view
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/clients/meshdeliveryclient"
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/meshdelivery"
|
|
"git.novox.be/novox/mesh-sdk/go/buscalls"
|
|
"git.novox.be/novox/mesh-sdk/go/keys"
|
|
)
|
|
|
|
// SourceVerb is the seat mesh-delivery's verb source as the view's invokes names it: each watched branch's source revision,
|
|
// asked of the seat and never read from the gate's state (design 47 G §507, §512, A-173).
|
|
const SourceVerb = "seat:" + meshdelivery.Seat + "." + meshdelivery.VerbSource
|
|
|
|
// SourceOf asks the seat, through call, for one watched branch's source revision (branch as named) and reads its declared
|
|
// answer; an answer that carries an error is that error.
|
|
func SourceOf(call func(key string, body any) (json.RawMessage, error), branch string) (meshdelivery.SourceAnswer, error) {
|
|
raw, err := call(SourceVerb, meshdelivery.SourceInput{Branch: keys.EscapeName(branch)})
|
|
if err != nil {
|
|
return meshdelivery.SourceAnswer{}, fmt.Errorf("%s of %s: %w", SourceVerb, branch, err)
|
|
}
|
|
answer, said, ok := buscalls.Unwrap(raw)
|
|
if !ok {
|
|
return meshdelivery.SourceAnswer{}, fmt.Errorf("%s of %s answered: %s", SourceVerb, branch, said)
|
|
}
|
|
var a meshdelivery.SourceAnswer
|
|
if err := json.Unmarshal(answer, &a); err != nil {
|
|
return a, fmt.Errorf("the answer of %s of %s is not a source revision: %w", SourceVerb, branch, err)
|
|
}
|
|
if a.Error != "" {
|
|
return a, fmt.Errorf("%s of %s: %s", SourceVerb, branch, a.Error)
|
|
}
|
|
return a, nil
|
|
}
|
|
|
|
// SourceEntry is a branch's source answer as the model's entry of SourceBucket: keyed by the escaped branch, its revision the
|
|
// source revision, its value the heads by repository; a branch the gate holds no source revision of yet is a removal.
|
|
func SourceEntry(branch string, a meshdelivery.SourceAnswer) (Entry, error) {
|
|
heads := map[string]string{}
|
|
for _, h := range a.Repositories {
|
|
heads[h.Repository] = h.Head
|
|
}
|
|
e := Entry{Bucket: SourceBucket, Key: keys.EscapeName(branch), Revision: uint64(a.Revision)}
|
|
if a.Revision == 0 && len(heads) == 0 { // the gate holds no source revision of the branch yet
|
|
e.Deleted = true
|
|
return e, nil
|
|
}
|
|
v, err := meshdeliveryclient.EncodeSource(meshdelivery.SourceByBranchValue{Group: a.Group, Heads: heads})
|
|
if err != nil {
|
|
return Entry{}, err
|
|
}
|
|
e.Value = v
|
|
return e, nil
|
|
}
|
|
|
|
// SourcesOf is Reader.Sources over the watched branches followed now: each one's newest source revision through call.
|
|
func SourcesOf(call func(key string, body any) (json.RawMessage, error), followed func() []string) func() (map[string]uint64, error) {
|
|
return func() (map[string]uint64, error) {
|
|
out := map[string]uint64{}
|
|
for _, branch := range followed() {
|
|
a, err := SourceOf(call, branch)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out[branch] = uint64(a.Revision)
|
|
}
|
|
return out, nil
|
|
}
|
|
}
|