First Steps
A tour from a fresh clone to running project tools, and then the three commands worth knowing.
Examples throughout this manual call tools by bare name, envy sync and
cmake --version, which assumes the shell hook is
installed. The hook puts the project's bin directory on PATH while you are
inside the project.
Without the hook, every one of those commands still works with the bin directory
in front: ./bin/envy sync and ./bin/cmake --version on macOS and Linux,
bin\envy.bat sync and bin\cmake.bat --version on Windows. That is the form
CI jobs use, since no interactive shell is involved.
Run a tool
In a project that is already set up, there is nothing to do first:
$ git clone https://github.com/acme/firmware && cd firmware
$ cmake --version
[envy.cmake@r0] installed (8.2s)
cmake version 4.4.0
That one line of install output is the whole setup. bin/cmake is a committed
wrapper, it asked bin/envy for cmake's path, bin/envy downloaded the pinned
envy, and envy installed cmake. The second call prints only cmake's own output.
Only what that tool needed was installed, not the whole manifest. See Installation.
Install everything at once
When on-demand is not what you want, install fills the cache and stops there:
$ envy install
[envy.cmake@r0] installed (8.2s)
[envy.ninja@r0] installed (1.1s)
[envy.python@r1] installed (31.4s)
One line per package. Reach for it before going offline, and in CI when you want the job to fail at install rather than mid-compile.
sync is the same thing plus the bin directory, so it adds a summary line when
the bin directory changed:
$ envy sync
deploy: 12 product script(s) (1 created, 0 updated, 11 unchanged, 0 removed)
Run that one after editing the manifest, which is when a wrapper has to be written or pruned. Both are idempotent and incremental, and running either again installs nothing.
Run it a second time and it prints nothing:
$ envy sync
$
That means it succeeded. A package prints a line only if it did something, and the deploy summary appears only when a wrapper was written or pruned, so a project that is already correct has nothing to report. Redirect the output to a file and every package prints its outcome again, which is what keeps CI logs complete. See a run with no work is silent.
The three verbs
They are not synonyms.
| Command | Packages | Bin directory |
|---|---|---|
envy install | installs | untouched |
envy deploy | untouched | written, refreshed, pruned |
envy sync | installs | written, refreshed, pruned |
install is for warming a cache without touching the work tree, which is what
you want in a Docker layer, a CI cache step, or anything you would rather not
see in git status. deploy is for restoring a bin directory you cleaned, or
picking up a product a spec just added, without reinstalling anything. sync is
for a manifest edit, when both halves apply.
The bin directory is the whole distinction. A wrapper resolves its package at
call time, so a version bump, a cache wipe, or a switch to a project-local cache
changes nothing about the wrappers and needs no sync. Adding, removing, or
renaming a product does.
Three ways to run project tools
- The wrappers.
cmake. Committed, zero setup, works in any shell and in CI. See Product Scripts. envy run.envy run make -jputs the bin directory onPATHfor one command and setsENVY_PROJECT_ROOT. Good for scripts, git hooks, and CI.- Shell integration.
cdinto the project and its tools are onPATHuntil you leave.
All three reach the same packages. Pick by context rather than by preference:
wrappers and envy run are deterministic anywhere, hooks are for interactive
work.
Asking envy questions
$ envy product # every product, and who provides it
cmake bin/cmake envy.cmake@r0{["version"]="4.4.0"}
ctest bin/ctest envy.cmake@r0{["version"]="4.4.0"}
python3 bin/python3 envy.python@r1{["version"]="3.13.14"}
$ envy product cmake # one product, resolved
/Users/you/Library/Caches/envy/packages/envy.cmake@r0/darwin-arm64-blake3-49a9b2620de8c380/pkg/bin/cmake
$ envy package envy.cmake@r0 # the package's whole tree
/Users/you/Library/Caches/envy/packages/envy.cmake@r0/darwin-arm64-blake3-49a9b2620de8c380/pkg
$ envy cache # what is on disk, largest first
Cache: /Users/you/Library/Caches/envy
...
envy product <name> installs the provider if it is missing, so it doubles as
"install just this one thing".
Working on a subset
Queries select manifest entries by identity:
envy install envy.cmake@r0 # this entry and its dependencies
envy install python # matches any namespace and revision
See query forms. Prefer install
while iterating. A filtered sync prunes wrappers outside the filtered subgraph,
so if you do use one, follow it with a bare sync when you are done.
What is safe
- Deleting the cache. Everything in it is reconstructible.
rm -rfis the supported cleanup tool. - Running
syncrepeatedly. It is incremental, and a no-op when nothing changed. - Interrupting a run. A partial install is never marked complete, so the next run redoes it. Verified downloads survive, so the retry is cheaper.
Next
- Shell integration for
cd-based activation. - Adding Packages for editing the manifest.
- Concepts for how any of this works.