Packages
A package is a directory with a project.trb, named owner/name, whose file names say what it produces - src/lib.trb, src/main.trb, *.test.trb - and it can only be reached by a project that lists it as a dependency.
Every "owner/name" after from names a package: a directory with a project.trb,
whose library is its src/lib.trb. What it may be imported by is never a guess, because a project has to say so
first, and what it produces is never a setting, because the names of its files say it.
Example#
name = "acme/greeter"
version = "0.1.0"
dependencies {
runtime "acme/greeting-words:^1.0.0"
development "acme/mock-clock:^2.0.0"
}Syntax#
my-project/
├ src/
├─ main.trb // The program: what torb run executes; may contain top-level code, never imported
├─ lib.trb // The library: what other packages import, declarations only
├─ <path>.trb // A module: "owner/name/<path>"
├ tools/
├─ migrate.trb // A second program, where project.trb says program "migrate", entry: "tools/migrate.trb"
├ tests/
├─ *.test.trb // A test, wherever it lies in the package
├ project.trb
└ project.lock.trbRules#
A name is
owner/name, and the owner is a verified namespace of a registry. A project binds an owner to a registry once (registry "acme", url: "https://packages.acme.test"), so a public package can never take the place of a private one under the same bare name.The names of the files decide what a package produces.
src/lib.trbis its library, what"owner/name"imports, and it holds declarations only;src/main.trbis its program, named after the package; a file called*.test.trbis a test wherever it lies. Nothing inproject.trbmakes a file any of these. A second program is aprogramline of project.trb, and a program's entry is never importable:"owner/name/main"and a relative path to an entry are errors at theuse.A package's files are every
.trbfile below its directory, except the ones inside a nested package - a directory below it with aproject.trbof its own - and inside a hidden directory,build,targetornode_modules.tools/migrate.trbis a file of the package, and it may import the package's modules with a relative path. A relative path never leaves the package: another package is imported by its name.A package can only be imported by a project whose
project.trblists it as a dependency,std/*excepted - the standard library comes with the toolchain and needs no entry.use Int from "std/prelude" print Int.tryFrom("42")project.lock.trbpins the whole graph: the exact version, content hash and registry of every dependency, direct or transitive.torb run,buildandtestfail if it does not matchproject.trb; onlytorb add,torb removeandtorb updatewrite the graph, andtorb lockandtorb publishthe evaluated settings beside it.Published versions are immutable. A version can be withdrawn from new resolutions, never replaced or deleted, so a lock file always resolves to the same bytes it pinned.
Resolution picks the highest version compatible with every requirement, and one version of a package per major version in a graph. A requirement is written as published,
^1.2.3by default, so patch and minor upgrades happen without editingproject.trb.project.trbruns in a sandbox without IO, so installing a package never runs code. There are no install scripts and no build scripts; reading a package's metadata is as safe as reading its source.Capabilities are visible from the imports alone. There is no reflection, no
evaland no dynamic import, so what a package can touch - the file system, the network, processes, the environment, foreign functions - is exactly what itsuselines and those of everything it depends on say.torb addshows it, and gaining one on an update needs confirmation.
What this is not#
A package is not a folder you can reach because it happens to be on disk. Only a name project.trb lists as a
dependency resolves; std/* is the one family that needs no entry.
use File from "std/fs"
print File.exists("project.trb")use Router from "acme/http/routing"A relative path does not reach it either, even where the other package's files lie right beside this one's: a relative path names a file of the same package.
use Vector2 from "../../linear/src/vector2"A project.trb is not a list of what the package produces. There is no setting that makes a file the program,
the library or a test; the names of the files say it, and the manifest adds only a second program.
Related#
- use - every form of importing a name out of a package.
- Workspaces - several packages sharing one root and one lock file.
- The prelude - the one package whose names need no
useat all. - project.trb - the manifest, its
programlines and its profiles.