builder_build reads the builds and asked states, and the tools bundle follows the catalog half itself (registrations for the watched branches, revision per branch) for `newest`; the manifest names the tool and the two seat verbs. Builds: design 47 G §589, A-87 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
80 lines
3.5 KiB
Go
80 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
|
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
"git.novox.be/novox/mesh-sdk/go/buscalls"
|
|
|
|
"mesh-delivery-builder/internal/build"
|
|
)
|
|
|
|
// catalogWithin is how long a call waits for the catalog half's first view of one branch.
|
|
var catalogWithin = 30 * time.Second
|
|
|
|
// buildTool is builder_build (design 47 G §589): a module's build keys whole.
|
|
func buildTool(r *build.BuildReader) stdio.Tool {
|
|
return stdio.Tool{Name: build.BuildTool,
|
|
Description: "A module's build keys, whole, newest first (at most 20): per key its fingerprint (whole, as the build-input fingerprint the catalog graph " +
|
|
"entry carries it), state (queued, building, done or failed), revision and since when, the step and its node, the error whole, event-builds " +
|
|
"(the revisions events started since the last a person started; after three the operator is asked) and the open ask; and newest, the watched " +
|
|
"branches whose newest catalog graph entry of the module names that fingerprint, read from the catalog half. A module none of whose keys the newest " +
|
|
"entry names says so, naming the entry's fingerprint. With fingerprint, that key alone. Which node wants which fingerprint is the assigner's " +
|
|
"to answer (the seat mesh-wants). Read-only.",
|
|
Input: map[string]any{"type": "object", "required": []string{"module"}, "properties": map[string]any{
|
|
"module": map[string]any{"type": "string", "description": "the module"},
|
|
"fingerprint": map[string]any{"type": "string", "description": "one key: its fingerprint, src2:<hex>"}}},
|
|
Run: func(args map[string]any) (any, error) {
|
|
module, _ := args["module"].(string)
|
|
fp, _ := args["fingerprint"].(string)
|
|
return r.Build(module, fp)
|
|
}}
|
|
}
|
|
|
|
// newestVia reads the fingerprint of a module's newest catalog graph entry on each of its watched branches, from the catalog
|
|
// half through the seat mesh-catalog (the verb registrations for the branches, the verb revision for each branch's view), as
|
|
// the delivery view's tools read it: once per call (design 47 G §532, §589, A-87).
|
|
func newestVia(ask meshcatalogclient.Call) func(module string) (map[string]string, error) {
|
|
return func(module string) (map[string]string, error) {
|
|
raw, err := ask(meshcatalogclient.RegistrationsVerb, meshcatalog.RegistrationsInput{Module: module})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("the registrations of %s: %w", module, err)
|
|
}
|
|
answer, said, ok := buscalls.Unwrap(raw)
|
|
if !ok {
|
|
return nil, fmt.Errorf("%s answered: %s", meshcatalogclient.RegistrationsVerb, said)
|
|
}
|
|
var regs meshcatalog.RegistrationsAnswer
|
|
if err := json.Unmarshal(answer, ®s); err != nil {
|
|
return nil, fmt.Errorf("%s answered no registrations: %w", meshcatalogclient.RegistrationsVerb, err)
|
|
}
|
|
out := map[string]string{}
|
|
for _, reg := range regs.Registrations {
|
|
if reg.Module != module {
|
|
continue
|
|
}
|
|
for _, branch := range reg.Branches {
|
|
c, err := meshcatalogclient.NewCatalog(ask, branch)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), catalogWithin)
|
|
err = c.Start(ctx)
|
|
cancel()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("the catalog half of %s has no first view: %w", branch, err)
|
|
}
|
|
if e, ok := c.Entry(module); ok && e.Fp != "" {
|
|
out[branch] = e.Fp
|
|
}
|
|
}
|
|
}
|
|
return out, nil
|
|
}
|
|
}
|