Git Product home page Git Product logo

nix-direnv's Introduction

nix-direnv

Test

A faster, persistent implementation of direnv's use_nix and use_flake, to replace the built-in one.

Prominent features:

  • significantly faster after the first run by caching the nix-shell environment
  • prevents garbage collection of build dependencies by symlinking the resulting shell derivation in the user's gcroots (Life is too short to lose your project's build cache if you are on a flight with no internet connection)

Why not use lorri instead?

Compared to lorri, nix-direnv is simpler (and requires no external daemon) and supports flakes. Additionally, lorri can sometimes re-evaluate the entirety of nixpkgs on every change (leading to perpetual high CPU load).

Installation

Heads up: nix-direnv requires a modern Bash and GNU Grep. MacOS ships with outdated or non-GNU versions of these tools, As a work-around we suggest that macOS users install direnv/grep via Nix or Homebrew. Discussion of these problems can be found here.

There are different ways to install nix-direnv, pick your favourite:

Via home-manager (Recommended)

Via home-manager

Note that while the home-manager integration is recommended, some use cases require the use of features only present in some versions of nix-direnv. It is much harder to control the version of nix-direnv installedwith this method. If you require such specific control, please use another method of installing nix-direnv.

In $HOME/.config/nixpkgs/home.nix add

{ pkgs, ... }:

{
  # ...other config, other config...

  programs.direnv.enable = true;
  programs.direnv.nix-direnv.enable = true;
  # optional for nix flakes support in home-manager 21.11, not required in home-manager unstable or 22.05
  programs.direnv.nix-direnv.enableFlakes = true;

  programs.bash.enable = true;
  # OR
  programs.zsh.enable = true;
  # Or any other shell you're using.
}

Optional: To protect your nix-shell against garbage collection you also need to add these options to your Nix configuration.

If you are on NixOS also add the following lines to your /etc/nixos/configuration.nix:

{ pkgs, ... }: {
  nix.extraOptions = ''
    keep-outputs = true
    keep-derivations = true
  '';
}

On other systems with Nix add the following configuration to your /etc/nix/nix.conf:

keep-derivations = true
keep-outputs = true
Direnv's source\_url

Direnv source_url

Put the following lines in your .envrc:

if ! has nix_direnv_version || ! nix_direnv_version 2.3.0; then
  source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc" "sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8="
fi
Via configuration.nix in NixOS

Via configuration.nix in NixOS

In /etc/nixos/configuration.nix:

{ pkgs, ... }: {
  environment.systemPackages = with pkgs; [ direnv nix-direnv ];
  # nix options for derivations to persist garbage collection
  nix.settings = {
    keep-outputs = true;
    keep-derivations = true;
  };
  environment.pathsToLink = [
    "/share/nix-direnv"
  ];
  # if you also want support for flakes
  nixpkgs.overlays = [
    (self: super: { nix-direnv = super.nix-direnv.override { enableFlakes = true; }; } )
  ];
}

Then source the direnvrc from this repository in your own $HOME/.config/direnv/direnvrc

# put this in ~/.config/direnv/direnvrc
source /run/current-system/sw/share/nix-direnv/direnvrc
With `nix-env`

With nix-env

As non-root user do the following:

nix-env -f '<nixpkgs>' -iA nix-direnv

Then add nix-direnv to $HOME/.config/direnv/direnvrc:

source $HOME/.nix-profile/share/nix-direnv/direnvrc

You also need to set keep-outputs and keep-derivations to nix.conf as described in the installation via home-manager section.

With `nix profile`

With nix profile

As non-root user do the following:

nix profile install nixpkgs#nix-direnv

Then add nix-direnv to $HOME/.config/direnv/direnvrc:

source $HOME/.nix-profile/share/nix-direnv/direnvrc

You also need to set keep-outputs and keep-derivations to nix.conf as described in the installation via home-manager section.

From source

From source

Clone the repository to some directory and then source the direnvrc from this repository in your own ~/.config/direnv/direnvrc:

# put this in ~/.config/direnv/direnvrc
source $HOME/nix-direnv/direnvrc

You also need to set keep-outputs and keep-derivations to nix.conf as described in the installation via home-manager section.

Usage example

Either add shell.nix or a default.nix to the project directory:

# save this as shell.nix
{ pkgs ? import <nixpkgs> {}}:

pkgs.mkShell {
  packages = [ pkgs.hello ];
}

Then add the line use nix to your envrc:

$ echo "use nix" >> .envrc
$ direnv allow

If you haven't used direnv before, make sure to hook it into your shell first.

Using a non-standard file name

You may use a different file name than shell.nix or default.nix by passing the file name in .envrc, e.g.:

$ echo "use nix foo.nix" >> .envrc

Flakes support

nix-direnv also comes with an alternative use_flake implementation. The code is tested and does work but the upstream flake api is not finalized, so we we cannot guarantee stability after an nix upgrade.

Like use_nix, our use_flake will prevent garbage collection of downloaded packages, including flake inputs.

Creating a new flake-native project

This repository ships with a flake template. which provides a basic flake with devShell integration and a basic .envrc.

To make use of this template, you may issue the following command:

$ nix flake new -t github:nix-community/nix-direnv <desired output path>

Integrating with a existing flake

$ echo "use flake" >> .envrc && direnv allow

The use flake line also takes an additional arbitrary flake parameter, so you can point at external flakes as follows:

use flake ~/myflakes#project

Advanced usage

use flake

Under the covers, use_flake calls nix print-dev-env. The first argument to the use_flake function is the flake expression to use, and all other arguments are proxied along to the call to print-dev-env. You may make use of this fact for some more arcane invocations.

For instance, if you have a flake that needs to be called impurely under some conditions, you may wish to pass --impure to the print-dev-env invocation so that the environment of the calling shell is passed in.

You can do that as follows:

$ echo "use flake . --impure" > .envrc
$ direnv allow

use nix

Like use flake, use nix now uses nix print-dev-env. Due to historical reasons, the argument parsing emulates nix shell.

This leads to some limitations in what we can reasonably parse.

Currently, all single-word arguments and some well-known double arguments will be interpeted or passed along.

Known arguments
  • -p: Starts a list of packages to install; consumes all remaining arguments
  • --include / -I: Add the following path to the list of lookup locations for <...> file names
  • --attr / -A: Specify the output attribute to utilize

--command, --run, --exclude, --pure, -i, and --keep are explicitly ignored.

All single word arguments (-j4, --impure etc) are passed to the underlying nix invocation.

Tracked files

nix-direnv makes a performance tradeoff and only considers changes in a limited number of files when deciding to update its cache.

  • for use nix this is:

    • ~/.direnvrc
    • ~/.config/direnv/direnvrc
    • .envrc,
    • A single nix file. In order of preference:
      • The file argument to use nix
      • default.nix if it exists
      • shell.nix if it exists
  • for use flake this is:

    • ~/.direnvrc
    • ~/.config/direnv/direnvrc
    • .envrc
    • flake.nix
    • flake.lock
    • devshell.toml if it exists

To add more files to be checked use nix_direnv_watch_file like this

nix_direnv_watch_file your-file.nix
use nix # or use flake

Or - if you don't mind the overhead (runtime and conceptual) of watching all nix-files:

nix_direnv_watch_file $(find . -name "*.nix" -printf '"%p" ')

Note that this will re-execute direnv for any nix change, regardless of whether that change is meaningful for the devShell in use.

nix_direnv_watch_file must be invoked before either use flake or use nix to take effect.

General direnv tips

Other projects in the field

nix-direnv's People

Contributors

aaqaishtyaq avatar amarshall avatar bbenne10 avatar bbigras avatar bors[bot] avatar cassandracomar avatar counterposition avatar cyntheticfox avatar davhau avatar dependabot[bot] avatar enzime avatar erikarvstedt avatar ew-at-vier avatar fzakaria avatar github-actions[bot] avatar hannseman avatar hoverbear avatar ismaelbouyaf avatar jesusmtnez avatar johnae avatar joncol avatar kubukoz avatar m4dc4p avatar martinetd avatar meck avatar mergify[bot] avatar mic92 avatar pinselimo avatar qaristote avatar ryneeverett avatar

Watchers

 avatar

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.