Files
mesh-delivery/modules/mesh-delivery-indexer/internal/index/toolchains_values.go
T

82 lines
2.7 KiB
Go

package index
import (
"encoding/json"
"fmt"
"strings"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/nodebuildgo"
"git.novox.be/novox/mesh-sdk/go/keys"
)
// The toolchains the build modules keep in their state toolchains, one key per node and language, `<node>.<language>`
// (reads: mesh-build-go.toolchains, mesh-build-node.toolchains). Both build modules state it in the one form of a
// node-build seat; the indexer reads it as nodebuildgo.Toolchain and takes the agreed one with the delivery sdk's rule
// (buildstep.AgreedToolchain, novox/hq ADR 0584).
func checkToolchainLanguage(language string) error {
switch language {
case "go", "typescript":
return nil
}
return fmt.Errorf("index: the toolchain language %q is not go or typescript", language)
}
// ToolchainKey is the key of a node's toolchain of one language. It refuses a node that is not a name and a language
// other than go or typescript.
func ToolchainKey(node, language string) (string, error) {
if err := keys.CheckName("node", node); err != nil {
return "", err
}
if err := checkToolchainLanguage(language); err != nil {
return "", err
}
return nodebuildgo.ToolchainsByNodeLanguageKey(node, language), nil
}
// ParseToolchainKey is the inverse of ToolchainKey.
func ParseToolchainKey(key string) (node, language string, err error) {
node, language, ok := strings.Cut(key, ".")
if !ok {
return "", "", fmt.Errorf("index: %q is not a toolchain key, <node>.<language>", key)
}
if _, err := ToolchainKey(node, language); err != nil {
return "", "", fmt.Errorf("index: %q is not a toolchain key: %w", key, err)
}
return node, language, nil
}
func checkToolchain(t nodebuildgo.Toolchain) error {
if err := checkToolchainLanguage(t.Language); err != nil {
return err
}
if t.Version == "" || t.Recipe == "" {
return fmt.Errorf("index: a %s toolchain needs its version and its recipe", t.Language)
}
return nil
}
// EncodeToolchain is t as JSON at the kept values' version (the build modules write it; the indexer's tests do too).
func EncodeToolchain(t nodebuildgo.Toolchain) ([]byte, error) {
if err := checkToolchain(t); err != nil {
return nil, err
}
t.V = keys.Version
return json.Marshal(t)
}
// DecodeToolchain reads a toolchains value; it refuses an unknown version and what EncodeToolchain refuses.
func DecodeToolchain(data []byte) (nodebuildgo.Toolchain, error) {
if err := keys.CheckVersion(data); err != nil {
return nodebuildgo.Toolchain{}, err
}
t, err := nodebuildgo.DecodeToolchainsByNodeLanguageValue(data)
if err != nil {
return nodebuildgo.Toolchain{}, fmt.Errorf("index: a toolchain does not fit its shape: %w", err)
}
if err := checkToolchain(t); err != nil {
return nodebuildgo.Toolchain{}, err
}
return t, nil
}