Embedding Files
_embed_ bakes a file's contents into the compiled binary at compile time, so
the program doesn't need the file on disk when it runs:
func main()
logo := _embed_ ./logo.png
>> logo : [Byte]
The path is relative to the source file doing the embedding. An embed is a
[Byte] by default, but can be embedded as a Text (checked for valid UTF8 at
compile time) or a CString (checked for no NUL bytes at compile time) by
giving it that type:
motd : Text = _embed_ ./motd.txt
Embedding Directories
Embedding a directory embeds every file in it, recursively, as a table mapping each file's relative path to its contents:
func main()
assets := _embed_ ./assets
>> assets : {Path:[Byte]}
say(assets[(./style.css)]!.length)
pages : {Path:Text} = _embed_ ./pages
for path, contents in pages.entries()
say("$path: $(contents.length) graphemes")
Keys are the files' paths relative to the embedded directory, in the same
normalized form path literals compile to, so a literal like
(./inner/file.txt) looks its entry up directly. Entries iterate in sorted
path order, and the table compiles deterministically.
As with single files, a directory embeds as {Path:[Byte]} by default and can
be embedded as {Path:Text} instead, in which case every file in it must be
valid UTF8, or as {Path:CString}, in which case no file in it may contain a
NUL byte. Both are checked at compile time, and the error names the file
that failed.
A few rules about which files a directory embed includes:
- Dotfiles (and dot-directories) are not included. To embed one, name it
explicitly:
_embed_ ./config/.env. - Symbolic links are silently skipped, since they could point outside the directory or form a cycle.
- A directory with no embeddable files is a compile-time error, as is a missing file or directory.
Embedded paths must be relative (starting with ./ or ../) — an absolute or
home-based path is machine-specific and could never travel with the program's
sources, so it's a compile-time error. Relative paths may reach anywhere,
including above the source file: no directory is privileged.
Embedded files are tracked as build dependencies: editing, adding, removing,
or renaming a file under an embedded directory causes the module embedding it
to recompile. They are also included in the compiled binary's embedded source
archive (see Compilation), whose src/ tree is rooted at
the deepest directory containing every source and embedded file — so a module
embedding ../file.txt simply roots the extracted tree one level higher, and
tomo source <program> -o <dir> always extracts a project that rebuilds into
the same program.