https://github.com/target/lorri
lorri is a nix-shell
replacement for project development. lorri is
based around fast direnv integration for robust CLI and editor
integration.
The project is about experimenting with and improving the developer's experience with Nix. A particular focus is managing your project's external dependencies, editor integration, and quick feedback.
lorri supports Linux and macOS.
You can find the lorri tutorial in the ./example
directory. After following this tutorial, you will have
a working setup of lorri
, direnv
, and working basic editor
integration into Emacs.
Please use the issue tracker
for any problems or bugs you encounter. We are on #lorri
on
freenode
(Webchat), though we might not be responsive at all
times.
All development on lorri happens on the Github repository, in the open. You can propose a change in an issue, then create a pull request after some discussion. Some issues are marked with the “good first issue” label, those are a good place to start. Just remember to leave a comment when you start working on something.
You will need direnv v2.19.2 or later.
On NixOS, we have a simple service for installing and enabling the
needed direnv version at ./direnv/nixos.nix.
Download this file and add imports = [ ./direnv.nix ];
to your
system's configuration.nix
.
For Nix on Linux or macOS, you can install the needed version of direnv with:
$ curl -o direnv.nix -L https://github.com/target/lorri/raw/master/direnv/nix.nix
$ nix-env -if ./direnv.nix
Enable direnv according to its setup instructions.
Install with nix-env:
$ git clone -b rolling-release https://github.com/target/lorri.git
$ cd lorri
$ nix-env -if .
Create a file named .envrc
in your project's root with the contents:
eval "$(lorri direnv)"
Then, run lorri watch
. The first time you run lorri watch
on a
project, wait for it to print Completed
before continuing. Leave
this terminal open.
In a new terminal:
- enter the project directory
- run
direnv allow
- watch as direnv loads the environment
The lorri watch
process will continue monitoring and evaluating
the Nix expressions, and direnv will automatically reload the
environment as it changes. If you close lorri watch
, direnv will
still load the cached environment when you enter the directory,
but the environment will not reload.
Set these environment variables when debugging:
RUST_LOG=lorri=debug RUST_BACKTRACE=1 lorri watch
lorri
sometimes recursively watches a directory that the user did
not expect. This can happen for a number of reasons:
- When using a local checkout instead of a channel for
nixpkgs
,lorri
watches that directory recursively, and will trigger on any file change. - When specifying
src
via a path, (like the much-usedsrc = ./.;
)lorri
watches that path recursively (see target#6 for details). To get around this, use abuiltins.filterSource
-based function to filtersrc
, e.g., usenix-gitignore
:src = pkgs.nix-gitignore.gitignoreSource [] ./.
, or one of the functions innixpkgs/lib/sources.nix
- When using a construct like
import ./.
to import adefault.nix
file,lorri
watches the current directory recursively. To get around it, useimport ./default.nix
.
Upgrading lorri is easy with the lorri self-upgrade
command.
By default, the upgrade command will upgrade from the
rolling-release
branch.
Other upgrade options are available, including upgrading from a
local clone. See lorri self-upgrade --help
for more details.
The evaluator should eagerly reevaluate the Nix expressions as soon as anything material to their output changes. This takes place in a few stages.
builder::run()
instantiates (and builds) the Nix expression with
nix-build -vv
. The evaluator prints each imported Nix file, and
each copied source file. builder::run()
parses the log and notes each
of these paths out as an "input" path.
Each input path is the absolute path which Nix examined.
Each input path is then passed to PathReduction
which examines each
path referenced, and reduces it to a minimum set of paths with the
following rules:
- Discard any store paths which isn't a symlink to outside the store: they are immutable.
- Replace any store path which is a symlink to outside the store to the destination of the symlink.
- Replace a reference to a Nix Channel with the updateable symlink
root of the channel. Concretely, replace the path
/nix/var/nix/profiles/per-user/root/channels/nixos/default.nix
with/nix/var/nix/profiles/per-user/root/
to watch for the channels symlink to change.
Initial testing collapses over 2,000 paths to just five.
Each identified path is watched for changes with inotify (Linux) or fsevent (macOS). If the watched path is a directory, all of its sub-directories are also watched for changes.
Each new batch of change notifications triggers a fresh evaluation. Newly discovered paths are added to the watch list.
lorri creates an indirect garbage collection root for each .drv in
$XDG_CACHE_HOME/lorri
(~/.cache/lorri/
by default) each time it
evaluates your project.
Copyright 2019 Target
License: Apache 2.0 (see LICENSE
file)
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
#################( )############################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################
################################################################