Code Monkey home page Code Monkey logo

sorri's Introduction

SORRI

Just Add Water direnv support for the nix-shell.

Install

Add sorri to your project:

$ curl https://raw.githubusercontent.com/nmattia/sorri/master/sorri --create-dirs --output nix/sorri

Update your .envrc to use sorri:

$ echo ". nix/sorri $(basename $PWD)" > .envrc

You're all set!

The sorri helper

The sorri helper bootstraps projects for you. Install it with:

nix-env -if https://github.com/nmattia/sorri/tarball/master

... and from then on use:

$ sorri init

inside your project.

How It Works

This is a simple, lightweight implementation of Tweag's lorri

sorri reuses lorri's tricks for figuring out the files to track for changes, but uses direnv's own mechanism for actually tracking those files. sorri uses a local cache at '~/.cache/sorri//v/'. Each entry is a directory containing two files:

  ~/.cache/sorri/niv/v1/
  └── 0716a121e4f986f9f8cf11f7c579d332
      ├── link -> /nix/store/jfzkisfgmv3qgpzz3i8nai12y1cry77v-nix-shell
      └── manifest

link is the result of a previous evaluation. manifest is used to find that result of a previous evaluation. The directory name (0716a121e4f986f9f8cf11f7c579d332 above) is the hash of the manifest.

link is a symlink to a shell script that sets a shell's variables.

  cat ~/.cache/sorri/niv/v1/0716a121e4f986f9f8cf11f7c579d332/link
  declare -x AR_x86_64_apple_darwin="/nix/store/amsm28x2hnsgp8c0nm4glkjc2gw2l9kw-cctools-binutils-darwin-927.0.2/bin/ar"
  declare -x BZ2_LIB_DIR="/nix/store/7yikqcm4v4b57xv3cqknhdnf0p1aakxp-bzip2-1.0.6.0.1/lib"
  declare -x BZ2_STATIC="1"
  declare -x CARGO_BUILD_TARGET="x86_64-apple-darwin"
  declare -x CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_LINKER="/nix/store/swiic36rl7njy6bfll5z0afl42c9q4s5-lld-9.0.1/bin/lld"

manifest is a list of files used for an evaluation alongside their checksums:

  $ cat ~/.cache/sorri/niv/v1/0716a121e4f986f9f8cf11f7c579d332/manifest
  /Users/nicolas/niv/shell.nix:029451f2a9bee59f4ce002bdbdf20554
  /Users/nicolas/niv/nix/default.nix:7ff8c9138044fc7e31f1d4ed2bf1c0ba
  /Users/nicolas/niv/nix/overlays/buf/default.nix:c4a24e0bba0178b73f0211d0f26147e6
  ...

sorri first checks the existing cache entries (sorri/niv/v1/0716..., etc); if it finds a cache entry with a manifest where all the manifest entries (nix/default.nix:7ff...) match local files, the link is loaded; if no manifest matches, a new entry is created and loaded.

sorri's People

Contributors

davhau avatar inlaw avatar nmattia avatar purcell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

davhau inlaw purcell

sorri's Issues

ERROR: no link found

This might have been triggered by a recent garbage collect. Even a direnv reload doesn't help.

~/p/g/mach-nix ❯❯❯ cat .envrc
. nix/sorri mach-nix
~/p/g/mach-nix ❯❯❯ direnv allow
direnv: loading ~/synced/projects/github/mach-nix/.envrc
sorri: looking for matching cached shell in /home/grmpf/.cache/sorri/mach-nix/v2
sorri: using cache created Mon 19 Oct 2020 02:07:00 PM +07 (701eded07fcffa8542ed4cf355fdf56f)
sorri: ERROR: no link found at /home/grmpf/.cache/sorri/mach-nix/v2/701eded07fcffa8542ed4cf355fdf56f/link
sorri: please run 'direnv allow' to reload the shell
direnv: error exit status 1
~/p/g/mach-nix ❯❯❯ direnv reload
direnv: loading ~/synced/projects/github/mach-nix/.envrc
sorri: looking for matching cached shell in /home/grmpf/.cache/sorri/mach-nix/v2
sorri: using cache created Mon 19 Oct 2020 02:07:02 PM +07 (701eded07fcffa8542ed4cf355fdf56f)
sorri: ERROR: no link found at /home/grmpf/.cache/sorri/mach-nix/v2/701eded07fcffa8542ed4cf355fdf56f/link
sorri: please run 'direnv allow' to reload the shell
direnv: error exit status 1

Performance bottleneck

Hi Nicolas,

For a few years, I've been maintaining my own Direnv script based on ideas from the Nix integration page on the Direnv wiki. In the meantime, the field of projects filling this space expanded a lot (Lorri, Sorri, Nixify, for example). So I took a moment to dive into each to decide if I should continue maintaining my own, or just use something maintained by someone else.

In the process of doing that, I found differences in performance with both Lorri and Sorri. The evaluation time for these were both at times around 2x the speed of just going into a Nix shell directly. That overhead isn't as perceptible with Lorri, because it runs as a background process. But it's a more noticeable hit for Sorri, when first building out an environment.

The slowdown seems to be almost entirely due to slipping in tracing on reading files with overrides. I have a toy Haskell project I was playing around with, and just entering a Nix Shell was taking me ~30 seconds (because of some Haskell.nix-based dependencies). That's pretty bad, but at least I have caching. The first-time hit is kind of annoying, though. And if changing files frequently, this could get pretty annoying. When I switched from lightweight auto-detection (no tracing) to full auto-detection, the only file I picked up for the extra 30 seconds of evaluation was the sources.json file from my usage of Niv (that tool is great, thanks for it). Over a minute of evaluation time is pretty extreme for a toy project (granted, Nix has terrible evaluation times, and Haskell.nix only stresses that).

I don't have a PR, but hopefully I've described the problem clearly enough. But that gets to something else I was hoping to run by you.

In all this exploration, I did end up iterating on my own personal project, and though I originally had no desire to rewrite something someone else has worked on, I think this is what I have ended up doing, just to prove out all the ideas I was thinking should be implemented.

Could you have a look at this project? https://github.com/shajra/direnv-nix-lorelei. I'd really appreciate your feedback. I think it has all the functionality Sorri does. The readme file has a small writeup comparing it with prior art. The idea I wanted to play around with was calling Lorri directly, rather than copying/pasting code from that project. I think I pulled that off okay. Also I rolled in a lot of features from all the other scripts that are out there. I did, though, deviate from your approach of scaffolding projects with a script called from .envrc. My approach to installation/configuration is more along the conventional lines of installing into ~/.config/direnv/lib. I do, though, use Nix to directly tie in all the dependencies needed by the script (so users can have confidence it will work upon installation).

There's so many of these projects out there. I empathize with new users confused by yet-another-option. So if you like what you see with Lorelei, I'm curious if you'd be open to joining forces behind one project.

Installation as ~/.config/direnv/lib/sorri.sh

I think I have a preference of installing a tool like sorri globally as a library. I think you're file is very close. I just need to crop out the last call to sorri_main.

So it's not like I'm blocked or anything, this is easy enough to do.

But if you think it's a good idea, I wonder if we can make it more of an official way to install sorri as a courtesy to new users.

Would you be opposed to taking out the last call to sorri_main? And then just allowing the invocation to be done explicitly in the user's .envrc file? On that note, "sorri_main" seems like a bit of an internal name. Could we just make it "sorri" instead?

I think the instructions on the README would then be:

$ echo ". nix/sorri; sorri $(basename $PWD)" > .envrc

Is that too bad? Any suggested alternative?

sorri triggers infinite shell recursion

I'm using direnv with fish and whenever sorri detects a change and decides to re-evaluate, I'm getting:

~/p/g/mach-nix ❯❯❯ 
direnv: loading ~/synced/projects/github/mach-nix/.envrc
sorri: looking for matching cached shell in /home/grmpf/.cache/sorri/mach-nix/v2
sorri: no candidate accepted, creating manifest
sorri: building shell, this may take a while
direnv: ([/nix/store/086y8hv6ayv0y90690xbff0lxgrpi6k8-direnv-2.21.2-bin/bin/direnv export fish]) is taking a while to execute. Use CTRL-C to give up.
bash: warning: shell level (1000) too high, resetting to 1
bash: warning: shell level (1000) too high, resetting to 1
bash: warning: shell level (1000) too high, resetting to 1
... (goes on forever)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.