Skip to content

Commit

Permalink
Use Nix to manage the development environment
Browse files Browse the repository at this point in the history
  • Loading branch information
ejpcmac committed Sep 4, 2018
1 parent 33f35ae commit 98f983e
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 4 deletions.
84 changes: 84 additions & 0 deletions .envrc
@@ -0,0 +1,84 @@
####################################
# Environment setup for Nix shells #
####################################

# From https://github.com/direnv/direnv/wiki/Nix#persistent-cached-shell
#
# Usage: use_nix [...]
#
# Load environment variables from `nix-shell`.
# If you have a `default.nix` or `shell.nix` one of these will be used and
# the derived environment will be stored at ./.direnv/env-<hash>
# and symlink to it will be created at ./.direnv/default.
# Dependencies are added to the GC roots, such that the environment remains persistent.
#
# Packages can also be specified directly via e.g `use nix -p ocaml`,
# however those will not be added to the GC roots.
#
# The resulting environment is cached for better performance.
#
# To trigger switch to a different environment:
# `rm -f .direnv/default`
#
# To derive a new environment:
# `rm -rf .direnv/env-$(md5sum {shell,default}.nix 2> /dev/null | cut -c -32)`
#
# To remove cache:
# `rm -f .direnv/dump-*`
#
# To remove all environments:
# `rm -rf .direnv/env-*`
#
# To remove only old environments:
# `find .direnv -name 'env-*' -and -not -name `readlink .direnv/default` -exec rm -rf {} +`
#
use_nix() {
set -e

local shell="shell.nix"
if [[ ! -f "${shell}" ]]; then
shell="default.nix"
fi

if [[ ! -f "${shell}" ]]; then
fail "use nix: shell.nix or default.nix not found in the folder"
fi

local dir="${PWD}"/.direnv
local default="${dir}/default"
if [[ ! -L "${default}" ]] || [[ ! -d `readlink "${default}"` ]]; then
local wd="${dir}/env-`md5sum "${shell}" | cut -c -32`" # TODO: Hash also the nixpkgs version?
mkdir -p "${wd}"

local drv="${wd}/env.drv"
if [[ ! -f "${drv}" ]]; then
log_status "use nix: deriving new environment"
IN_NIX_SHELL=1 nix-instantiate --add-root "${drv}" --indirect "${shell}" > /dev/null
nix-store -r `nix-store --query --references "${drv}"` --add-root "${wd}/dep" --indirect > /dev/null
fi

rm -f "${default}"
ln -s `basename "${wd}"` "${default}"
fi

local drv=`readlink -f "${default}/env.drv"`
local dump="${dir}/dump-`md5sum ".envrc" | cut -c -32`-`md5sum ${drv} | cut -c -32`"

if [[ ! -f "${dump}" ]] || [[ "${XDG_CONFIG_DIR}/direnv/direnvrc" -nt "${dump}" ]]; then
log_status "use nix: updating cache"

old=`find ${dir} -name 'dump-*'`
nix-shell "${drv}" --show-trace "$@" --run 'direnv dump' > "${dump}"
rm -f ${old}
fi

direnv_load cat "${dump}"

watch_file "${default}"
watch_file shell.nix
if [[ ${shell} == "default.nix" ]]; then
watch_file default.nix
fi
}

use nix
27 changes: 23 additions & 4 deletions .gitignore
@@ -1,18 +1,37 @@
# Application artifacts (Elixir)
##
## Application artifacts
##

# direnv cache for Nix shells
/.direnv/

# Elixir build directory
/_build/

# Elixir dependencies
/deps/
/.fetch

# Elixir binary files
*.beam
*.ez
typed_struct-*.tar
/typed_struct-*.tar
/typed_struct

# Test coverage and documentation
/cover/
/doc/

# Editor artifacts
##
## Editor artifacts
##

/.elixir_ls/
/.history/

# Crash dumps
##
## Crash dumps
##

# Erang VM
erl_crash.dump
49 changes: 49 additions & 0 deletions shell.nix
@@ -0,0 +1,49 @@
{ pkgs ? import <nixpkgs> {} }:

with pkgs;

let
inherit (lib) optional optionals;

erlangDrv = { mkDerivation }:
mkDerivation rec {
version = "21.0";
# Use `nix-prefetch-github --rev OTP-<version> erlang otp` to update.
sha256 = "0khprgawmbdpn9b8jw2kksmvs6b45mibpjralsc0ggxym1397vm8";

prePatch = ''
substituteInPlace configure.in --replace '`sw_vers -productVersion`' '10.10'
'';
};

elixirDrv = { mkDerivation }:
mkDerivation rec {
version = "1.7.3";
# Use `nix-prefetch-github --rev v<version> elixir-lang elixir` to update.
sha256 = "0d7rj4khmvy76z12njzwzknm1j9rhjadgj9k1chjd4gnjffkb1aa";
minimumOTPVersion = "19";
};

erlang = (beam.lib.callErlang erlangDrv { wxGTK = wxGTK30; }).override {
# Temporary fix to enable use on OS X El Capitan.
enableKernelPoll = if stdenv.isDarwin then false else true;
};

rebar = pkgs.rebar.override { inherit erlang; };

elixir = beam.lib.callElixir elixirDrv {
inherit erlang rebar;
debugInfo = true;
};
in

mkShell {
buildInputs = [ elixir git ]
++ optional stdenv.isLinux libnotify # For ExUnit Notifier on Linux.
++ optional stdenv.isDarwin terminal-notifier # For ExUnit Notifier on macOS.
++ optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [
# For file_system on macOS.
CoreFoundation
CoreServices
]);
}

0 comments on commit 98f983e

Please sign in to comment.