82 lines
2.7 KiB
Go
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
|
|
}
|