Files
mesh-delivery/sdk/buildstep/toolchain.go
T
jschoubben 541eaa20fe
mesh/delivery merged: source.main moved to novox/mesh-delivery@21eaa55b277a
mesh/delivery-group group fix/47-G-bridge merged: every member is merged
mesh/check checking 541eaa20fec4 on 21eaa55b277a
Bridge for G's take-in: the pre-G package directories contracts/go and sdk again, unused
The running pre-G indexer publishes a repository's packages only when every package directory it published last is
still in the tree; G moved contracts/go and sdk to modules/, so mesh-delivery's packages, G's renamed paths among them,
are never published and nothing importing them builds (2026-11-13, indexer journal 'its packages are not published').
These are the trees of e70754ef, unchanged, without sdk/module.json (no second module). Nothing imports them; they go
once G's indexer runs and publishes without them.

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-13 14:34:40 +01:00

82 lines
2.7 KiB
Go

package buildstep
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"time"
)
// ToolchainVersion is the layout version of a toolchains value.
const ToolchainVersion = 1
// Toolchain is the value of a build module's state toolchains under the key <node>.<language>: the version of the
// language's toolchain installed on the node, the build module's recipe version, and when the module saw them. It is
// the part build-step's `Toolchain`, the layout every node-build seat gives that state; the three build modules share
// this neutral form (a seat's generated type is one package per seat). A test reads each seat's fixture strictly into it.
type Toolchain struct {
V int `json:"v,omitempty"`
Language string `json:"language"`
Version string `json:"version"`
Recipe string `json:"recipe"`
At time.Time `json:"at,omitzero"`
}
func checkToolchainLanguage(language string) error {
switch language {
case "go", "typescript":
return nil
}
return fmt.Errorf("buildstep: the toolchain language %q is not go or typescript", language)
}
// ToolchainKey is the key of a node's toolchain of one language: <node>.<language>. It refuses an empty node, a node
// with a dot and a language other than go or typescript.
func ToolchainKey(node, language string) (string, error) {
if node == "" || strings.ContainsAny(node, ". ") {
return "", fmt.Errorf("buildstep: %q is not a node name", node)
}
if err := checkToolchainLanguage(language); err != nil {
return "", err
}
return node + "." + language, nil
}
func (t Toolchain) check() error {
if err := checkToolchainLanguage(t.Language); err != nil {
return err
}
if t.Version == "" || t.Recipe == "" {
return fmt.Errorf("buildstep: a %s toolchain needs its version and its recipe", t.Language)
}
return nil
}
// EncodeToolchain is t as JSON; it refuses a language other than go or typescript and an empty version or recipe.
func EncodeToolchain(t Toolchain) ([]byte, error) {
if err := t.check(); err != nil {
return nil, err
}
t.V = ToolchainVersion
return json.Marshal(t)
}
// DecodeToolchain reads a toolchains value, refusing an unknown field, another layout version and what
// EncodeToolchain refuses.
func DecodeToolchain(data []byte) (Toolchain, error) {
var t Toolchain
dec := json.NewDecoder(bytes.NewReader(data))
dec.DisallowUnknownFields()
if err := dec.Decode(&t); err != nil {
return Toolchain{}, fmt.Errorf("buildstep: a toolchain does not read: %w", err)
}
if t.V != ToolchainVersion {
return Toolchain{}, fmt.Errorf("buildstep: a toolchain of version %d, this reads %d", t.V, ToolchainVersion)
}
if err := t.check(); err != nil {
return Toolchain{}, err
}
return t, nil
}