candela.toml¶
The project manifest. Its presence makes a directory a project: candela run,
candela check and candela build take their entry point from it, and
candela add, candela remove, candela fetch, candela update and
candela publish work on the package it describes.
[package]
name = "geom"
version = "0.3.1"
description = "2D geometry"
entry = "src/main.cdl"
candela = ">=0.0.7"
[dependencies]
shapes = "1.2"
Where it is found¶
A command looks for candela.toml in the working directory and then in each
directory above it, stopping at the first one it finds. That directory is the
project root, and every relative path in the manifest is relative to it.
candela.lock sits beside it. It is written by the registry client, records
the exact version of every package resolved, and is meant to be committed.
Unknown keys¶
A table or a key candela does not know is an error naming it, rather than something quietly ignored. A manifest either says what candela reads or says what is wrong with it.
[package]¶
| Key | Type | Required | Meaning |
|---|---|---|---|
name |
string | yes | The package name. This is what another project writes in its [dependencies], and what its imports resolve under. |
version |
string | yes | The package version. candela publish releases this version, and a workflow release checks it against the tag. |
description |
string | no | One line about the package, sent to the registry when it is published. |
entry |
string | no | The file run, check and build compile when no file is named, and the file another project reads when it imports this package by name. Defaults to src/main.cdl. |
candela |
string | no | The oldest candela the package compiles on, as a version requirement. A release records it. With no key here, a release records the version of the candela that checked the package. |
The entry is the package's front door twice over: the verbs start there, and
import "name" in a project that depends on the package reads it. A library
entry needs no main: check compiles a file without one, and a main in an
imported module is ignored either way. It is a path inside the package, so a
.. component in it is an error: a release archive holds the package root and
nothing above it.
candela names a floor, so it takes a version with an optional comparator in
front: ">=0.0.7", "^0.0.7", "~0.0.7", ">0.0.7", "=0.0.7",
"<=0.1.0", a comma-separated pair such as ">=0.0.7, <0.1.0", or a bare
"0.0.7". A version is one to three dot-separated numbers, with an optional
-prerelease after them. Anything else is an error naming it: nightly and
latest name whatever is newest today rather than a version, and * names no
floor at all. A [dependencies] requirement is not held to this; candela
passes those to the registry client as written.
The key is what candela publish and the release workflow record as the
toolchain a user needs, which is what keeps a package checked on the nightly
channel from demanding the in-development version no release carries yet.
Nothing compares the running compiler against the requirement; it travels to
the registry with the release. 0.0.7 is the oldest candela that reads the key
at all, so a floor below it says nothing any toolchain acts on.
[dependencies]¶
One entry per package, keyed by name. The value is a version requirement, in either of two spellings:
The requirement is passed to the registry client as written; candela does not
interpret it. candela add writes the first spelling and edits the version
key of the second, leaving whatever else the table carries alone.
An empty table, or no table at all, means no dependencies, and no command reaches for the registry client.
A dependency on a package published for the lumen platform is refused by
name. The two platforms ship different things, and a Lumen package holds
nothing a candela import can reach.
Editing¶
candela add and candela remove rewrite the file in place and keep
everything that is not data: comments, key order, blank lines, and the table
form a dependency was written in.
Package layout¶
Nothing is enforced beyond the manifest, but candela new writes, and the
reusable release workflow packs, this shape:
package/
candela.toml
candela.lock
src/
main.cdl
dist/ # native libraries, when the package ships any
A release archive carries the manifest and the directory the entry sits in,
with the package root at the root of the archive, so the default entry makes it
candela.toml and src/. An entry at the package root instead ships
everything beside the manifest, apart from dist/, target/, any .tar.gz,
.tgz or .zip lying there, and every name that starts with a dot, so .git,
.github and .gitignore stay out. A package that ships native libraries
carries dist/ too, built per target.
Imports into a package¶
A library import whose first segment is the package name resolves against the package's entry: the name alone reads the entry file, and a path reads from the entry's directory. With the default entry:
| Import | Reads |
|---|---|
import "shapes"; |
<package root>/src/main.cdl |
import "shapes/circle"; |
<package root>/src/circle.cdl |
import "shapes/geo/arc"; |
<package root>/src/geo/arc.cdl |
A manifest that sets entry = "lib/shapes.cdl" moves both: the name reads
lib/shapes.cdl and shapes/circle reads lib/circle.cdl.
The package root is also searched for native libraries, so a dylib import
with a plain name finds a library shipped at the root of the package. A library
under dist/ is reached from src/ with a path: dylib "../dist/mylib". See
C libraries.