torb add
torb add writes a dependency into project.trb, resolves the workspace with it, writes project.lock.trb and installs what is new - or changes nothing and explains why there is no solution.
Diese Seite gibt es noch nicht auf Deutsch, deshalb steht sie hier auf Englisch. Zur englischen Seite
add is how a dependency gets into a project: one line in the dependencies { } block of
project.trb, a resolution of the whole workspace with it, the new
project.lock.trb, and every new package fetched and verified into the cache. If the
requirements have no solution, nothing is written and the reason is printed.
Synopsis#
torb add <package>[@<requirement>]... Add runtime dependencies to the project around the working directory
--development A development dependency: tests and tools, never part of what dependents get
--offline No network: indexes from the cache's copies, archives only if unpacked
--project <directory> The project to add to, instead of the one around the working directoryWhat it does#
The line it writes#
torb add acme/json asks the registry for the newest release of acme/json that may be chosen - no pre-release, no
yanked release, none that needs a newer language than this toolchain - and writes runtime "acme/json:^1.2.0". With a
requirement, torb add acme/json@~1.2.0 writes that one instead. A workspace member is added without a version.
The edit is made over the syntax tree and touches one line: a requirement of the same package is replaced in place, a
new one goes at the end of the block, indented like the lines above it, and a file without a block gets one at its end.
Comments, blank lines and the file's line endings stay. A block that computes anything is refused rather than
rewritten, because only plain runtime "..." and development "..." lines can be edited without changing what the
file means.
The resolution#
Every member of the workspace, every source ... path: package and every registry package any of them reaches is
resolved at once by PubGrub, which answers the highest version every requirement allows and keeps the version the lock
already has for every other package where it still fits. The result is written to project.lock.trb and printed, one
line a package, with what each new one touches:
$ torb add acme/json --project app
added acme/json to acme/app
+ acme/json 1.0.0
installed acme/json 1.0.0
1 package installed, 0 of them already in the cacheA graph may hold two majors of one package (acme/json 1.x for one dependent, 2.x for another): the lock keeps a
line for each, and torb build, torb run and torb doc keep their modules and types apart under the names
acme/json@1 and acme/json@2.
The signatures of the index#
A registry that signs its index lists its keys in index/config.trb, and every record of every index file add
reads is checked against them before resolution sees it: a record that is unsigned, changed, or moved to another place
of its file is refused, named by what it is, and nothing is written. The keys are trusted the way SSH trusts a host -
at the first contact with a registry torb prints them and pins them in <cache>/keys/, and afterwards a key the
registry adds is trusted only where a key already trusted endorsed it. A registry without keys, such as a file:
registry of a test, is read as it is. RELEASE.md section 7.14
has the rules.
An index file can come from a mirror of the machine's config.trb, which is asked before the registry. It is checked against the same keys, and a record the mirror changed is refused with the mirror named. The keys themselves are trusted at the first contact with the registry itself, never through a mirror.
$ torb add acme/json
torb: trusting the signing keys of https://packages.acme.test from now on: ed25519:3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c (pinned in /home/ada/.torb/cache/keys/packages.acme.test.trb)
added acme/json to acme/app
+ acme/json 1.0.0The owner of a new package#
A registry that signs its index keeps one more file per owner, index/<owner>/owner.trb: its kind, when the registry
made it, the domain it proved, and the registry it publishes at instead, where it does. When a package named on the
command line was not in the lock before, add reads that file, checks its signature like every record, and prints one
line about the owner - its kind, its age in whole years from a year on (else in days), and the domain it proved - so a
name that only looks like a familiar one shows its newness:
$ torb add acme/json
added acme/json to acme/app
+ acme/json 1.0.0
owner acme (organisation, 3 years old, verified domain acme.com)
installed acme/json 1.0.0An organisation that proved several domains (up to five) has them all in the line, verified domains acme.com, acme.org beside verified domain acme.com for one.
A package the lock already has prints no such line, nor does an owner without a file or a registry that signs nothing.
--offline reads the copy the cache keeps beside the index files. An owner file that does not verify is refused and
nothing is written; so is one older than the copy in the cache, which only a source that hands back an old file
produces.
An owner that publishes elsewhere#
An owner can publish at a registry of its own instead (RELEASE.md section 7.1). The public registry then has none of
its packages, and where it has no file for the package, add - and every resolution - reads the owner's file and
names that registry and the line that binds the owner to it, instead of saying only that the package is not there:
$ torb add acme/json
error: the registry https://packages.torb.dev/ has no package `acme/json`: `acme` publishes at https://packages.acme.com (verified domain acme.com); bind it in project.trb with `registry "acme", url: "https://packages.acme.com"`The URL is only printed: torb never binds it or fetches from it on its own. "(verified domain ...)" appears only where
its host is one of the domains the owner proved or under one of them; otherwise nothing about it is claimed.
A deprecated package#
When a package named on the command line is flagged by torb deprecate, add still adds it and
then says so once, on standard error, with the package to use instead where its maintainers named one. The packages those
need are not announced, and update and install print nothing:
$ torb add acme/http
added acme/http to acme/app
+ acme/http 1.4.0
warning: acme/http is deprecated: http2 speaks HTTP/2 and keeps the API
use acme/http2 instead
installed acme/http 1.4.0When there is no solution#
Resolution fails before anything is written, and the explanation is the derivation of the failure, one reason a line:
$ torb add acme/json@^9.0.0
Because no version of acme/json matches ^9.0.0 and acme/app depends on acme/json ^9.0.0, version solving failed.
error: nothing was changed: the dependencies of project.trb have no solutionPitfalls#
The toolchain's packages are never dependencies. torb add std/fs is refused: every std/* package comes with
torb and needs no line.
A requirement is ^ by default. @1.2.3 means ^1.2.3, as in Cargo; @=1.2.3 is the one version.
A registry whose keys changed is refused until you decide. A registry that replaced its key without announcing
the new one - endorsed by the old - looks exactly like somebody else's index, so torb refuses it and names the file of
pinned keys. Removing that file after checking with the registry's operator trusts the new keys on the next contact.
Examples#
A requirement that a dependency of a dependency rules out is explained through it:
$ torb add acme/json@=1.0.0 --project app
Because every version of acme/text depends on acme/json ^1.1.0 and acme/app depends on acme/json 1.0.0, every version of acme/text is forbidden.
So, because acme/app depends on acme/text ^1.0.0, version solving failed.
error: nothing was changed: the dependencies of project.trb have no solutionRelated#
- torb remove, torb update, torb install - the other package commands.
- project.lock.trb - the file
addwrites. - config.trb - the mirrors an index file is fetched through.
- torb deprecate - flags a package, which
addannounces. - Add a dependency - the steps, with the requirement grammar.