The bridge watches the registrations' branches by origin (a first view of registrations, then registration-changed), before the first registration the gate's source's (source-moved); no branch is named in its code, Trunk goes. Every move is heard on the seat git's branch-moved through the bridge's durable on SEAT_git_branch-moved, its head read by the seat's verb branch, never the event's: merged with its pull request and `base` (the watched branch) when the seat's pull names the head a pull request's merge, else `pushed` with branch, head and `before`, both with the take-in inputs at the head. The last head written per watched branch is kept in the state heads under branch.<owner>.<name>.<escaped branch>, so a move heard twice writes once, and each watched branch's head is read at the start and when a branch is registered. A move of an unprotected branch writes nothing. pull.merged into a watched branch writes nothing (its message is the move's); the forge-made merge's trunk filter goes. Builds: design 47 G §4, §7, §11, §20, §41, §507, §509, §532, §714, A-227, A-236 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
72 lines
2.1 KiB
Go
72 lines
2.1 KiB
Go
package bridge
|
|
|
|
import (
|
|
"slices"
|
|
"sync"
|
|
)
|
|
|
|
// Watched is the branches the bridge watches, by repository (design 47 G §4, §11, §507, §532): the registrations' watched
|
|
// branches by their origin, from a first view of `registrations` and then `registration-changed`; before the first
|
|
// registration, the branches the gate's `source` answers, of every repository. No branch is fixed in code (§7).
|
|
type Watched struct {
|
|
mu sync.Mutex
|
|
byRepo map[string][]string
|
|
source []string
|
|
registered bool
|
|
}
|
|
|
|
// Registered is one registration as the bridge reads it: its origin `<owner>/<name>` and its watched branches.
|
|
type Registered struct {
|
|
Origin string
|
|
Branches []string
|
|
}
|
|
|
|
// Set takes what the bridge read: the registrations (none before the first) and the gate's source's branches by name.
|
|
func (w *Watched) Set(regs []Registered, source []string) {
|
|
by := map[string][]string{}
|
|
for _, r := range regs {
|
|
for _, b := range r.Branches {
|
|
if b != "" && !slices.Contains(by[r.Origin], b) {
|
|
by[r.Origin] = append(by[r.Origin], b)
|
|
}
|
|
}
|
|
}
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
w.byRepo, w.registered = by, len(regs) > 0
|
|
w.source = slices.Clone(source)
|
|
}
|
|
|
|
// Watches says whether a move of branch in repository is one the bridge writes.
|
|
func (w *Watched) Watches(repository, branch string) bool {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
if !w.registered {
|
|
return slices.Contains(w.source, branch)
|
|
}
|
|
return slices.Contains(w.byRepo[repository], branch)
|
|
}
|
|
|
|
// Branches are the watched branches of repository, in the order the registrations name them; before the first
|
|
// registration, the gate's source's.
|
|
func (w *Watched) Branches(repository string) []string {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
if !w.registered {
|
|
return slices.Clone(w.source)
|
|
}
|
|
return slices.Clone(w.byRepo[repository])
|
|
}
|
|
|
|
// Repositories are the repositories the registrations name, sorted; none before the first registration.
|
|
func (w *Watched) Repositories() []string {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
out := make([]string, 0, len(w.byRepo))
|
|
for r := range w.byRepo {
|
|
out = append(out, r)
|
|
}
|
|
slices.Sort(out)
|
|
return out
|
|
}
|