Giter VIP home page Giter VIP logo

nix-direnv's Introduction

nix-direnv

Test

A faster, persistent implementation of direnv's use_nix, 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.1.1; then
  source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.1.1/direnvrc" "sha256-b6qJ4r34rbE23yWjMqbmu3ia2z4b2wIlZUksBke/ol0="
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.extraOptions = ''
    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/.direnvrc

# put this in ~/.direnvrc
source /run/current-system/sw/share/nix-direnv/direnvrc
With nix-envAs non-root user do the following:

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

Then add nix-direnv to $HOME/.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 ~/.direnvrc or ~/.config/direnv/direnvrc:

# put this in ~/.direnvrc or ~/.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 same directory:

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

pkgs.mkShell {
  nativeBuildInputs = [ 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 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, default.nix and shell.nix
  • for use flake this is ~/.direnvrc, ~/.config/direnv/direnvrc, .envrc, flake.nix, flake.lock and devshell.toml

To add more files to be checked use nix_direnv_watch_file like this: nix_direnv_watch_file your-file.nix

General direnv tips

Other projects in the field

nix-direnv's People

Contributors

aaqaishtyaq avatar amarshall avatar bbenne10 avatar bbigras avatar crabtw avatar cyntheticfox avatar davhau avatar dependabot[bot] avatar dergutemoritz avatar enzime avatar erikarvstedt avatar ew-at-vier avatar fzakaria avatar github-actions[bot] avatar hoverbear avatar ismaelbouyaf avatar jesusmtnez avatar johnae avatar joncol avatar lrworth avatar m4dc4p avatar manusajith avatar martinetd avatar matt-snider avatar meck avatar mergify[bot] avatar mic92 avatar petarkirov avatar ryneeverett avatar sir4ur0n 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.