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 } }