I have been looking for a way to keep packages used in my shell.nix
from being garbage collected. Most online sources (1 2 3 ) point to using something along the lines of the following command:
nix-instantiate shell.nix --indirect --add-root ./.nix-gc-roots/shell.drv
and having keep-outputs = true
in shell.nix
, however I have not been able to get it to work. What I step I am missing?
Direnv is the easiest that I know of with the additional benefit of it getting activated.
However be aware that aliases and functions in shellhooks don’t work automatically:
opened 06:44PM - 17 Oct 22 UTC
closed 07:36AM - 18 Oct 22 UTC
I use nix-direnv together with flakes (`use flake`)
My `flake.nix` contains a… `devShell` output with a non-empty `shellHook`. Any aliases, exported variables or custom functions I may define in the `shellHook` won't be sourced to the current shell.
`flake.nix` to reproduce
```
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { nixpkgs, flake-utils, ... }: flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in rec {
devShell = pkgs.mkShell {
shellHook = ''
echo "This is executed"
export VAR_FOO="This is set"
function f_foo {
echo "This is lost"
}
alias a_foo="true"
'';
};
}
);
}
```
`use flake` in the `.envrc`, `direnv allow` to enable devShell.
In the shell
- observe the line `This is executed`
- echo `$VAR_FOO`, observe `This is set`
- try calling `f_foo` (should fail)
- try calling `a_foo` (should fail)
I'd expect aliases and functions to be propagated to the current shell to be consistent with exported variables and other side-effects
1 Like
I am rather new to Nix and have not dipped my toes into flakes yet. My research leads me to believe that they aren’t necessary to accomplishing my goals, has that changed?
Direnv and shellhooks aren’t related to Flakes.
You can use shellhooks in a shell.nix file as well.
1 Like
Thanks for the tip! For most of my packages, direnv
seems to be working. However, the following packages are still being garbage collected:
/nix/store/3mzd4jjvixjjkldnz3mjk7dpbjvl52hg-perl5.36.0-Any-URI-Escape-0.01
/nix/store/byb33msjlx9yaz603irlwkbzyj214bd6-perl5.36.0-YAML-PP-0.026
/nix/store/ihsm38jgs74qxpli4j7q6v1yv83zljq1-gcc-9.5.0-lib
/nix/store/ik9rhgnkagg9x9fb0hhhd3j0pacrcf66-kf5gpgmepp-16.08.3
/nix/store/jnc7klg39rdcravhm9f3jwg1xnfv81c0-xerces-c-3.2.4
/nix/store/pa7ad0v5hs8amap6j09dh72cwc36l0sv-python3-3.11.3
/nix/store/zayrihc2i9a2kl0mcmhqd9yn4xhc97ff-xsd-4.0.0
This is my shell.nix
{ pkgs ? import <nixos> {} }: pkgs.mkShell {
packages = with pkgs; [
bison
boost
cmake
curl
cyrus_sasl
docbook_xml_dtd_45
docbook-xsl-ns
flex
gperf
intltool
libsForQt5.accounts-qt
libsForQt5.kf5gpgmepp
libsForQt5.phonon
libsForQt5.qcoro
libsForQt5.qgpgme
libsForQt5.qtkeychain
libsForQt5.signond
libgcrypt
libical
perl
perl536Packages.AnyURIEscape
perl536Packages.IOSocketSSL
perl536Packages.YAMLPP
pkg-config
polkit
python311
qrencode
qt5.qtbase
qt5.qtnetworkauth
qt5.qttools
qt5.qtquickcontrols2
qt5.qtwayland
qt5.qtwebengine
qt5.qtxmlpatterns
qt5.qtx11extras
util-linux
wayland
wayland-protocols
xapian
xercesc
xsd
xorg.libXdmcp
xz
];
}
Is there any reason why it wouldn’t work for these?
I honestly don’t know and would’ve to test how it behaves on my machine but that would have to wait until after the weekend.