119 lines
4.3 KiB
Go
119 lines
4.3 KiB
Go
package inventory
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// The merges a batch or walk answers (novox/hq ADR 0276): every merge the controller heard into a branch a
|
|
// module follows is kept here once, with the batch or walk that answers it. A merge is never dropped and never
|
|
// walked twice: its key is its repository and commit, and it belongs to one plan at a time.
|
|
|
|
// BatchedMerge is one merge as the controller heard it.
|
|
type BatchedMerge struct {
|
|
Repository string
|
|
Branch string
|
|
Commit string
|
|
// Merged is when the forge made it: the branch's order. Heard is when the controller heard it: what the
|
|
// window is measured from.
|
|
Merged time.Time
|
|
Heard time.Time
|
|
// Event is the forge's announcement, what the cut plans from.
|
|
Event json.RawMessage
|
|
// Plan is the batch or walk answering it; empty while it waits to be walked alone.
|
|
Plan string
|
|
// Alone says it is walked on its own commit, after a failed walk that carried it in a later one.
|
|
Alone bool
|
|
}
|
|
|
|
// AddMerge keeps a merge for a plan; false when the merge was kept already, for whatever plan.
|
|
func (i *Inventory) AddMerge(ctx context.Context, m BatchedMerge) (bool, error) {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return i.chainAddMerge(ctx, c, m)
|
|
}
|
|
|
|
// MergeOf is one kept merge; false when it was never heard.
|
|
func (i *Inventory) MergeOf(ctx context.Context, repository, commit string) (BatchedMerge, bool, error) {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return BatchedMerge{}, false, err
|
|
}
|
|
return i.chainMergeOf(ctx, c, repository, commit)
|
|
}
|
|
|
|
// MergesOf is every merge a plan answers, oldest merge first.
|
|
func (i *Inventory) MergesOf(ctx context.Context, plan string) ([]BatchedMerge, error) {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return i.chainMergesOf(ctx, c, plan)
|
|
}
|
|
|
|
// LaterMergesOf is every merge of a repository's branch made after a moment and answered by a plan, the
|
|
// newest first.
|
|
func (i *Inventory) LaterMergesOf(ctx context.Context, repository, branch string, after time.Time) ([]BatchedMerge, error) {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return i.chainLaterMergesOf(ctx, c, repository, branch, after)
|
|
}
|
|
|
|
// KeptOnBranch says the controller keeps a merge of a repository's branch, and when it heard the branch's first: a merge of a branch it keeps merges of, made since then, is the record's to answer, whatever a
|
|
// module's last look says (novox/hq ADR 0276).
|
|
func (i *Inventory) KeptOnBranch(ctx context.Context, repository, branch string) (bool, time.Time, error) {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return false, time.Time{}, err
|
|
}
|
|
return i.chainKeptOnBranch(ctx, c, repository, branch)
|
|
}
|
|
|
|
// AloneMerges is every merge waiting to be walked on its own commit, the newest first (ADR 0276 decision 3).
|
|
func (i *Inventory) AloneMerges(ctx context.Context) ([]BatchedMerge, error) {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return i.chainAloneMerges(ctx, c)
|
|
}
|
|
|
|
// WaitingMerges is every merge no plan answers that is not walked alone: kept, and waiting for something else to
|
|
// happen to it (a first merge into a repository, waiting for mesh-delivery's word on it, issue 1146).
|
|
func (i *Inventory) WaitingMerges(ctx context.Context) ([]BatchedMerge, error) {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return i.chainWaitingMerges(ctx, c)
|
|
}
|
|
|
|
// AnswerMerge moves a merge to the plan that answers it now; an empty plan with alone leaves it waiting to
|
|
// be walked on its own commit.
|
|
func (i *Inventory) AnswerMerge(ctx context.Context, repository, commit, plan string, alone bool) error {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return i.chainSavePlans(ctx, c, nil, []MergeMove{{Repository: repository, Commit: commit, Plan: plan, Alone: alone}})
|
|
}
|
|
|
|
// Batches is every batch not yet cut: assembling or queued, oldest first. One at a time is the rule; more
|
|
// are read so a fault is seen.
|
|
func (i *Inventory) Batches(ctx context.Context) ([]Plan, error) {
|
|
c, err := i.theChain(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return i.chainPlans(ctx, c, func(e viewEntry) bool { return e.sum.State == PlanAssembling || e.sum.State == PlanQueued }, sortCreated)
|
|
}
|
|
|
|
// SameRepository says two spellings of a repository are one.
|
|
func SameRepository(a, b string) bool { return strings.EqualFold(a, b) }
|