Module Files
Want operates on units called Modules. A Module is a filesystem tree with a file named WANT at its root.
The WANT file provides module-level configuration and doubles as a sanity
check that a directory is supposed to be built by Want. It is a Spore body that evaluates to a module config:
.deps = [
{"want", \(_: Ctx) FS LATEST},
]
.deps
.deps lists the module's dependencies. Each dep is a tuple of a name and a
proc that produces the dependency's filesystem from a build context
((#Product String (#Proc build.Ctx build.FS))). At plan time every dep's
proc runs and its returned filesystem is registered as a Spore source under
<name>:; planning files import its packages as <name>:pkg.
The WANT file is compiled with a preamble binding Ctx (build.Ctx), FS
(build.FS, a wantfs.Segment) and LATEST (the compiled-in want standard
library as an FS), so the default dep above gives the module the standard
library under want: without any imports. The spore standard library
(core:) is always implicit; a module that does not declare a want dep has
no want stdlib. want init writes the default config above.
.secrets
.secrets grants named secrets to the module's planning files. It is a list
of {paths, names} tuples, where paths is a paths.Set matched against a
planning file's module-root-relative path, and names is the list of secret
names that file may access:
paths = (#import "want:build/paths")
.secrets = [
{{.all = {}}, ["cloudflare"]}, // the whole module
{(paths.prefix "site/"), ["S3_KEY"]}, // files under site/
{(paths.unit "build/doc.want"), ["DOCS_TOKEN"]}, // one file
]
Only want build --publish uses secrets. Each matching target's build and
sink contexts receive the granted names as a (#List (#Port Unit Unit)) in
grant order (first occurrence wins), so a sink reads the first granted secret
with (#listslot ctx.secrets 0). The names must be supplied on the command
line:
-
--secret NAME:PATH— a single secret: the file's bytes. -
--secrets NAME:PATH— a spore module whose exports are the map entries:.CLOUDFLARE_API_TOKEN = "..." .CLOUDFLARE_ACCOUNT_ID = "..."
--secrets cloudflare:~/.config/want/cloudflare.sp supplies the map under the
name cloudflare, matching the grant above. A GitHub release upload takes a
file exporting .GITHUB_TOKEN in the same way:
--secrets github:~/.config/want/github.sp. A name supplied twice is an
error; names supplied but unused are ignored. A publish build fails before
running any target if a file it will publish is granted a name that was not
supplied. Secret values are loaded into memory (never the content store), and
only port tokens travel through tasks. Keep secret files outside the module
tree (or dot-ignored, as .* in the default .wantignore) so the workspace
import does not capture them as ordinary sources.
.wantignore
Which paths are imported into the module is configured separately, by a root
.wantignore file. It uses gitignore-style patterns, one per line: any path
matching a pattern is left out of the imported module tree.
By default a project that uses Git should ignore its VCS metadata and build outputs. For example:
.*
zig-out/
zig-cache/
.* ignores every dotfile (including .git), which keeps the import fast; the
other entries ignore build output directories.
.want is always ignored, and files starting with .want cannot be imported.