Reference

torb vendor

torb vendor copies every registry package project.lock.trb pins into vendor/ after checking its tree hash, names each copy with a source path line and locks it as a path package, so a build needs neither the cache nor a network.

vendor puts the dependencies of a project into the project. It reads project.lock.trb, takes every package the lock pins from a registry, and writes it to vendor/<owner>/<name>/ exactly as the cache unpacks it. The root project.trb then names each copy with a source "<owner>/<name>", path: "vendor/<owner>/<name>" line, which is the mechanism a path: source always was rather than a new one, and the lock lists the package as path: from then on. A build of the project reads the copies and needs neither the cache nor a network.

Synopsis#

torb vendor                  Copy the registry packages of the lock into vendor/
  --offline                  No network: fail naming the first package that is not in the cache
  --project <directory>      The project whose workspace to vendor

What it does#

Every package of the lock's graph that comes from a registry is copied, the ones a dependency needs included. Packages that are already path: sources, archive: and git: packages - their source line already says where they come from, and a copy would replace it - and the members of a workspace are left alone.

Checked before anything is written#

Each package is checked against the tree hash the lock pins before the first file is written: the copy in the cache is read back and hashed, and a package that is not in the cache is fetched like torb install does it, from the mirrors of config.trb and the registry, and checked the same way. A package whose hash differs is refused, and nothing is changed. With --offline a package that is not unpacked in the cache is an error that names it, the first in the order of the lock.

Resolution runs once more with the copies in place. If it has no solution, the copies are taken out again and the command fails, with project.trb and the lock as they were.

What is written#

  • vendor/<owner>/<name>/ for every package, the same files the archive holds (project.trb, src/, and the lock the package was published with).
  • One source line per package in the project.trb of the workspace root, after the last source line or the dependencies block. Comments and line endings of the file are kept.
  • project.lock.trb, with the packages listed as path: "vendor/<owner>/<name>". The settings blocks are kept.
$ torb vendor --project app
vendored 2 packages into app/vendor
  ~ acme/json 1.1.0 -> path vendor/acme/json
  ~ acme/text 1.0.0 -> path vendor/acme/text

Running it again#

A second run changes no file and says so:

$ torb vendor --project app
up to date: 2 packages vendored in app/vendor

A package that left the graph - after torb remove, say - is taken out of vendor/ by the next run, together with its source line, and so are the directories above it that are empty now. Only a directory below vendor/<owner>/ that holds a project.trb is a copy; anything else in vendor/ stays.

Errors#

  • There is no project.lock.trb: torb update writes one first.
  • A lock that does not match project.trb is refused with the command that fixes it, as install does.
  • A project whose lock has no registry package says nothing to vendor and changes nothing.

Pitfalls#

A vendored package is not verified later. A path: source is not hashed: after torb vendor the files in vendor/ are the project's own, and what the lock records for them is a directory. That is the price of building without a registry, and a review of vendor/ in the version control history is how a change shows. The hash was checked once, when the copy was made.

A project with vendored dependencies cannot be published. torb publish refuses a runtime dependency that comes from a path: source, because nobody who installs the package has the directory. The way back is by hand: delete the source lines and the vendor/ directory, then run torb update, which resolves from the registry again and pins hashes.

vendor does not follow updates. A new version of a vendored package needs the way back as well: remove its source line and its directory, run torb update, and vendor again.

Examples#

A project that builds with an empty cache and no network:

$ torb vendor --project app
vendored 2 packages into app/vendor
$ TORB_CACHE=/tmp/empty torb run ./app
acme/json 1.1.0: "say "hello""
  • torb install - the packages of a lock into the cache, which vendor reads from.
  • project.trb - the source "...", path: "..." line vendor writes.
  • project.lock.trb - where a vendored package is listed as path:.
  • torb publish - refuses a project with vendored dependencies.
Esc