The state tag-asks and its bounds, builder_tag, builder_tag_asks and builder_untag, the checker's tag-wanted consumer, the branch end's removal of tagged versions, the numbering of a check's build under a tag and the event version.numbered (its contract in builds, its emit, its manifest line) are removed; a forge message still wakes a floor. builder_publish_again refuses a held build, since nothing says a version numbered. Builds: design 47 G §373, §321, §349, §413 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
77 lines
2.4 KiB
Go
77 lines
2.4 KiB
Go
package versions
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
// The registry seats' events the builder hears on its durable consumer of each `<seat>.events` (design 51 *How a
|
|
// publish ends*, DLV-B4).
|
|
const (
|
|
HeardPublished = "published"
|
|
HeardRefused = "refused"
|
|
HeardRemoved = "removed"
|
|
HeardKept = "kept"
|
|
)
|
|
|
|
// Outcome is the body of a registry seat's published, refused and removed (mesh-contracts parts/registry Outcome), the
|
|
// fields the builder reads.
|
|
type Outcome struct {
|
|
Name string `json:"name"`
|
|
Version string `json:"version,omitempty"`
|
|
Digest string `json:"digest"`
|
|
Kind string `json:"kind"`
|
|
Holder string `json:"holder"`
|
|
Reason string `json:"reason,omitempty"`
|
|
// Tags are, on kept, the other tags still naming its digest.
|
|
Tags []string `json:"tags,omitempty"`
|
|
}
|
|
|
|
// Heard takes one seat event in: a numbered version's entry turns published (with its digest when it held none),
|
|
// refused with the holder's reason, removed with its reason and the event's id, or kept (another tag names its digest)
|
|
// with the other tags; a by-digest publish (no version)
|
|
// marks nothing. It answers the names waiting on their floor that the event wakes: a `published` says the seat
|
|
// answers (design 51 *The floor*).
|
|
func (n *Numberer) Heard(ctx context.Context, seat, event, id string, o Outcome) ([]string, error) {
|
|
var wake []string
|
|
if event == HeardPublished && n.Waits != nil {
|
|
wake = n.Waits.Wake(WakePublished, seat, "", "")
|
|
}
|
|
if o.Version == "" {
|
|
return wake, nil
|
|
}
|
|
var change func(*Entry)
|
|
switch event {
|
|
case HeardPublished:
|
|
change = func(e *Entry) {
|
|
e.State, e.Reason = Published, ""
|
|
if e.Digest == "" {
|
|
e.Digest = o.Digest
|
|
}
|
|
}
|
|
case HeardRefused:
|
|
change = func(e *Entry) {
|
|
if e.State != Published {
|
|
e.State, e.Reason, e.RefusedDigest = Refused, o.Reason, o.Digest
|
|
}
|
|
}
|
|
case HeardRemoved:
|
|
change = func(e *Entry) { e.State, e.Reason, e.RemovedBy = Removed, o.Reason, id }
|
|
case HeardKept:
|
|
change = func(e *Entry) {
|
|
if e.State != Removed {
|
|
e.State, e.Reason, e.KeptWith = Kept, o.Reason, append([]string(nil), o.Tags...)
|
|
if e.Reason == "" {
|
|
e.Reason = "shared-digest"
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
return wake, fmt.Errorf("%s says %q, which the builder does not hear", seat, event)
|
|
}
|
|
if _, err := n.Versions.Mark(ctx, o.Name, o.Version, change); err != nil {
|
|
return wake, fmt.Errorf("%s's %s of %s@%s: %w", seat, event, o.Name, o.Version, err)
|
|
}
|
|
return wake, nil
|
|
}
|