diff --git a/modules/mesh-delivery-sdk/buildstep/ask_test.go b/modules/mesh-delivery-sdk/buildstep/ask_test.go index f63c248b..7676d0f4 100644 --- a/modules/mesh-delivery-sdk/buildstep/ask_test.go +++ b/modules/mesh-delivery-sdk/buildstep/ask_test.go @@ -59,7 +59,9 @@ func stepAsk() StepAsk { // The ask the three build seats share is one neutral form: it round-trips, and every ill-formed ask is refused, // naming what is wrong (the rules of the old delivery.StepAsk, now the shared runner's). func TestAskCheckAndRoundTrip(t *testing.T) { - for _, a := range []StepAsk{goodBuild(), goodCheck(), runAsk(), stepAsk()} { + headless := runAsk() // a run whose program reads only its input names no head (design 47 G §712, A-238) + headless.Run.Heads = nil + for _, a := range []StepAsk{goodBuild(), goodCheck(), runAsk(), headless, stepAsk()} { raw, err := EncodeStepAsk(a) if err != nil { t.Fatal(err) @@ -106,7 +108,6 @@ func TestAskCheckAndRoundTrip(t *testing.T) { {"run at a short commit", func(a *StepAsk) { a.Run.Program.Commit = "0123456" }, "no full commit"}, {"run outside the repository", func(a *StepAsk) { a.Run.Program.Dir = "../x" }, "no clean directory"}, {"run of no package", func(a *StepAsk) { a.Run.Program.Package = "" }, "no package"}, - {"run over no head", func(a *StepAsk) { a.Run.Heads = nil }, "no head"}, {"run over a head twice", func(a *StepAsk) { a.Run.Heads = append(a.Run.Heads, a.Run.Heads[0]) }, "twice"}, {"run over a branch", func(a *StepAsk) { a.Run.Heads[1].Commit = "main" }, "novox/mesh-sdk at no full commit"}, {"input on a state", func(a *StepAsk) { a.Run.Input.Verb = "mesh-delivery-checker.inputs" }, "no seat:."}, diff --git a/modules/mesh-delivery-sdk/buildstep/run.go b/modules/mesh-delivery-sdk/buildstep/run.go index e975cdf4..c98c6262 100644 --- a/modules/mesh-delivery-sdk/buildstep/run.go +++ b/modules/mesh-delivery-sdk/buildstep/run.go @@ -31,7 +31,9 @@ type RunJob struct { // Program is where the program is built: the repository and full commit fetched, the Go module's directory in it and // the program's import path. The ask's Packages are the mesh package versions it builds against (ADR 0573 §2, §4). Program RunProgram `json:"program"` - // Heads are the commits the program reads, each laid read-only at its repository's path; a repository at most once. + // Heads are the commits the program reads, each laid read-only at its repository's path; a repository at most once. None + // is a program that reads only its input (the indexer's manifest validator, design 47 G §712, A-238): the directory + // RunHeadsEnv names is then empty. Heads []RunHead `json:"heads"` // Input names the program's input, kept by the asker by its digest and served on a verb of its seat. Input RunInput `json:"input"` @@ -150,9 +152,6 @@ func (r RunJob) check(id string) error { if p.Package == "" || strings.ContainsAny(p.Package, " \t\n") { return fmt.Errorf("buildstep: the run ask %s names no package to build (%q)", id, p.Package) } - if len(r.Heads) == 0 { - return fmt.Errorf("buildstep: the run ask %s names no head", id) - } seen := map[string]bool{} for _, h := range r.Heads { if err := checkRunRepository(id, "a head of", h.Repository); err != nil {