Every method of builds, build requests, rollouts, merges and assignments reads and writes the chain alone: the else branches that read the tables, the movers and MoveChain with their tests, chain_moved reads, ChainReads and the flags that switched a kind, the store's assignments mirror (KeepAssignmentPlans needs none of it: it uses only the AssignmentMirrored type, mirrors.go, and AssignmentValues, provisioning.go) and its tick, the move code of the controller's start, and ForTest's chain_moved row. The listed store tests of the move go with their functions; the tests of the readers, requests, assignments and plans that lived beside them stay in chain_store_test.go. Tests that replayed old data migrations over the build, assignment and pin tables are removed with the tables. The static test that no plan is written but through SavePlansMoving now reads the plan's chain path.
109 lines
3.9 KiB
Go
109 lines
3.9 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)
|
|
}
|
|
|
|
// 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) }
|