Skip to content

Commit

Permalink
use mkNakedShell from devshell for less noisy shell
Browse files Browse the repository at this point in the history
Fixes cachix#79
  • Loading branch information
thenonameguy committed Nov 21, 2022
1 parent 280f550 commit 530a99b
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 34 deletions.
94 changes: 94 additions & 0 deletions src/modules/mkNakedShell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# copied from https://github.com/amarshall/devshell/blob/917a891e98ca26c006a6be1fdb3335a74720c237/nix/mkNakedShell.nix#L1
# to support inputDerivation for easy CI caching as well: https://github.com/numtide/devshell/pull/226
{ bashInteractive
, coreutils
, system
, writeTextFile
}:
let
bashPath = "${bashInteractive}/bin/bash";
stdenv = writeTextFile {
name = "naked-stdenv";
destination = "/setup";
text = ''
# Fix for `nix develop`
: ''${outputs:=out}
runHook() {
eval "$shellHook"
unset runHook
}
'';
};
in
{ name
, # A path to a buildEnv that will be loaded by the shell.
# We assume that the buildEnv contains an ./env.bash script.
profile
, shellHook ? ""
, meta ? { }
, passthru ? { }
}:
let
derivationArg = {
inherit name system;

# `nix develop` actually checks and uses builder. And it must be bash.
builder = bashPath;

# Bring in the dependencies on `nix-build`
args = [ "-ec" "${coreutils}/bin/ln -s ${profile} $out; exit 0" ];

# $stdenv/setup is loaded by nix-shell during startup.
# https://github.com/nixos/nix/blob/377345e26f1ac4bbc87bb21debcc52a1d03230aa/src/nix-build/nix-build.cc#L429-L432
stdenv = stdenv;

# The shellHook is loaded directly by `nix develop`. But nix-shell
# requires that other trampoline.
shellHook = ''
# Remove all the unnecessary noise that is set by the build env
unset NIX_BUILD_TOP NIX_BUILD_CORES NIX_STORE
unset TEMP TEMPDIR TMP TMPDIR
# $name variable is preserved to keep it compatible with pure shell https://github.com/sindresorhus/pure/blob/47c0c881f0e7cfdb5eaccd335f52ad17b897c060/pure.zsh#L235
unset builder out shellHook stdenv system
# Flakes stuff
unset dontAddDisableDepTrack outputs
# For `nix develop`. We get /noshell on Linux and /sbin/nologin on macOS.
if [[ "$SHELL" == "/noshell" || "$SHELL" == "/sbin/nologin" ]]; then
export SHELL=${bashPath}
fi
# https://github.com/numtide/devshell/issues/158
PATH=''${PATH#/path-not-set:}
export PATH="${profile}/bin:$PATH"
${shellHook}
'';
};
in
(derivation derivationArg) // {
inherit meta passthru;

# https://github.com/NixOS/nixpkgs/blob/41f7e338216fd7f5e57817c4f8e148d42fb88b24/pkgs/stdenv/generic/make-derivation.nix#L486-L504
inputDerivation = derivation (derivationArg // {
# Add a name in case the original drv didn't have one
name = derivationArg.name or "inputDerivation";
# This always only has one output
outputs = [ "out" ];

# Propagate the original builder and arguments, since we override
# them and they might contain references to build inputs
_derivation_original_builder = derivationArg.builder;
_derivation_original_args = derivationArg.args;

builder = bashPath;
# The bash builtin `export` dumps all current environment variables,
# which is where all build input references end up (e.g. $PATH for
# binaries). By writing this to $out, Nix can find and register
# them as runtime dependencies (since Nix greps for store paths
# through $out to find them)
args = [ "-c" "export > $out" ];
});
} // passthru
76 changes: 42 additions & 34 deletions src/modules/top-level.nix
Original file line number Diff line number Diff line change
Expand Up @@ -71,39 +71,47 @@ in
./update-check.nix
] ++ map (name: ./. + "/languages/${name}") (builtins.attrNames (builtins.readDir ./languages));

config = {
# TODO: figure out how to get relative path without impure mode
env.DEVENV_ROOT = builtins.getEnv "PWD";
env.DEVENV_DOTFILE = config.env.DEVENV_ROOT + "/.devenv";
env.DEVENV_STATE = config.env.DEVENV_DOTFILE + "/state";

procfile = pkgs.writeText "procfile"
(lib.concatStringsSep "\n" (lib.mapAttrsToList (name: process: "${name}: ${process.exec}") config.processes));

procfileEnv = pkgs.writeText "procfile-env"
(lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name}=${toString value}") config.env));

enterShell = ''
export PS1="(devenv) $PS1"
config =
let
mkNakedShell = pkgs.callPackage ./mkNakedShell.nix { };
in
{
# TODO: figure out how to get relative path without impure mode
env.DEVENV_ROOT = builtins.getEnv "PWD";
env.DEVENV_DOTFILE = config.env.DEVENV_ROOT + "/.devenv";
env.DEVENV_STATE = config.env.DEVENV_DOTFILE + "/state";

procfile = pkgs.writeText "procfile"
(lib.concatStringsSep "\n" (lib.mapAttrsToList (name: process: "${name}: ${process.exec}") config.processes));

procfileEnv = pkgs.writeText "procfile-env"
(lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name}=${toString value}") config.env));

enterShell = ''
export PS1="(devenv) $PS1"
# note what environments are active, but make sure we don't repeat them
if [[ ! "$DIRENV_ACTIVE" =~ (^|:)"$PWD"(:|$) ]]; then
export DIRENV_ACTIVE="$PWD:$DIRENV_ACTIVE"
fi
# devenv helper
if [ ! type -p direnv &>/dev/null && -f .envrc ]; then
echo "You have .envrc but direnv command is not installed."
echo "Please install direnv: https://direnv.net/docs/installation.html"
fi
'';

shell = pkgs.mkShell ({
name = "devenv";
packages = config.packages;
shellHook = config.enterShell;
} // config.env);

ci = [ config.shell config.procfile ];
};
# note what environments are active, but make sure we don't repeat them
if [[ ! "$DIRENV_ACTIVE" =~ (^|:)"$PWD"(:|$) ]]; then
export DIRENV_ACTIVE="$PWD:$DIRENV_ACTIVE"
fi
# devenv helper
if [ ! type -p direnv &>/dev/null && -f .envrc ]; then
echo "You have .envrc but direnv command is not installed."
echo "Please install direnv: https://direnv.net/docs/installation.html"
fi
'';

shell = mkNakedShell {
name = "devenv";
profile = pkgs.buildEnv {
name = "devenv-profile";
paths = config.packages;
};
shellHook = config.enterShell;
passthru = config.env;
};

ci = [ config.shell config.procfile ];
};
}

0 comments on commit 530a99b

Please sign in to comment.