The mesh can compile Go, which is why nothing delivered the host
novox/hq 04-ISSUES/142, and ADR 0141's own progressive insight naming this as the first of two things missing: "nothing can compile it". The toolchain list was a closed set of typescript and python, whose warning — every language is another implementation of the contracts modules share — does not attach to Go. Go is how the host, the control plane and the builder are written, and none of them is a module in that sense: the host is what APPLIES modules. The toolchain names mesh-tools-go as its base rather than pinning an upstream release here (ADR 0142, 0044): named and not pinned means the mesh answers with the copy it holds, and moving compiler is a build instead of an edit to this file. Two things beyond the list also assumed one language, and both would have failed after the entry was added: sourcesFor turned every entrypoint into a `.ts` file. The extension is the toolchain's now — one language's file extension written into the code that serves every language is a wall the next one hits. The output directory was the compiler's to create. tsc --outDir makes one; go build -o writes into a directory and does not make it, failing with a message about a path rather than about a build. Made here for every toolchain, because which compilers are forgiving is not something a reader should have to know. And a toolchain now says what it is pointed at: a file list from the module's entrypoints, or the one package the artifact is built `from`. Pointing `go build` at a file list builds a program out of exactly those files and ignores the rest of the package — a missing symbol rather than a legible refusal. Static and -trimpath: what a machine holds is a file, not a container, so a binary needing a libc it did not bring is a delivery that works until a machine differs; and a version comes from where a component sits rather than from its linker, so two builds of one commit are the same bytes.
This commit is contained in:
@@ -861,6 +861,15 @@ func compile(ctx context.Context, run Runner, tree string, chain Toolchain,
|
||||
// each other and then be packed together, so each bundle compiles and packs alone.
|
||||
out := Out(a.Name)
|
||||
|
||||
// **The output directory exists before the compiler is told about it.** `tsc --outDir` makes
|
||||
// one; `go build -o` writes a file into a directory and does not create it, failing with a
|
||||
// message about a path rather than about a build. Made here for every toolchain, because which
|
||||
// compilers happen to be forgiving is not a thing a reader should have to know
|
||||
// (novox/hq 04-ISSUES/142).
|
||||
if err := os.MkdirAll(filepath.Join(tree, out), 0o755); err != nil {
|
||||
return "", fmt.Errorf("making the output directory for %s: %w", a.Name, err)
|
||||
}
|
||||
|
||||
invocation := []string{
|
||||
"run", "--rm",
|
||||
"--volume", tree + ":" + within,
|
||||
@@ -873,8 +882,14 @@ func compile(ctx context.Context, run Runner, tree string, chain Toolchain,
|
||||
}
|
||||
// What to compile. Named by the module rather than discovered, so adding a file does not
|
||||
// silently change what a build produces.
|
||||
if len(a.Entrypoints) > 0 {
|
||||
invocation = append(invocation, sourcesFor(a.Entrypoints, out)...)
|
||||
switch {
|
||||
case chain.Unit == UnitPackage:
|
||||
// One directory, compiled whole: the thing the artifact is built `from`. Relative, because
|
||||
// the compiler runs with the module's own root as its working directory and a package path
|
||||
// that looked absolute would name one inside the toolchain image.
|
||||
invocation = append(invocation, "./"+strings.Trim(a.From, "./"))
|
||||
case len(a.Entrypoints) > 0:
|
||||
invocation = append(invocation, sourcesFor(a.Entrypoints, out, chain.SourceExt)...)
|
||||
}
|
||||
if _, err := run(ctx, tree, "docker", invocation...); err != nil {
|
||||
return "", err
|
||||
@@ -887,14 +902,16 @@ func compile(ctx context.Context, run Runner, tree string, chain Toolchain,
|
||||
// A module names what a tool host should LOAD — compiled paths under the bundle's root — because
|
||||
// that is the thing anything else needs to know. What to compile is the same list with the
|
||||
// language's own extension, which is the toolchain's business rather than the module's.
|
||||
func sourcesFor(entrypoints []string, out string) []string {
|
||||
func sourcesFor(entrypoints []string, out, ext string) []string {
|
||||
sources := make([]string, 0, len(entrypoints))
|
||||
for _, e := range entrypoints {
|
||||
// An entrypoint is named as it will be FOUND — a path inside the unpacked bundle — so the
|
||||
// source is the same path with the output directory taken off the front and the language's
|
||||
// own extension on the end.
|
||||
// own extension on the end. **The extension is the toolchain's**, where it used to be the
|
||||
// literal `.ts`: one language's file extension written into the code that serves every
|
||||
// language is a wall the next one hits (novox/hq 04-ISSUES/142).
|
||||
at := strings.TrimPrefix(strings.TrimPrefix(e, out), "/")
|
||||
sources = append(sources, strings.TrimSuffix(at, filepath.Ext(at))+".ts")
|
||||
sources = append(sources, strings.TrimSuffix(at, filepath.Ext(at))+ext)
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user