devenv && direnv
Updated: September 28, 2024
Provides containerized packages and session variables to a devShell environment.
There is also Direnv for just when inside a specific directory.
First we will go over a development environment.
We can just make various types of shells.
mkShell
This will produce a shell default for when we type
nix-shell
This will not work fornix shell
because it requires a flake.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "node"; # name of the shell
packages = with pkgs; [
git
node
];
}
direnv
To use direnv in the nix flake we need nix-direnv.
This makes it so when we enter the directory where a .envrc file is, direnv will activate. The direnv is configured by the .envrc file:
use flake . --impure
In order to use a .envrc file we need permissions:
direnv allow
This ties the .envrc environment into our shell environment.
devenv
Devenvs can be implemented through a flake or imported as a module.
Devenv takes mkShell to next level. It will activate itself using hooks, instead of us typingnix-shell
.
Key notes regarding devenv:
# Can use inside a flake with .envrc file, just uses `use flake` instead of `use nix`
# For inside a flake add this to inputs
devenv.url = "github:cachix/devenv";
# then inside `mkFlake`:
imports = [
inputs.devenv.flakeModule
];
# create a lockfile, then all set
nix flake lock
# open the `devenv` with --impure to allow host env and configuration into the shell
# (this would also create a lock file) devenv reuires --impure and in direnv via devenv
nix develop --impure
Devenv as a module (configuration file) like devenv-hugo.nix
if you use definitions from the flake it is no longer standalone
# inside perSystem = { ... }: {
devenv.shells.default = {
# here we added imports inside with default as the name
imports = [ ./devenv-foo.nix ];
enterShell = ''
hello
'';
};
The devenv-hugo module could looks something like this:
{ config, lib, ... }:
let cfg = config.services.foo;
in {
options = {
services.foo = {
package = lib.mkOption {
type = lib.types.package;
defaultText = lib.literalMD "defined internally";
description = "The foo package to use.";
};
# ...
};
};
config = lib.mkIf cfg.enable {
processes.foo.exec = "${cfg.package}/bin/foo";
};
}