Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Latest commit

 

History

History
150 lines (110 loc) · 5.04 KB

use-direnv.md

File metadata and controls

150 lines (110 loc) · 5.04 KB

Have you ever used a tool like pip's bin/activate script, or rbenv? These tools populate your shell environment with the right tools and scripts and dependencies (e.g. PYTHONPATH) to run your software.

What if I told you there was a magical tool that worked like that, and could do it for arbitrary languages and tools?

That tool is called direnv.

Install direnv and use it in your shell

First, install direnv:

$ nix profile install nixpkgs#direnv
$ which direnv
/home/austin/.nix-profile/bin/direnv

Now, you need to activate it in your shell by hooking into it. If you're using Bash, try putting this in your .bashrc and starting up a new interactive shell:

eval "$(direnv hook bash)"

Not using bash? Check the direnv hook documentation for more.

Set up nix-postgres

Let's go back to the nix-postgres source code.

cd $HOME/tmp-nix-postgres

Now, normally, direnv is going to look for a file called .envrc and load that if it exists. But to be polite, we don't do that by default; we keep a file named .envrc.recommended in the repository instead, and encourage people to do this:

echo "source_env .envrc.recommended" >> .envrc

All this says is "Load the code from .envrc.recommended directly", just like a normal bash script using source. The idea of this pattern is to allow users to have their own customized .envrc and piggyback on the committed code for utility — and .envrc is .gitignore'd, so you can put e.g. secret tokens inside without fear of committing them.

Run the above command, and then...

What just happened?

Oops, a big red error appeared?

$ echo "source_env .envrc.recommended" >> .envrc
direnv: error /home/austin/work/nix-postgres/.envrc is blocked. Run `direnv allow` to approve its content

What happened? By default, as a security measure, direnv does not load or execute any code from an .envrc file, and instead it MUST be allowed explicitly.

direnv allow

Our .envrc.recommended file will integrate with Nix directly. So run direnv allow, and you'll suddenly see the following:

$ direnv allow
direnv: loading ~/work/nix-postgres/.envrc
direnv: loading ~/work/nix-postgres/.envrc.recommended
direnv: loading https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc (sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8=)
direnv: using flake
direnv: nix-direnv: renewed cache
direnv: export +AR +AS +CC +CONFIG_SHELL +CXX +DETERMINISTIC_BUILD +HOST_PATH +IN_NIX_SHELL +LD +NIX_BINTOOLS +NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_BUILD_CORES +NIX_CC +NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_CFLAGS_COMPILE +NIX_ENFORCE_NO_NATIVE +NIX_HARDENING_ENABLE +NIX_LDFLAGS +NIX_STORE +NM +OBJCOPY +OBJDUMP +PYTHONHASHSEED +PYTHONNOUSERSITE +PYTHONPATH +RANLIB +READELF +SIZE +SOURCE_DATE_EPOCH +STRINGS +STRIP +_PYTHON_HOST_PLATFORM +_PYTHON_SYSCONFIGDATA_NAME +__structuredAttrs +buildInputs +buildPhase +builder +cmakeFlags +configureFlags +depsBuildBuild +depsBuildBuildPropagated +depsBuildTarget +depsBuildTargetPropagated +depsHostHost +depsHostHostPropagated +depsTargetTarget +depsTargetTargetPropagated +doCheck +doInstallCheck +dontAddDisableDepTrack +mesonFlags +name +nativeBuildInputs +out +outputs +patches +phases +preferLocalBuild +propagatedBuildInputs +propagatedNativeBuildInputs +shell +shellHook +stdenv +strictDeps +system ~PATH ~XDG_DATA_DIRS

What just happened is that we populated the ambient shell environment with tools specified inside of flake.nix — we'll cover Flakes later. But for now, your tools are provisioned!

Run just to build the code

Previously, we needed to run nix develop to get access to the just command. No longer! It's now available in your shell:

$ which just
/nix/store/1di6nb4qsv86907l3xarw4llzdss2g89-just-1.14.0/bin/just
$ just b
...

Viola, done!

Go back $HOME and return again

When you cd ~, direnv will automatically unload the .envrc file for you:

$ cd ~
direnv: unloading

Now, just is no longer available:

$ just build-all
just: command not found

And if you go back, it is!

$ cd $HOME/nix-postgres
direnv: loading ~/work/nix-postgres/.envrc
direnv: loading ~/work/nix-postgres/.envrc.recommended
direnv: loading https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc (sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8=)
direnv: using flake
...
$ just build-all
...

The power of direnv

direnv with Nix is a frighteningly good development combination for many purposes. This is its main power: you can use it to create on-demand developer shells for any language, tool, or environment, and all you need to do is cd to the right directory.

This is the power of direnv: your projects always, on demand, will have the right tools configured and available, no matter if you last worked on them a day ago or a year ago, or it was done by your teammate, or you have a brand new computer that you've never programmed on.