Using Want
This section will get you up and running with Want.
Most of the time you should run
want build. This command is suitable to use as a pre-merge check. It will build all the targets in the current module. It does not and cannot perform publishing or other side effects.
Creating a Want Module
Want operates on Modules. A Module is just a filesystem tree with a file named
WANT at its root. The WANT file holds module level configuration, and its
presence is what tells Want that a directory is meant to be built.
To start a new module, run want init in your project's root. It writes a
WANT file with the default module config — the want standard library as a
dependency — and a default .wantignore:
.deps = [
{"want", \(_: Ctx) FS LATEST},
]
See Module Files for what the WANT file can contain,
and how the sibling .wantignore file controls which paths are imported.
Creating a Build Target
Want calls the things that you, the user, want, but don't yet have, and need to build, Targets.
A target is declared by a file ending in .want. Create a file named
hello.txt.want at the root of your module, and fill it with the following:
build = (#import "want:build")
paths = (#import "want:build/paths")
.input = [
(paths.unit "./input.txt")
]
.do = \(ctx: build.Ctx) build.FS {
(build.pick ctx.jobs ctx.input "input.txt")
}
The file declares two things: the module paths the build reads (.input), and
the computation that produces the output (.do). Here do simply picks the
input file input.txt out of the target's input tree and returns it.
Create input.txt next to it containing Hello World!, then run
$ want cat hello.txt
Hello World!
The unit file hello.txt.want produces the output path hello.txt (its file
name minus the .want extension), and want cat reads that file out of the
build output.
Inspecting the Build Output
Normally cat hello.txt would print the source file, but want cat reads from
the build output, while the regular cat reads from the regular filesystem,
which is the build input.
Want organizes build targets into an output filesystem.
This filesystem only exists virtually, within Want, but it can be inspected using UNIX-like tools (ls and cat).
want ls <path> will list the contents of a tree in the build output. Compare this to the output of regular ls.
want serve-http <addr> builds the output and serves it as a read-only HTTP
file tree (for example want serve-http 127.0.0.1:8080): directories render
as an index of links, and files are written with a content type guessed from
their extension. Stop it with Ctrl-C.
This simple translation of inputs to outputs is what makes Want so easy to use and reason about. You will never find yourself in a situation where you don't know when/how/where a Target is being computed.
Armed with just want ls, want cat, and want build, you can get pretty far. To learn more about what you can build with Want, read the Build Configuration section.
Publishing and Secrets
A unit file may export an optional .sink proc: the side effect to run after
the build is green. Sinks do not run in a normal build; want build --publish runs them. A sink belongs to its target, consumes the target's
output as ctx.input, and reaches the outside world through the job port and
the capabilities in build.SinkCtx.
Secrets reach a sink through ctx.secrets, a list of ports in the order the
WANT's .secrets grants name them. Supply them on the command line:
# one raw secret
want build --publish --secret mySecret:/path/to/my_secret.txt
# or one spore map carrying several named values
want build --publish --secrets cloudflare:~/.config/want/cloudflare.sp
want build --publish --secrets github:~/.config/want/github.sp
Only the targets the build query names directly are published; a target pulled
in to satisfy a dependency is built but its sink does not run. A publish build
fails if a directly queried target (or the sink that will run for it) is
granted a secret that was not supplied. See
Module Files for the .secrets grant syntax.