package builder import ( "strings" "testing" ) // Nothing could compile the mesh's own components, which is why nothing delivers the host // (novox/hq 04-ISSUES/142, and ADR 0141's own insight naming it). The toolchain list was a closed // set of typescript and python, and two things in the path beyond it assumed TypeScript. func TestTheMeshCanCompileGo(t *testing.T) { chain, err := ToolchainFor("go") if err != nil { t.Fatal(err) } // Named, not pinned: the mesh answers with the copy it holds, so moving compiler is a build // rather than an edit to this source (ADR 0044, 0142). if chain.Base != "mesh-tools-go" || chain.Artifact != "build" { t.Fatalf("the go toolchain is based on %s/%s", chain.Base, chain.Artifact) } joined := strings.Join(chain.Compile, " ") // Static, because what a machine holds is a file and not a container: a binary needing a libc // it did not bring is a delivery that works until a machine differs. if !strings.Contains(joined, "CGO_ENABLED=0") { t.Fatalf("the go toolchain does not build statically: %q", joined) } // Reproducible: a version comes from where a component sits, not from its linker (ADR 0142), // so two builds of one commit should produce the same bytes. if !strings.Contains(joined, "-trimpath") { t.Fatalf("the go toolchain leaves build paths in the binary: %q", joined) } if chain.Unit != UnitPackage { t.Fatalf("the go toolchain compiles %q, wanted a package", chain.Unit) } } func TestEveryToolchainSaysWhatItIsPointedAt(t *testing.T) { // The field exists because the compile path used to assume one language. A toolchain that says // nothing would fall through to the entrypoint branch and compile a file list, which for a // compiled language builds a program out of exactly those files and ignores the rest of the // package — a missing symbol rather than a legible refusal. for _, chain := range toolchains { switch chain.Unit { case UnitPackage: case UnitSources: if chain.SourceExt == "" { t.Fatalf("%s compiles a file list and names no source extension", chain.Language) } if !strings.HasPrefix(chain.SourceExt, ".") { t.Fatalf("%s's source extension %q is not an extension", chain.Language, chain.SourceExt) } default: t.Fatalf("%s says it is pointed at %q, which is neither sources nor a package", chain.Language, chain.Unit) } } } func TestAnEntrypointBecomesASourceInItsOwnLanguage(t *testing.T) { // It used to become a `.ts` whatever the language was. out := Out("build") got := sourcesFor([]string{out + "/tools/index.js"}, out, ".ts") if len(got) != 1 || got[0] != "tools/index.ts" { t.Fatalf("a typescript entrypoint became %v", got) } got = sourcesFor([]string{out + "/tools/index.js"}, out, ".py") if len(got) != 1 || got[0] != "tools/index.py" { t.Fatalf("a python entrypoint became %v", got) } }