The package manager

Install, lock, verify and publish packages with Venutian's own package manager, content hashed and cycle checked, written in Venutian.

The seven commands

venutian install, uninstall, list, lock and verify all run as plain Venutian, the same way venutian run runs any other .ven file. Nothing about how a package gets installed lives in the native binary.

Command Does
venutian install [path-or-archive] With no argument, reinstalls everything already in this project's venutian.json. With one, adds and installs that local directory or .zip, .tar, .tar.gz or .tgz archive (--name NAME to set the entry's name).
venutian uninstall <name> Removes an installed package's whole destination directory.
venutian list Lists the packages installed in this project's venutian_packages/.
venutian lock Writes venutian.lock.json from what is installed right now.
venutian verify Checks every installed package's content hash against venutian.lock.json.
venutian publish <source-dir> <name> <version> Copies a source directory into a registry directory under a name and version, ready for another project to fetch (--sign <key> to sign it).
venutian fetch <name> [<version>] [--registry <dir>] Installs a published package straight from a registry directory into this project's venutian_packages/ (--verify-key <key> refuses an unsigned or wrongly signed package).

The manifest and the lockfile

venutian.json is the manifest you write: a name, a version and a dependencies map, one entry per package, each naming its kind and where to find it.

JSON
{
  "name": "utils_lib",
  "version": "1.0.0",
  "dependencies": {
    "core_lib": {
      "kind": "path",
      "location": "../core_lib"
    }
  }
}

venutian.lock.json is the file venutian lock writes, one entry per installed package, each carrying the content hash of the directory venutian install actually put on disk.

JSON
{
  "core_lib": {
    "content_hash": "5f2b1c9a0e7d4f6b8a3c1d9e0f2b7a4c6d8e1f3a5b7c9d0e2f4a6b8c0d2e4f6a"
  }
}

The manifest says what you asked for. The lockfile says what you actually got, byte for byte.

Installing from a path or archive

venutian install ../my-lib or venutian install my-lib.tar.gz copies that directory or unpacks that archive into venutian_packages/<name>/, a conventional local directory your own code reaches through Venutian's existing relative path use:

Venutian
use "venutian_packages/my-lib/whatever.ven"

There is no package name resolution at the language level. use stays whole file and relative path, so the package manager's job is exactly this: take a package from a local directory or a local archive and put it where a plain relative use already knows how to find it.

Transitive resolution and cycle detection

Installing one package installs its dependencies too. The resolver walks a package's own venutian.json, installs each dependency, then recurses into that dependency's own manifest, resolving relative paths against the dependency's original source location so a nested ../sibling-lib still finds the right directory once everything is copied into venutian_packages/. A package already resolved is skipped; a package still being resolved when its own name comes up again is a real cycle, and the resolver raises rather than looping forever:

Error
circular dependency detected at 'name'

Content hash verification

Every installed package's whole directory is hashed once: every file found under it, each combined as its path and its own SHA-256, concatenated together and hashed again as a whole. Two installs of a byte for byte identical package always produce the same hash; any changed, added, removed or renamed file changes it. venutian lock records that hash for what is installed right now; venutian verify recomputes it and compares, catching a missing package directory or a mismatched hash before it becomes a build that only works on one machine.

Publishing

Publishing copies a source directory into a registry directory under a name and version, so another project can fetch it back out, content hash and all.

Terminal
venutian publish <source-dir> <name> <version> [--sign <key>]
venutian fetch <name>

Marketplace publishing sends the same package to the network registry that also powers the packages page and the release notifier below.

Library updates reach you

Once a day, the notifier installed alongside venutian compares the libraries your project actually has, recorded when they were installed, against the registry's current manifest, and names every new library and every updated one in your terminal, no extra command required. What you see once a day:

What you see once a day
Venutian 1.1.0 is out (you have 1.0.1).
New libraries: vgeo 0.1.0, vstats 0.1.0. Updated: vassert 0.2.0, vjson 0.3.1.
This project: vjson 0.3.0 can go to 0.3.1.
Upgrade:    curl -fsSL https://venutian.org/install.sh | sh
Libraries:  venutian-notifier libraries
Notes:      https://venutian.org/releases/1.1.0/
Quiet:      venutian-notifier off

When your project has a venutian.lock.json, the notifier also checks that lockfile's own versions against the registry and adds the line "This project: vjson 0.3.0 can go to 0.3.1." The lockfile is read, never written, by the notifier. Run venutian-notifier libraries any time to list every new and updated library with its page link, or venutian-notifier libraries --fetch <name> to download one, verify its hash and print the venutian install line that adds it to your project. Nothing installs into a project on its own; the notifier only ever tells you the command to run.

Next chapter Packages