mesh-delivery-contracts, sdk buildstep: the check answer's fetch keeps the fetch tool's whole answer (workspace, commit, modules, merge, conflicts, changed, programs, trees, beside, packages, installed, refused), typed in the seats' StepResult and the sdk's CheckAnswer and StepResult; fixtures from the build modules' captured answers (B2g; issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -233,7 +233,7 @@ type Capacity struct {
|
||||
|
||||
// CheckAnswer is a type of the contract.
|
||||
type CheckAnswer struct {
|
||||
Fetch Fetch `json:"fetch"`
|
||||
Fetch FetchAnswer `json:"fetch"`
|
||||
Levels []LevelAnswer `json:"levels,omitempty"`
|
||||
}
|
||||
|
||||
@@ -271,6 +271,30 @@ type Fetch struct {
|
||||
Repository string `json:"repository"`
|
||||
}
|
||||
|
||||
// FetchAnswer is what a build module's fetch tool answers, whole: the workspace it made, the commit in it, the module directories found; and, when the call gave a base, the merge preview (the trunk commit, the merge commit, the files that conflict, the paths the merge changes, the compiled programs among them, the tree of each module directory). A head that does not merge cleanly is an answer, not an error: merge is empty and conflicts names the files. The Go module adds the sibling repositories placed and the package versions taken; the TypeScript module the directories installed and refused and the group's package.
|
||||
type FetchAnswer struct {
|
||||
Base string `json:"base,omitempty"`
|
||||
Beside []PlacedBeside `json:"beside,omitempty"`
|
||||
Changed []string `json:"changed,omitempty"`
|
||||
Commit string `json:"commit"`
|
||||
Conflicts []string `json:"conflicts,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Installed []string `json:"installed,omitempty"`
|
||||
Merge string `json:"merge,omitempty"`
|
||||
Modules []string `json:"modules"`
|
||||
Packages []TakenVersion `json:"packages,omitempty"`
|
||||
Programs []Program `json:"programs,omitempty"`
|
||||
Refused []FetchRefusal `json:"refused,omitempty"`
|
||||
Trees map[string]ModuleTree `json:"trees,omitempty"`
|
||||
Workspace string `json:"workspace"`
|
||||
}
|
||||
|
||||
// FetchRefusal is a TypeScript module whose packages the fetch did not install, with why.
|
||||
type FetchRefusal struct {
|
||||
Module string `json:"module"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// LevelAnswerDigestNeedsItem is a type of the contract.
|
||||
type LevelAnswerDigestNeedsItem struct {
|
||||
Needs []string `json:"needs,omitempty"`
|
||||
@@ -316,6 +340,16 @@ type LevelAnswer struct {
|
||||
Unmet []LevelAnswerUnmetItem `json:"unmet,omitempty"`
|
||||
}
|
||||
|
||||
// ModuleTree is the tree of one module directory in a merge preview: its git tree, the digest of its manifest, the lock files' digests and the digests of the named paths.
|
||||
type ModuleTree struct {
|
||||
Locks map[string]string `json:"locks,omitempty"`
|
||||
Manifest string `json:"manifest"`
|
||||
// no longer filled (ADR 0593 section 2); kept so a preview written before still reads
|
||||
Packages []string `json:"packages,omitempty"`
|
||||
Paths map[string]string `json:"paths,omitempty"`
|
||||
Tree string `json:"tree"`
|
||||
}
|
||||
|
||||
// Pause is whether the node takes no new ask.
|
||||
type Pause struct {
|
||||
// when (RFC 3339 time)
|
||||
@@ -326,6 +360,21 @@ type Pause struct {
|
||||
V int64 `json:"v,omitempty"`
|
||||
}
|
||||
|
||||
// PlacedBeside is a sibling repository placed as a plain directory under the workspace's beside directory.
|
||||
type PlacedBeside struct {
|
||||
Commit string `json:"commit"`
|
||||
Dir string `json:"dir"`
|
||||
Repository string `json:"repository"`
|
||||
}
|
||||
|
||||
// Program is a changed file that is a compiled program (issue 1577): its path, its executable format, and the commit of the branch that added it when the merge's tree no longer holds it.
|
||||
type Program struct {
|
||||
Commit string `json:"commit,omitempty"`
|
||||
// ELF, Mach-O or PE
|
||||
Kind string `json:"kind"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// Step is one step a build module runs on a node.
|
||||
type Step struct {
|
||||
// when (RFC 3339 time)
|
||||
@@ -409,10 +458,10 @@ type StepResult struct {
|
||||
Artifacts []BuiltArtifact `json:"artifacts,omitempty"`
|
||||
Built bool `json:"built,omitempty"`
|
||||
// the holder declined the ask: its node lacks what the ask needs
|
||||
Declined bool `json:"declined,omitempty"`
|
||||
Fetch *Fetch `json:"fetch,omitempty"`
|
||||
Imports []string `json:"imports,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Declined bool `json:"declined,omitempty"`
|
||||
Fetch *FetchAnswer `json:"fetch,omitempty"`
|
||||
Imports []string `json:"imports,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
// what the holder's node lacks of it
|
||||
Lacks []string `json:"lacks,omitempty"`
|
||||
Levels []LevelAnswer `json:"levels,omitempty"`
|
||||
@@ -424,6 +473,17 @@ type StepResult struct {
|
||||
Verdict any `json:"verdict,omitempty"`
|
||||
}
|
||||
|
||||
// TakenVersion is of a directory whose go.mod requires an asked mesh package, the version it is built against: the asked one, or go.mod's when it names a newer one, said.
|
||||
type TakenVersion struct {
|
||||
Asked string `json:"asked"`
|
||||
Built string `json:"built"`
|
||||
Dir string `json:"dir"`
|
||||
Named string `json:"named"`
|
||||
Package string `json:"package"`
|
||||
Said string `json:"said,omitempty"`
|
||||
Sum string `json:"sum,omitempty"`
|
||||
}
|
||||
|
||||
// Toolchain is the toolchain a node reports.
|
||||
type Toolchain struct {
|
||||
// when (RFC 3339 time)
|
||||
|
||||
@@ -43,10 +43,12 @@ func TestFixtures(t *testing.T) {
|
||||
decode: func(b []byte) (any, error) { var v CheckAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.accept\\.check$")},
|
||||
{name: "a finished build step with its artifacts", subject: "", given: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a finished check step with its levels", subject: "", given: "{\"ended\":\"2026-11-05T10:06:00Z\",\"id\":\"c3d4\",\"node\":\"ace\",\"result\":{\"fetch\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-catalog\"},\"levels\":[{\"digest\":{\"level\":\"unit\",\"packages\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\"}]},\"kept\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\",\"tests\":12}],\"level\":\"unit\",\"tests\":[{\"package\":\"./modules/b\",\"pass\":true}],\"unmet\":[{\"needs\":[\"docker\"],\"package\":\"./modules/c\"}]}]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:06:00Z\",\"id\":\"c3d4\",\"node\":\"ace\",\"result\":{\"fetch\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-catalog\"},\"levels\":[{\"digest\":{\"level\":\"unit\",\"packages\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\"}]},\"kept\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\",\"tests\":12}],\"level\":\"unit\",\"tests\":[{\"package\":\"./modules/b\",\"pass\":true}],\"unmet\":[{\"needs\":[\"docker\"],\"package\":\"./modules/c\"}]}]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
|
||||
{name: "a finished check step with its levels", subject: "", given: "{\"ended\":\"2026-11-05T10:06:00Z\",\"id\":\"c3d4\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"a.go\",\"modules/m/main.go\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"fedcba9876543210fedcba9876543210fedcba98\",\"modules\":[\".\"],\"trees\":{\"modules/m\":{\"locks\":{\"go.sum\":\"c5fc83c01e92404452b986527d239140ccf9a48b88e0c268fbf38c2e1429e9c9\"},\"manifest\":\"ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356\",\"tree\":\"1111111111111111111111111111111111111111\"}},\"workspace\":\"mvii1iwu5414e4\"},\"levels\":[{\"digest\":{\"level\":\"unit\",\"packages\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\"}]},\"kept\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\",\"tests\":12}],\"level\":\"unit\",\"tests\":[{\"package\":\"./modules/b\",\"pass\":true}],\"unmet\":[{\"needs\":[\"docker\"],\"package\":\"./modules/c\"}]}]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:06:00Z\",\"id\":\"c3d4\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"a.go\",\"modules/m/main.go\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"fedcba9876543210fedcba9876543210fedcba98\",\"modules\":[\".\"],\"trees\":{\"modules/m\":{\"locks\":{\"go.sum\":\"c5fc83c01e92404452b986527d239140ccf9a48b88e0c268fbf38c2e1429e9c9\"},\"manifest\":\"ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356\",\"tree\":\"1111111111111111111111111111111111111111\"}},\"workspace\":\"mvii1iwu5414e4\"},\"levels\":[{\"digest\":{\"level\":\"unit\",\"packages\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\"}]},\"kept\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\",\"tests\":12}],\"level\":\"unit\",\"tests\":[{\"package\":\"./modules/b\",\"pass\":true}],\"unmet\":[{\"needs\":[\"docker\"],\"package\":\"./modules/c\"}]}]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a declined step", subject: "", given: "{\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"declined\":true,\"lacks\":[\"docker\"],\"needs\":[\"docker\"]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"refused\",\"tool\":\"check\",\"v\":1}", wire: "{\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"declined\":true,\"lacks\":[\"docker\"],\"needs\":[\"docker\"]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"refused\",\"tool\":\"check\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a finished check step whose head does not merge", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"conflicts\":[\"a.go\",\"sub/b.go\"],\"modules\":[\".\"],\"workspace\":\"mvii1iwz5050eb\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"conflicts\":[\"a.go\",\"sub/b.go\"],\"modules\":[\".\"],\"workspace\":\"mvii1iwz5050eb\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
}
|
||||
for _, c := range cases {
|
||||
v, err := c.decode([]byte(c.given))
|
||||
|
||||
@@ -233,7 +233,7 @@ type Capacity struct {
|
||||
|
||||
// CheckAnswer is a type of the contract.
|
||||
type CheckAnswer struct {
|
||||
Fetch Fetch `json:"fetch"`
|
||||
Fetch FetchAnswer `json:"fetch"`
|
||||
Levels []LevelAnswer `json:"levels,omitempty"`
|
||||
}
|
||||
|
||||
@@ -271,6 +271,30 @@ type Fetch struct {
|
||||
Repository string `json:"repository"`
|
||||
}
|
||||
|
||||
// FetchAnswer is what a build module's fetch tool answers, whole: the workspace it made, the commit in it, the module directories found; and, when the call gave a base, the merge preview (the trunk commit, the merge commit, the files that conflict, the paths the merge changes, the compiled programs among them, the tree of each module directory). A head that does not merge cleanly is an answer, not an error: merge is empty and conflicts names the files. The Go module adds the sibling repositories placed and the package versions taken; the TypeScript module the directories installed and refused and the group's package.
|
||||
type FetchAnswer struct {
|
||||
Base string `json:"base,omitempty"`
|
||||
Beside []PlacedBeside `json:"beside,omitempty"`
|
||||
Changed []string `json:"changed,omitempty"`
|
||||
Commit string `json:"commit"`
|
||||
Conflicts []string `json:"conflicts,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Installed []string `json:"installed,omitempty"`
|
||||
Merge string `json:"merge,omitempty"`
|
||||
Modules []string `json:"modules"`
|
||||
Packages []TakenVersion `json:"packages,omitempty"`
|
||||
Programs []Program `json:"programs,omitempty"`
|
||||
Refused []FetchRefusal `json:"refused,omitempty"`
|
||||
Trees map[string]ModuleTree `json:"trees,omitempty"`
|
||||
Workspace string `json:"workspace"`
|
||||
}
|
||||
|
||||
// FetchRefusal is a TypeScript module whose packages the fetch did not install, with why.
|
||||
type FetchRefusal struct {
|
||||
Module string `json:"module"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// LevelAnswerDigestNeedsItem is a type of the contract.
|
||||
type LevelAnswerDigestNeedsItem struct {
|
||||
Needs []string `json:"needs,omitempty"`
|
||||
@@ -316,6 +340,16 @@ type LevelAnswer struct {
|
||||
Unmet []LevelAnswerUnmetItem `json:"unmet,omitempty"`
|
||||
}
|
||||
|
||||
// ModuleTree is the tree of one module directory in a merge preview: its git tree, the digest of its manifest, the lock files' digests and the digests of the named paths.
|
||||
type ModuleTree struct {
|
||||
Locks map[string]string `json:"locks,omitempty"`
|
||||
Manifest string `json:"manifest"`
|
||||
// no longer filled (ADR 0593 section 2); kept so a preview written before still reads
|
||||
Packages []string `json:"packages,omitempty"`
|
||||
Paths map[string]string `json:"paths,omitempty"`
|
||||
Tree string `json:"tree"`
|
||||
}
|
||||
|
||||
// Pause is whether the node takes no new ask.
|
||||
type Pause struct {
|
||||
// when (RFC 3339 time)
|
||||
@@ -326,6 +360,21 @@ type Pause struct {
|
||||
V int64 `json:"v,omitempty"`
|
||||
}
|
||||
|
||||
// PlacedBeside is a sibling repository placed as a plain directory under the workspace's beside directory.
|
||||
type PlacedBeside struct {
|
||||
Commit string `json:"commit"`
|
||||
Dir string `json:"dir"`
|
||||
Repository string `json:"repository"`
|
||||
}
|
||||
|
||||
// Program is a changed file that is a compiled program (issue 1577): its path, its executable format, and the commit of the branch that added it when the merge's tree no longer holds it.
|
||||
type Program struct {
|
||||
Commit string `json:"commit,omitempty"`
|
||||
// ELF, Mach-O or PE
|
||||
Kind string `json:"kind"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// Step is one step a build module runs on a node.
|
||||
type Step struct {
|
||||
// when (RFC 3339 time)
|
||||
@@ -409,10 +458,10 @@ type StepResult struct {
|
||||
Artifacts []BuiltArtifact `json:"artifacts,omitempty"`
|
||||
Built bool `json:"built,omitempty"`
|
||||
// the holder declined the ask: its node lacks what the ask needs
|
||||
Declined bool `json:"declined,omitempty"`
|
||||
Fetch *Fetch `json:"fetch,omitempty"`
|
||||
Imports []string `json:"imports,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Declined bool `json:"declined,omitempty"`
|
||||
Fetch *FetchAnswer `json:"fetch,omitempty"`
|
||||
Imports []string `json:"imports,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
// what the holder's node lacks of it
|
||||
Lacks []string `json:"lacks,omitempty"`
|
||||
Levels []LevelAnswer `json:"levels,omitempty"`
|
||||
@@ -424,6 +473,17 @@ type StepResult struct {
|
||||
Verdict any `json:"verdict,omitempty"`
|
||||
}
|
||||
|
||||
// TakenVersion is of a directory whose go.mod requires an asked mesh package, the version it is built against: the asked one, or go.mod's when it names a newer one, said.
|
||||
type TakenVersion struct {
|
||||
Asked string `json:"asked"`
|
||||
Built string `json:"built"`
|
||||
Dir string `json:"dir"`
|
||||
Named string `json:"named"`
|
||||
Package string `json:"package"`
|
||||
Said string `json:"said,omitempty"`
|
||||
Sum string `json:"sum,omitempty"`
|
||||
}
|
||||
|
||||
// Toolchain is the toolchain a node reports.
|
||||
type Toolchain struct {
|
||||
// when (RFC 3339 time)
|
||||
|
||||
@@ -233,7 +233,7 @@ type Capacity struct {
|
||||
|
||||
// CheckAnswer is a type of the contract.
|
||||
type CheckAnswer struct {
|
||||
Fetch Fetch `json:"fetch"`
|
||||
Fetch FetchAnswer `json:"fetch"`
|
||||
Levels []LevelAnswer `json:"levels,omitempty"`
|
||||
}
|
||||
|
||||
@@ -271,6 +271,30 @@ type Fetch struct {
|
||||
Repository string `json:"repository"`
|
||||
}
|
||||
|
||||
// FetchAnswer is what a build module's fetch tool answers, whole: the workspace it made, the commit in it, the module directories found; and, when the call gave a base, the merge preview (the trunk commit, the merge commit, the files that conflict, the paths the merge changes, the compiled programs among them, the tree of each module directory). A head that does not merge cleanly is an answer, not an error: merge is empty and conflicts names the files. The Go module adds the sibling repositories placed and the package versions taken; the TypeScript module the directories installed and refused and the group's package.
|
||||
type FetchAnswer struct {
|
||||
Base string `json:"base,omitempty"`
|
||||
Beside []PlacedBeside `json:"beside,omitempty"`
|
||||
Changed []string `json:"changed,omitempty"`
|
||||
Commit string `json:"commit"`
|
||||
Conflicts []string `json:"conflicts,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Installed []string `json:"installed,omitempty"`
|
||||
Merge string `json:"merge,omitempty"`
|
||||
Modules []string `json:"modules"`
|
||||
Packages []TakenVersion `json:"packages,omitempty"`
|
||||
Programs []Program `json:"programs,omitempty"`
|
||||
Refused []FetchRefusal `json:"refused,omitempty"`
|
||||
Trees map[string]ModuleTree `json:"trees,omitempty"`
|
||||
Workspace string `json:"workspace"`
|
||||
}
|
||||
|
||||
// FetchRefusal is a TypeScript module whose packages the fetch did not install, with why.
|
||||
type FetchRefusal struct {
|
||||
Module string `json:"module"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// LevelAnswerDigestNeedsItem is a type of the contract.
|
||||
type LevelAnswerDigestNeedsItem struct {
|
||||
Needs []string `json:"needs,omitempty"`
|
||||
@@ -316,6 +340,16 @@ type LevelAnswer struct {
|
||||
Unmet []LevelAnswerUnmetItem `json:"unmet,omitempty"`
|
||||
}
|
||||
|
||||
// ModuleTree is the tree of one module directory in a merge preview: its git tree, the digest of its manifest, the lock files' digests and the digests of the named paths.
|
||||
type ModuleTree struct {
|
||||
Locks map[string]string `json:"locks,omitempty"`
|
||||
Manifest string `json:"manifest"`
|
||||
// no longer filled (ADR 0593 section 2); kept so a preview written before still reads
|
||||
Packages []string `json:"packages,omitempty"`
|
||||
Paths map[string]string `json:"paths,omitempty"`
|
||||
Tree string `json:"tree"`
|
||||
}
|
||||
|
||||
// Pause is whether the node takes no new ask.
|
||||
type Pause struct {
|
||||
// when (RFC 3339 time)
|
||||
@@ -326,6 +360,21 @@ type Pause struct {
|
||||
V int64 `json:"v,omitempty"`
|
||||
}
|
||||
|
||||
// PlacedBeside is a sibling repository placed as a plain directory under the workspace's beside directory.
|
||||
type PlacedBeside struct {
|
||||
Commit string `json:"commit"`
|
||||
Dir string `json:"dir"`
|
||||
Repository string `json:"repository"`
|
||||
}
|
||||
|
||||
// Program is a changed file that is a compiled program (issue 1577): its path, its executable format, and the commit of the branch that added it when the merge's tree no longer holds it.
|
||||
type Program struct {
|
||||
Commit string `json:"commit,omitempty"`
|
||||
// ELF, Mach-O or PE
|
||||
Kind string `json:"kind"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// Step is one step a build module runs on a node.
|
||||
type Step struct {
|
||||
// when (RFC 3339 time)
|
||||
@@ -409,10 +458,10 @@ type StepResult struct {
|
||||
Artifacts []BuiltArtifact `json:"artifacts,omitempty"`
|
||||
Built bool `json:"built,omitempty"`
|
||||
// the holder declined the ask: its node lacks what the ask needs
|
||||
Declined bool `json:"declined,omitempty"`
|
||||
Fetch *Fetch `json:"fetch,omitempty"`
|
||||
Imports []string `json:"imports,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Declined bool `json:"declined,omitempty"`
|
||||
Fetch *FetchAnswer `json:"fetch,omitempty"`
|
||||
Imports []string `json:"imports,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
// what the holder's node lacks of it
|
||||
Lacks []string `json:"lacks,omitempty"`
|
||||
Levels []LevelAnswer `json:"levels,omitempty"`
|
||||
@@ -424,6 +473,17 @@ type StepResult struct {
|
||||
Verdict any `json:"verdict,omitempty"`
|
||||
}
|
||||
|
||||
// TakenVersion is of a directory whose go.mod requires an asked mesh package, the version it is built against: the asked one, or go.mod's when it names a newer one, said.
|
||||
type TakenVersion struct {
|
||||
Asked string `json:"asked"`
|
||||
Built string `json:"built"`
|
||||
Dir string `json:"dir"`
|
||||
Named string `json:"named"`
|
||||
Package string `json:"package"`
|
||||
Said string `json:"said,omitempty"`
|
||||
Sum string `json:"sum,omitempty"`
|
||||
}
|
||||
|
||||
// Toolchain is the toolchain a node reports.
|
||||
type Toolchain struct {
|
||||
// when (RFC 3339 time)
|
||||
|
||||
@@ -39,6 +39,8 @@ func TestFixtures(t *testing.T) {
|
||||
}, subjectIs: nil},
|
||||
{name: "a build ask", subject: "mesh.seat.node-build-node.accept.delivery", given: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b2\",\"kind\":\"build\",\"language\":\"go\"}", wire: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b2\",\"kind\":\"build\",\"language\":\"go\"}",
|
||||
decode: func(b []byte) (any, error) { var v DeliveryAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.accept\\.delivery$")},
|
||||
{name: "a finished check step of a TypeScript merge preview", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d6\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"modules/m/package.json\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"0123456789abcdef0123456789abcdef01234567\",\"modules\":[\"modules/m\"],\"trees\":{\"modules/m\":{\"manifest\":\"0581b699d9d05517e69b21f5cedbeb2eee8aba2b205280b561be731594d7feef\",\"tree\":\"0123456789abcdef0123456789abcdef01234567\"}},\"workspace\":\"mvii1sxt979f67\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d6\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"modules/m/package.json\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"0123456789abcdef0123456789abcdef01234567\",\"modules\":[\"modules/m\"],\"trees\":{\"modules/m\":{\"manifest\":\"0581b699d9d05517e69b21f5cedbeb2eee8aba2b205280b561be731594d7feef\",\"tree\":\"0123456789abcdef0123456789abcdef01234567\"}},\"workspace\":\"mvii1sxt979f67\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
}
|
||||
for _, c := range cases {
|
||||
v, err := c.decode([]byte(c.given))
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fetch": {
|
||||
"$ref": "#/defs/Fetch"
|
||||
"$ref": "#/defs/FetchAnswer"
|
||||
},
|
||||
"levels": {
|
||||
"type": "array",
|
||||
@@ -691,7 +691,7 @@
|
||||
}
|
||||
},
|
||||
"fetch": {
|
||||
"$ref": "#/defs/Fetch"
|
||||
"$ref": "#/defs/FetchAnswer"
|
||||
},
|
||||
"levels": {
|
||||
"type": "array",
|
||||
@@ -727,6 +727,211 @@
|
||||
"description": "what the holder's node lacks of it"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ModuleTree": {
|
||||
"type": "object",
|
||||
"description": "the tree of one module directory in a merge preview: its git tree, the digest of its manifest, the lock files' digests and the digests of the named paths",
|
||||
"properties": {
|
||||
"tree": {
|
||||
"type": "string"
|
||||
},
|
||||
"manifest": {
|
||||
"type": "string"
|
||||
},
|
||||
"locks": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"packages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "no longer filled (ADR 0593 section 2); kept so a preview written before still reads"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"tree",
|
||||
"manifest"
|
||||
]
|
||||
},
|
||||
"Program": {
|
||||
"type": "object",
|
||||
"description": "a changed file that is a compiled program (issue 1577): its path, its executable format, and the commit of the branch that added it when the merge's tree no longer holds it",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "ELF, Mach-O or PE"
|
||||
},
|
||||
"commit": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"kind"
|
||||
]
|
||||
},
|
||||
"PlacedBeside": {
|
||||
"type": "object",
|
||||
"description": "a sibling repository placed as a plain directory under the workspace's beside directory",
|
||||
"properties": {
|
||||
"repository": {
|
||||
"type": "string"
|
||||
},
|
||||
"commit": {
|
||||
"type": "string"
|
||||
},
|
||||
"dir": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"repository",
|
||||
"commit",
|
||||
"dir"
|
||||
]
|
||||
},
|
||||
"TakenVersion": {
|
||||
"type": "object",
|
||||
"description": "of a directory whose go.mod requires an asked mesh package, the version it is built against: the asked one, or go.mod's when it names a newer one, said",
|
||||
"properties": {
|
||||
"dir": {
|
||||
"type": "string"
|
||||
},
|
||||
"package": {
|
||||
"type": "string"
|
||||
},
|
||||
"asked": {
|
||||
"type": "string"
|
||||
},
|
||||
"named": {
|
||||
"type": "string"
|
||||
},
|
||||
"built": {
|
||||
"type": "string"
|
||||
},
|
||||
"sum": {
|
||||
"type": "string"
|
||||
},
|
||||
"said": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"dir",
|
||||
"package",
|
||||
"asked",
|
||||
"named",
|
||||
"built"
|
||||
]
|
||||
},
|
||||
"FetchRefusal": {
|
||||
"type": "object",
|
||||
"description": "a TypeScript module whose packages the fetch did not install, with why",
|
||||
"properties": {
|
||||
"module": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"module",
|
||||
"reason"
|
||||
]
|
||||
},
|
||||
"FetchAnswer": {
|
||||
"type": "object",
|
||||
"description": "what a build module's fetch tool answers, whole: the workspace it made, the commit in it, the module directories found; and, when the call gave a base, the merge preview (the trunk commit, the merge commit, the files that conflict, the paths the merge changes, the compiled programs among them, the tree of each module directory). A head that does not merge cleanly is an answer, not an error: merge is empty and conflicts names the files. The Go module adds the sibling repositories placed and the package versions taken; the TypeScript module the directories installed and refused and the group's package",
|
||||
"properties": {
|
||||
"workspace": {
|
||||
"type": "string"
|
||||
},
|
||||
"commit": {
|
||||
"type": "string"
|
||||
},
|
||||
"modules": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"base": {
|
||||
"type": "string"
|
||||
},
|
||||
"merge": {
|
||||
"type": "string"
|
||||
},
|
||||
"conflicts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"changed": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"programs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/defs/Program"
|
||||
}
|
||||
},
|
||||
"trees": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/defs/ModuleTree"
|
||||
}
|
||||
},
|
||||
"beside": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/defs/PlacedBeside"
|
||||
}
|
||||
},
|
||||
"packages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/defs/TakenVersion"
|
||||
}
|
||||
},
|
||||
"installed": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"refused": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/defs/FetchRefusal"
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"workspace",
|
||||
"commit",
|
||||
"modules"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,8 +147,26 @@
|
||||
"ended": "2026-11-05T10:06:00Z",
|
||||
"result": {
|
||||
"fetch": {
|
||||
"repository": "novox/mesh-catalog",
|
||||
"commit": "0123456789abcdef0123456789abcdef01234567"
|
||||
"workspace": "mvii1iwu5414e4",
|
||||
"commit": "0123456789abcdef0123456789abcdef01234567",
|
||||
"modules": [
|
||||
"."
|
||||
],
|
||||
"base": "abcdef0123456789abcdef0123456789abcdef01",
|
||||
"merge": "fedcba9876543210fedcba9876543210fedcba98",
|
||||
"changed": [
|
||||
"a.go",
|
||||
"modules/m/main.go"
|
||||
],
|
||||
"trees": {
|
||||
"modules/m": {
|
||||
"tree": "1111111111111111111111111111111111111111",
|
||||
"manifest": "ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356",
|
||||
"locks": {
|
||||
"go.sum": "c5fc83c01e92404452b986527d239140ccf9a48b88e0c268fbf38c2e1429e9c9"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
@@ -208,5 +226,32 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "a finished check step whose head does not merge",
|
||||
"of": "state:steps/<node>.<id>",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"id": "c3d5",
|
||||
"tool": "check",
|
||||
"node": "ace",
|
||||
"state": "passed",
|
||||
"started": "2026-11-05T10:00:00Z",
|
||||
"ended": "2026-11-05T10:01:00Z",
|
||||
"result": {
|
||||
"fetch": {
|
||||
"workspace": "mvii1iwz5050eb",
|
||||
"commit": "0123456789abcdef0123456789abcdef01234567",
|
||||
"modules": [
|
||||
"."
|
||||
],
|
||||
"base": "abcdef0123456789abcdef0123456789abcdef01",
|
||||
"conflicts": [
|
||||
"a.go",
|
||||
"sub/b.go"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -59,5 +59,38 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "a finished check step of a TypeScript merge preview",
|
||||
"of": "state:steps/<node>.<id>",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"id": "c3d6",
|
||||
"tool": "check",
|
||||
"node": "ace",
|
||||
"state": "passed",
|
||||
"started": "2026-11-05T10:00:00Z",
|
||||
"ended": "2026-11-05T10:01:00Z",
|
||||
"result": {
|
||||
"fetch": {
|
||||
"workspace": "mvii1sxt979f67",
|
||||
"commit": "0123456789abcdef0123456789abcdef01234567",
|
||||
"modules": [
|
||||
"modules/m"
|
||||
],
|
||||
"base": "abcdef0123456789abcdef0123456789abcdef01",
|
||||
"merge": "0123456789abcdef0123456789abcdef01234567",
|
||||
"changed": [
|
||||
"modules/m/package.json"
|
||||
],
|
||||
"trees": {
|
||||
"modules/m": {
|
||||
"tree": "0123456789abcdef0123456789abcdef01234567",
|
||||
"manifest": "0581b699d9d05517e69b21f5cedbeb2eee8aba2b205280b561be731594d7feef"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -111,16 +111,21 @@ export type ComposeAnswer = buildStep.ComposeAnswer;
|
||||
export type CurrentAnswer = buildStep.CurrentAnswer;
|
||||
export type CurrentInput = buildStep.CurrentInput;
|
||||
export type Fetch = buildStep.Fetch;
|
||||
export type FetchAnswer = buildStep.FetchAnswer;
|
||||
export type FetchBesideItem = buildStep.FetchBesideItem;
|
||||
export type FetchRefusal = buildStep.FetchRefusal;
|
||||
export type LevelAnswer = buildStep.LevelAnswer;
|
||||
export type LevelAnswerDigest = buildStep.LevelAnswerDigest;
|
||||
export type LevelAnswerDigestNeedsItem = buildStep.LevelAnswerDigestNeedsItem;
|
||||
export type LevelAnswerDigestPackagesItem = buildStep.LevelAnswerDigestPackagesItem;
|
||||
export type LevelAnswerKeptItem = buildStep.LevelAnswerKeptItem;
|
||||
export type LevelAnswerUnmetItem = buildStep.LevelAnswerUnmetItem;
|
||||
export type ModuleTree = buildStep.ModuleTree;
|
||||
export type Pause = buildStep.Pause;
|
||||
export type PauseAnswer = buildStep.PauseAnswer;
|
||||
export type PauseInput = buildStep.PauseInput;
|
||||
export type PlacedBeside = buildStep.PlacedBeside;
|
||||
export type Program = buildStep.Program;
|
||||
export type ResumeAnswer = buildStep.ResumeAnswer;
|
||||
export type ResumeInput = buildStep.ResumeInput;
|
||||
export type Step = buildStep.Step;
|
||||
@@ -129,6 +134,7 @@ export type StepAskBuild = buildStep.StepAskBuild;
|
||||
export type StepAskCheck = buildStep.StepAskCheck;
|
||||
export type StepAskCompose = buildStep.StepAskCompose;
|
||||
export type StepResult = buildStep.StepResult;
|
||||
export type TakenVersion = buildStep.TakenVersion;
|
||||
export type Toolchain = buildStep.Toolchain;
|
||||
export type ToolchainUsed = buildStep.ToolchainUsed;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ export interface Capacity {
|
||||
}
|
||||
|
||||
export interface CheckAnswer {
|
||||
"fetch": Fetch;
|
||||
"fetch": FetchAnswer;
|
||||
"levels"?: LevelAnswer[];
|
||||
}
|
||||
|
||||
@@ -87,6 +87,30 @@ export interface Fetch {
|
||||
"repository": string;
|
||||
}
|
||||
|
||||
/** what a build module's fetch tool answers, whole: the workspace it made, the commit in it, the module directories found; and, when the call gave a base, the merge preview (the trunk commit, the merge commit, the files that conflict, the paths the merge changes, the compiled programs among them, the tree of each module directory). A head that does not merge cleanly is an answer, not an error: merge is empty and conflicts names the files. The Go module adds the sibling repositories placed and the package versions taken; the TypeScript module the directories installed and refused and the group's package */
|
||||
export interface FetchAnswer {
|
||||
"base"?: string;
|
||||
"beside"?: PlacedBeside[];
|
||||
"changed"?: string[];
|
||||
"commit": string;
|
||||
"conflicts"?: string[];
|
||||
"group"?: string;
|
||||
"installed"?: string[];
|
||||
"merge"?: string;
|
||||
"modules": string[];
|
||||
"packages"?: TakenVersion[];
|
||||
"programs"?: Program[];
|
||||
"refused"?: FetchRefusal[];
|
||||
"trees"?: Record<string, ModuleTree>;
|
||||
"workspace": string;
|
||||
}
|
||||
|
||||
/** a TypeScript module whose packages the fetch did not install, with why */
|
||||
export interface FetchRefusal {
|
||||
"module": string;
|
||||
"reason": string;
|
||||
}
|
||||
|
||||
export interface LevelAnswerDigestNeedsItem {
|
||||
"needs"?: string[];
|
||||
"package"?: string;
|
||||
@@ -127,6 +151,16 @@ export interface LevelAnswer {
|
||||
"unmet"?: LevelAnswerUnmetItem[];
|
||||
}
|
||||
|
||||
/** the tree of one module directory in a merge preview: its git tree, the digest of its manifest, the lock files' digests and the digests of the named paths */
|
||||
export interface ModuleTree {
|
||||
"locks"?: Record<string, string>;
|
||||
"manifest": string;
|
||||
/** no longer filled (ADR 0593 section 2); kept so a preview written before still reads */
|
||||
"packages"?: string[];
|
||||
"paths"?: Record<string, string>;
|
||||
"tree": string;
|
||||
}
|
||||
|
||||
/** whether the node takes no new ask */
|
||||
export interface Pause {
|
||||
/** when (RFC 3339 time) */
|
||||
@@ -137,6 +171,21 @@ export interface Pause {
|
||||
"v"?: number;
|
||||
}
|
||||
|
||||
/** a sibling repository placed as a plain directory under the workspace's beside directory */
|
||||
export interface PlacedBeside {
|
||||
"commit": string;
|
||||
"dir": string;
|
||||
"repository": string;
|
||||
}
|
||||
|
||||
/** a changed file that is a compiled program (issue 1577): its path, its executable format, and the commit of the branch that added it when the merge's tree no longer holds it */
|
||||
export interface Program {
|
||||
"commit"?: string;
|
||||
/** ELF, Mach-O or PE */
|
||||
"kind": string;
|
||||
"path": string;
|
||||
}
|
||||
|
||||
/** one step a build module runs on a node */
|
||||
export interface Step {
|
||||
/** when (RFC 3339 time) */
|
||||
@@ -218,7 +267,7 @@ export interface StepResult {
|
||||
"built"?: boolean;
|
||||
/** the holder declined the ask: its node lacks what the ask needs */
|
||||
"declined"?: boolean;
|
||||
"fetch"?: Fetch;
|
||||
"fetch"?: FetchAnswer;
|
||||
"imports"?: string[];
|
||||
"key"?: string;
|
||||
/** what the holder's node lacks of it */
|
||||
@@ -232,6 +281,17 @@ export interface StepResult {
|
||||
"verdict"?: unknown;
|
||||
}
|
||||
|
||||
/** of a directory whose go.mod requires an asked mesh package, the version it is built against: the asked one, or go.mod's when it names a newer one, said */
|
||||
export interface TakenVersion {
|
||||
"asked": string;
|
||||
"built": string;
|
||||
"dir": string;
|
||||
"named": string;
|
||||
"package": string;
|
||||
"said"?: string;
|
||||
"sum"?: string;
|
||||
}
|
||||
|
||||
/** the toolchain a node reports */
|
||||
export interface Toolchain {
|
||||
/** when (RFC 3339 time) */
|
||||
|
||||
@@ -111,16 +111,21 @@ export type ComposeAnswer = buildStep.ComposeAnswer;
|
||||
export type CurrentAnswer = buildStep.CurrentAnswer;
|
||||
export type CurrentInput = buildStep.CurrentInput;
|
||||
export type Fetch = buildStep.Fetch;
|
||||
export type FetchAnswer = buildStep.FetchAnswer;
|
||||
export type FetchBesideItem = buildStep.FetchBesideItem;
|
||||
export type FetchRefusal = buildStep.FetchRefusal;
|
||||
export type LevelAnswer = buildStep.LevelAnswer;
|
||||
export type LevelAnswerDigest = buildStep.LevelAnswerDigest;
|
||||
export type LevelAnswerDigestNeedsItem = buildStep.LevelAnswerDigestNeedsItem;
|
||||
export type LevelAnswerDigestPackagesItem = buildStep.LevelAnswerDigestPackagesItem;
|
||||
export type LevelAnswerKeptItem = buildStep.LevelAnswerKeptItem;
|
||||
export type LevelAnswerUnmetItem = buildStep.LevelAnswerUnmetItem;
|
||||
export type ModuleTree = buildStep.ModuleTree;
|
||||
export type Pause = buildStep.Pause;
|
||||
export type PauseAnswer = buildStep.PauseAnswer;
|
||||
export type PauseInput = buildStep.PauseInput;
|
||||
export type PlacedBeside = buildStep.PlacedBeside;
|
||||
export type Program = buildStep.Program;
|
||||
export type ResumeAnswer = buildStep.ResumeAnswer;
|
||||
export type ResumeInput = buildStep.ResumeInput;
|
||||
export type Step = buildStep.Step;
|
||||
@@ -129,6 +134,7 @@ export type StepAskBuild = buildStep.StepAskBuild;
|
||||
export type StepAskCheck = buildStep.StepAskCheck;
|
||||
export type StepAskCompose = buildStep.StepAskCompose;
|
||||
export type StepResult = buildStep.StepResult;
|
||||
export type TakenVersion = buildStep.TakenVersion;
|
||||
export type Toolchain = buildStep.Toolchain;
|
||||
export type ToolchainUsed = buildStep.ToolchainUsed;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ export interface Capacity {
|
||||
}
|
||||
|
||||
export interface CheckAnswer {
|
||||
"fetch": Fetch;
|
||||
"fetch": FetchAnswer;
|
||||
"levels"?: LevelAnswer[];
|
||||
}
|
||||
|
||||
@@ -87,6 +87,30 @@ export interface Fetch {
|
||||
"repository": string;
|
||||
}
|
||||
|
||||
/** what a build module's fetch tool answers, whole: the workspace it made, the commit in it, the module directories found; and, when the call gave a base, the merge preview (the trunk commit, the merge commit, the files that conflict, the paths the merge changes, the compiled programs among them, the tree of each module directory). A head that does not merge cleanly is an answer, not an error: merge is empty and conflicts names the files. The Go module adds the sibling repositories placed and the package versions taken; the TypeScript module the directories installed and refused and the group's package */
|
||||
export interface FetchAnswer {
|
||||
"base"?: string;
|
||||
"beside"?: PlacedBeside[];
|
||||
"changed"?: string[];
|
||||
"commit": string;
|
||||
"conflicts"?: string[];
|
||||
"group"?: string;
|
||||
"installed"?: string[];
|
||||
"merge"?: string;
|
||||
"modules": string[];
|
||||
"packages"?: TakenVersion[];
|
||||
"programs"?: Program[];
|
||||
"refused"?: FetchRefusal[];
|
||||
"trees"?: Record<string, ModuleTree>;
|
||||
"workspace": string;
|
||||
}
|
||||
|
||||
/** a TypeScript module whose packages the fetch did not install, with why */
|
||||
export interface FetchRefusal {
|
||||
"module": string;
|
||||
"reason": string;
|
||||
}
|
||||
|
||||
export interface LevelAnswerDigestNeedsItem {
|
||||
"needs"?: string[];
|
||||
"package"?: string;
|
||||
@@ -127,6 +151,16 @@ export interface LevelAnswer {
|
||||
"unmet"?: LevelAnswerUnmetItem[];
|
||||
}
|
||||
|
||||
/** the tree of one module directory in a merge preview: its git tree, the digest of its manifest, the lock files' digests and the digests of the named paths */
|
||||
export interface ModuleTree {
|
||||
"locks"?: Record<string, string>;
|
||||
"manifest": string;
|
||||
/** no longer filled (ADR 0593 section 2); kept so a preview written before still reads */
|
||||
"packages"?: string[];
|
||||
"paths"?: Record<string, string>;
|
||||
"tree": string;
|
||||
}
|
||||
|
||||
/** whether the node takes no new ask */
|
||||
export interface Pause {
|
||||
/** when (RFC 3339 time) */
|
||||
@@ -137,6 +171,21 @@ export interface Pause {
|
||||
"v"?: number;
|
||||
}
|
||||
|
||||
/** a sibling repository placed as a plain directory under the workspace's beside directory */
|
||||
export interface PlacedBeside {
|
||||
"commit": string;
|
||||
"dir": string;
|
||||
"repository": string;
|
||||
}
|
||||
|
||||
/** a changed file that is a compiled program (issue 1577): its path, its executable format, and the commit of the branch that added it when the merge's tree no longer holds it */
|
||||
export interface Program {
|
||||
"commit"?: string;
|
||||
/** ELF, Mach-O or PE */
|
||||
"kind": string;
|
||||
"path": string;
|
||||
}
|
||||
|
||||
/** one step a build module runs on a node */
|
||||
export interface Step {
|
||||
/** when (RFC 3339 time) */
|
||||
@@ -218,7 +267,7 @@ export interface StepResult {
|
||||
"built"?: boolean;
|
||||
/** the holder declined the ask: its node lacks what the ask needs */
|
||||
"declined"?: boolean;
|
||||
"fetch"?: Fetch;
|
||||
"fetch"?: FetchAnswer;
|
||||
"imports"?: string[];
|
||||
"key"?: string;
|
||||
/** what the holder's node lacks of it */
|
||||
@@ -232,6 +281,17 @@ export interface StepResult {
|
||||
"verdict"?: unknown;
|
||||
}
|
||||
|
||||
/** of a directory whose go.mod requires an asked mesh package, the version it is built against: the asked one, or go.mod's when it names a newer one, said */
|
||||
export interface TakenVersion {
|
||||
"asked": string;
|
||||
"built": string;
|
||||
"dir": string;
|
||||
"named": string;
|
||||
"package": string;
|
||||
"said"?: string;
|
||||
"sum"?: string;
|
||||
}
|
||||
|
||||
/** the toolchain a node reports */
|
||||
export interface Toolchain {
|
||||
/** when (RFC 3339 time) */
|
||||
|
||||
@@ -111,16 +111,21 @@ export type ComposeAnswer = buildStep.ComposeAnswer;
|
||||
export type CurrentAnswer = buildStep.CurrentAnswer;
|
||||
export type CurrentInput = buildStep.CurrentInput;
|
||||
export type Fetch = buildStep.Fetch;
|
||||
export type FetchAnswer = buildStep.FetchAnswer;
|
||||
export type FetchBesideItem = buildStep.FetchBesideItem;
|
||||
export type FetchRefusal = buildStep.FetchRefusal;
|
||||
export type LevelAnswer = buildStep.LevelAnswer;
|
||||
export type LevelAnswerDigest = buildStep.LevelAnswerDigest;
|
||||
export type LevelAnswerDigestNeedsItem = buildStep.LevelAnswerDigestNeedsItem;
|
||||
export type LevelAnswerDigestPackagesItem = buildStep.LevelAnswerDigestPackagesItem;
|
||||
export type LevelAnswerKeptItem = buildStep.LevelAnswerKeptItem;
|
||||
export type LevelAnswerUnmetItem = buildStep.LevelAnswerUnmetItem;
|
||||
export type ModuleTree = buildStep.ModuleTree;
|
||||
export type Pause = buildStep.Pause;
|
||||
export type PauseAnswer = buildStep.PauseAnswer;
|
||||
export type PauseInput = buildStep.PauseInput;
|
||||
export type PlacedBeside = buildStep.PlacedBeside;
|
||||
export type Program = buildStep.Program;
|
||||
export type ResumeAnswer = buildStep.ResumeAnswer;
|
||||
export type ResumeInput = buildStep.ResumeInput;
|
||||
export type Step = buildStep.Step;
|
||||
@@ -129,6 +134,7 @@ export type StepAskBuild = buildStep.StepAskBuild;
|
||||
export type StepAskCheck = buildStep.StepAskCheck;
|
||||
export type StepAskCompose = buildStep.StepAskCompose;
|
||||
export type StepResult = buildStep.StepResult;
|
||||
export type TakenVersion = buildStep.TakenVersion;
|
||||
export type Toolchain = buildStep.Toolchain;
|
||||
export type ToolchainUsed = buildStep.ToolchainUsed;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ export interface Capacity {
|
||||
}
|
||||
|
||||
export interface CheckAnswer {
|
||||
"fetch": Fetch;
|
||||
"fetch": FetchAnswer;
|
||||
"levels"?: LevelAnswer[];
|
||||
}
|
||||
|
||||
@@ -87,6 +87,30 @@ export interface Fetch {
|
||||
"repository": string;
|
||||
}
|
||||
|
||||
/** what a build module's fetch tool answers, whole: the workspace it made, the commit in it, the module directories found; and, when the call gave a base, the merge preview (the trunk commit, the merge commit, the files that conflict, the paths the merge changes, the compiled programs among them, the tree of each module directory). A head that does not merge cleanly is an answer, not an error: merge is empty and conflicts names the files. The Go module adds the sibling repositories placed and the package versions taken; the TypeScript module the directories installed and refused and the group's package */
|
||||
export interface FetchAnswer {
|
||||
"base"?: string;
|
||||
"beside"?: PlacedBeside[];
|
||||
"changed"?: string[];
|
||||
"commit": string;
|
||||
"conflicts"?: string[];
|
||||
"group"?: string;
|
||||
"installed"?: string[];
|
||||
"merge"?: string;
|
||||
"modules": string[];
|
||||
"packages"?: TakenVersion[];
|
||||
"programs"?: Program[];
|
||||
"refused"?: FetchRefusal[];
|
||||
"trees"?: Record<string, ModuleTree>;
|
||||
"workspace": string;
|
||||
}
|
||||
|
||||
/** a TypeScript module whose packages the fetch did not install, with why */
|
||||
export interface FetchRefusal {
|
||||
"module": string;
|
||||
"reason": string;
|
||||
}
|
||||
|
||||
export interface LevelAnswerDigestNeedsItem {
|
||||
"needs"?: string[];
|
||||
"package"?: string;
|
||||
@@ -127,6 +151,16 @@ export interface LevelAnswer {
|
||||
"unmet"?: LevelAnswerUnmetItem[];
|
||||
}
|
||||
|
||||
/** the tree of one module directory in a merge preview: its git tree, the digest of its manifest, the lock files' digests and the digests of the named paths */
|
||||
export interface ModuleTree {
|
||||
"locks"?: Record<string, string>;
|
||||
"manifest": string;
|
||||
/** no longer filled (ADR 0593 section 2); kept so a preview written before still reads */
|
||||
"packages"?: string[];
|
||||
"paths"?: Record<string, string>;
|
||||
"tree": string;
|
||||
}
|
||||
|
||||
/** whether the node takes no new ask */
|
||||
export interface Pause {
|
||||
/** when (RFC 3339 time) */
|
||||
@@ -137,6 +171,21 @@ export interface Pause {
|
||||
"v"?: number;
|
||||
}
|
||||
|
||||
/** a sibling repository placed as a plain directory under the workspace's beside directory */
|
||||
export interface PlacedBeside {
|
||||
"commit": string;
|
||||
"dir": string;
|
||||
"repository": string;
|
||||
}
|
||||
|
||||
/** a changed file that is a compiled program (issue 1577): its path, its executable format, and the commit of the branch that added it when the merge's tree no longer holds it */
|
||||
export interface Program {
|
||||
"commit"?: string;
|
||||
/** ELF, Mach-O or PE */
|
||||
"kind": string;
|
||||
"path": string;
|
||||
}
|
||||
|
||||
/** one step a build module runs on a node */
|
||||
export interface Step {
|
||||
/** when (RFC 3339 time) */
|
||||
@@ -218,7 +267,7 @@ export interface StepResult {
|
||||
"built"?: boolean;
|
||||
/** the holder declined the ask: its node lacks what the ask needs */
|
||||
"declined"?: boolean;
|
||||
"fetch"?: Fetch;
|
||||
"fetch"?: FetchAnswer;
|
||||
"imports"?: string[];
|
||||
"key"?: string;
|
||||
/** what the holder's node lacks of it */
|
||||
@@ -232,6 +281,17 @@ export interface StepResult {
|
||||
"verdict"?: unknown;
|
||||
}
|
||||
|
||||
/** of a directory whose go.mod requires an asked mesh package, the version it is built against: the asked one, or go.mod's when it names a newer one, said */
|
||||
export interface TakenVersion {
|
||||
"asked": string;
|
||||
"built": string;
|
||||
"dir": string;
|
||||
"named": string;
|
||||
"package": string;
|
||||
"said"?: string;
|
||||
"sum"?: string;
|
||||
}
|
||||
|
||||
/** the toolchain a node reports */
|
||||
export interface Toolchain {
|
||||
/** when (RFC 3339 time) */
|
||||
|
||||
+72
-1
@@ -526,10 +526,81 @@ type AskBuilt struct {
|
||||
|
||||
// CheckAnswer is what a check ask's step answers.
|
||||
type CheckAnswer struct {
|
||||
Fetch Fetch `json:"fetch"`
|
||||
Fetch FetchAnswer `json:"fetch"`
|
||||
Levels []LevelAnswer `json:"levels,omitempty"`
|
||||
}
|
||||
|
||||
// FetchAnswer is what a build module's fetch tool answers, whole: the part's `FetchAnswer`. A check keeps it as the
|
||||
// answer's fetch, so the checker reads a conflict (a head that does not merge is an answer, not an error), the changed
|
||||
// paths, the programs and the trees from it.
|
||||
type FetchAnswer struct {
|
||||
Workspace string `json:"workspace"`
|
||||
Commit string `json:"commit"`
|
||||
Modules []string `json:"modules"`
|
||||
// The merge preview, only when the call gave a base.
|
||||
Base string `json:"base,omitempty"`
|
||||
Merge string `json:"merge,omitempty"`
|
||||
Conflicts []string `json:"conflicts,omitempty"`
|
||||
Changed []string `json:"changed,omitempty"`
|
||||
Programs []Program `json:"programs,omitempty"`
|
||||
Trees map[string]ModuleTree `json:"trees,omitempty"`
|
||||
// The Go module's.
|
||||
Beside []PlacedBeside `json:"beside,omitempty"`
|
||||
Packages []TakenVersion `json:"packages,omitempty"`
|
||||
// The TypeScript module's.
|
||||
Installed []string `json:"installed,omitempty"`
|
||||
Refused []FetchRefusal `json:"refused,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
// Program is a changed file that is a compiled program (issue 1577).
|
||||
type Program struct {
|
||||
Path string `json:"path"`
|
||||
Kind string `json:"kind"` // ELF, Mach-O or PE
|
||||
Commit string `json:"commit,omitempty"`
|
||||
}
|
||||
|
||||
// PlacedBeside is a sibling repository placed as a plain directory under the workspace's beside directory.
|
||||
type PlacedBeside struct {
|
||||
Repository string `json:"repository"`
|
||||
Commit string `json:"commit"`
|
||||
Dir string `json:"dir"`
|
||||
}
|
||||
|
||||
// TakenVersion is, of a directory whose go.mod requires an asked mesh package, the version it is built against.
|
||||
type TakenVersion struct {
|
||||
Dir string `json:"dir"`
|
||||
Package string `json:"package"`
|
||||
Asked string `json:"asked"`
|
||||
Named string `json:"named"`
|
||||
Built string `json:"built"`
|
||||
Sum string `json:"sum,omitempty"`
|
||||
Said string `json:"said,omitempty"`
|
||||
}
|
||||
|
||||
// FetchRefusal is a TypeScript module whose packages the fetch did not install, with why.
|
||||
type FetchRefusal struct {
|
||||
Module string `json:"module"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// StepResult is what any step answered: one layout for the four kinds, as the seats' `StepResult` (the fields of the
|
||||
// kinds do not meet). A step's result bytes read into it strictly.
|
||||
type StepResult struct {
|
||||
Artifacts []AskBuilt `json:"artifacts,omitempty"`
|
||||
Toolchain *ToolchainUsed `json:"toolchain,omitempty"`
|
||||
Imports []string `json:"imports,omitempty"`
|
||||
OutOfStep []string `json:"out-of-step,omitempty"`
|
||||
Fetch *FetchAnswer `json:"fetch,omitempty"`
|
||||
Levels []LevelAnswer `json:"levels,omitempty"`
|
||||
Built bool `json:"built,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Verdict json.RawMessage `json:"verdict,omitempty"`
|
||||
Declined bool `json:"declined,omitempty"`
|
||||
Needs []string `json:"needs,omitempty"`
|
||||
Lacks []string `json:"lacks,omitempty"`
|
||||
}
|
||||
|
||||
// ComposeAnswer is what a compose ask's step answers.
|
||||
type ComposeAnswer struct {
|
||||
Built bool `json:"built"`
|
||||
|
||||
@@ -264,6 +264,11 @@ func TestTheThreeSeatsFixturesFitTheNeutralForms(t *testing.T) {
|
||||
case strings.HasPrefix(f.Of, "state:steps/"):
|
||||
seen++
|
||||
strict(t, f.Given, &Step{})
|
||||
var st Step
|
||||
if err := json.Unmarshal(f.Given, &st); err == nil && len(st.Result) > 0 {
|
||||
// a step's result keeps what the tool answered, whole (the fetch tool's answer too)
|
||||
strict(t, st.Result, &StepResult{})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user