A module says what it is written in, and needs no Dockerfile
The bundle recipe: the one that both builds and packs. An archive packs a directory as it stands, so shipping compiled output meant compiling somewhere first — which meant a Dockerfile repeating the same incantation in every module. Two base arguments with no defaults, a working directory chosen so the SDK resolves upward, the compiler invoked by absolute path because the usual symlink is resolved away when the base image is assembled, a second stage, an environment variable naming the entrypoints. Most of the catalogue is unconverted and that is why; two conversions done in one session were each wrong twice with a working example open in the next window. A bundle says a language and a list of entrypoints. The mesh knows what the language implies. Anything a module could override there it would be writing a Dockerfile to override, so a toolchain is deliberately not configurable. Declared rather than inferred, both of them: guessing the language from which files are present makes a build depend on a directory listing, and guessing the entrypoints makes it change meaning when somebody adds a helper. A toolchain the mesh does not hold is refused before anything is compiled, naming what to build first — the same treatment a missing base already gets, because it is the same question and somebody can answer it. A language the mesh does not build is refused saying what would have worked, since the author is usually one word away. The list of languages is closed and adding to it is a decision. Every language is another implementation of the contracts every module shares, and those change rarely and cascade when they do (ADR 0039) — a mesh whose SDKs disagree about the envelope fails by ignoring messages rather than by failing to compile. Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
@@ -389,6 +389,26 @@ type Artifact struct {
|
||||
// version and an operating system — while letting each be built and published separately.
|
||||
// Empty means the whole recipe, which is what a module with one image says by saying nothing.
|
||||
Target string `json:"target,omitempty"`
|
||||
|
||||
// Language is what this module's code is written in, for a bundle.
|
||||
//
|
||||
// **Declared, never guessed.** Inferring it from what files happen to be present makes a
|
||||
// module's build depend on a directory listing, and a module that adds a stray file builds
|
||||
// differently for a reason nobody can see. It is also the only thing a bundle needs to say:
|
||||
// everything else about the toolchain — which compiler, which flags, which base — is the
|
||||
// mesh's, and a module that could override it would be writing a Dockerfile again.
|
||||
//
|
||||
// Empty for every other kind, which do not compile.
|
||||
Language string `json:"language,omitempty"`
|
||||
|
||||
// Entrypoints are the compiled files a tool host should load from this module, relative to the
|
||||
// bundle's root.
|
||||
//
|
||||
// **Named rather than derived from which files exist**, for the same reason as the language:
|
||||
// the module knows what it serves, and a build that guesses would change meaning when
|
||||
// somebody adds a helper. An empty list is a bundle that is run rather than loaded — a
|
||||
// provisioner or a step, named by whatever runs it.
|
||||
Entrypoints []string `json:"entrypoints,omitempty"`
|
||||
}
|
||||
|
||||
// Kinds an artifact may be.
|
||||
@@ -397,6 +417,21 @@ const (
|
||||
ArtifactImage = "image"
|
||||
// ArtifactArchive is a directory in this repository, packed.
|
||||
ArtifactArchive = "archive"
|
||||
// ArtifactBundle is this module's own code, COMPILED by a toolchain and then packed.
|
||||
//
|
||||
// **The one recipe that both builds and packs**, and the reason it exists is the authoring
|
||||
// burden. An `archive` packs a directory as it stands, so shipping compiled output means
|
||||
// compiling somewhere first — which means a Dockerfile, repeating the same incantation in
|
||||
// every module: two base arguments, a working directory chosen so the SDK resolves upward, the
|
||||
// compiler invoked by absolute path because the usual symlink is resolved away when the base is
|
||||
// assembled, a second stage, an environment variable naming the entrypoints. Most of the
|
||||
// catalogue is unconverted and that is why.
|
||||
//
|
||||
// A bundle says what the module is written in and nothing about how. The mesh knows what a
|
||||
// language implies, which is the whole of the difference: a Dockerfile is right for software
|
||||
// that needs a particular base, and wrong for "compile my module's code", which is the same
|
||||
// operation every time.
|
||||
ArtifactBundle = "bundle"
|
||||
// ArtifactUpstream is an image somebody else built, mirrored into the mesh's own registry and
|
||||
// pinned by the digest it lands with.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user