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, `.` // (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, .", 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 }