Requires GNU grep
tviti opened this issue · 12 comments
Issue
This isn't really an issue with nix-direnv, but more of a caveate I encountered when trying to use nix-direnv on macOS. I first encountered this using direnv-mode in emacs w/ nix-direnv on macOS, but it looks like it's also a problem just using direnv from bash on macOS.
From a directory that DOESN'T have a cached environment (i.e. .direnv
either doesn't exist or is empty), the following error is shown when making a first attempt at loading the env:
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
[-e pattern] [-f file] [--binary-files=value] [--color=when]
[--context[=num]] [--directories=action] [--label] [--line-buffered]
[--null] [pattern] [file ...]
which results in the creation of an empty cache.
Setup
Directory structure:
nix-direnv-test taylor$ ls -la
total 16
drwxr-xr-x 5 taylor staff 160 Mar 10 11:26 .
drwxr-xr-x 55 taylor staff 1760 Mar 10 11:24 ..
drwxr-xr-x 3 taylor staff 96 Mar 10 11:26 .direnv
-rw-r--r-- 1 taylor staff 8 Mar 10 11:24 .envrc
-rw-r--r-- 1 taylor staff 87 Mar 10 11:25 shell.nix
.direnv
:
use nix
shell.nix
:
let pkgs = import <nixpkgs> { };
in pkgs.mkShell {
buildInputs = [ pkgs.hello ];
}
Steps to reproduce
nix-direnv-test taylor$ direnv allow
direnv: loading ~/Source/nix-direnv-test/.envrc
direnv: using nix
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
[-e pattern] [-f file] [--binary-files=value] [--color=when]
[--context[=num]] [--directories=action] [--label] [--line-buffered]
[--null] [pattern] [file ...]
Fix
The issue seems to be that nix-direnv is trying to invoke the macOS builtin BSD-grep at /usr/bin/grep
, which for one reason or another doesn't like (in direnvrc
):
tmp=$(nix-shell --show-trace --pure "$@" --run "$dump_cmd" \
| grep -oP '(?<=_____direnv_____).*')
I haven't actually spent any time trying to figure out WHY that line is problematic with the builtin grep, but I managed to sort this out by installing nix-direnv with the following derivation, which explicitely uses nixpkgs.gnugrep
{ bash, fetchFromGitHub, gnugrep, stdenv }:
stdenv.mkDerivation {
name = "nix-direnv";
src = fetchFromGitHub {
owner = "nix-community";
repo = "nix-direnv";
rev = "81d3f5083ae68aec5d9f6fc9eebac57c82a9d280";
sha256 = "067493hbsij59bvaqi38iybacqbzwx876dvdm651b5mn3zs3h42c";
};
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
prePatch = ''
substituteInPlace direnvrc --replace "/usr/bin/env bash" "${bash}/bin/bash"
substituteInPlace direnvrc --replace "grep" "${gnugrep}/bin/grep"
'';
installPhase = ''
mkdir -p $out/share/nix-direnv
cp -rv ./* $out/share/nix-direnv
'';
}
Interesting. I might be able to replace this invocation with an awk call that should be portable. Do you now if nix show-derivation $out | grep -E -o -m1 '/nix/store/.*.drv'
is problematic with bsdgrep?
@zimbatm does direnv on macOS uses the builtin bash btw? Because that might also cause problems.
Replacing /usr/bin/env bash
should not have any effect because direnv executes the bash version itself.
yes... direnv uses whatever bash is in the environment
In that case I should suggest people to install direnv
via nixpkgs or get a newer version via $packagemanager. I have not tested bash compatibility though.
The one that comes from nixpkgs is bound to the nixpkgs bash at compile time.
Anyone using Homebrew should also brew install bash
It would be great if direnv
would have something like a .direnv.d or even environment variables to load third party plugins. I think it is time to package nix-direnv in nixpkgs itself.
Can we convince the homebrew maintainers to also hard code bash? https://github.com/Homebrew/homebrew-core/blob/master/Formula/direnv.rb#L18
@Mic92 direnv looks in ~/.config/direnv/lib/*.sh
for additional libs. (since v2.21)
Ok. This would not play well with vanilla nix or most other system package manager in that regard, but a home-manager module could work.
Nix-direnv can now be installed via nix
. This version will hard code nix as well as gnugrep.