I have a shell.nix
configuration retrieving a pkgs
from a variable like so:
{ pkgs ? import <nixpkgs> { } }:
with pkgs;
let
nodeJs = "pkgs.nodejs_${builtins.getEnv "NODE_VERSION"}";
terraform = pkgs.writers.writeBashBin "terraform" ''
${pkgs.terraform}/bin/terraform "$@"
'';
in
pkgs.mkShell {
buildInputs = [
nodeJs
terraform
pkgs.ngrok
];
}
But when I run nix shell
I get:
build input pkgs.nodejs_20 does not exist
Yet, if I was to run it straight up (without variable) like so:
{ pkgs ? import <nixpkgs> { } }:
with pkgs;
pkgs.mkShell {
buildInputs = [
nodejs_20
terraform
pkgs.ngrok
];
}
This would work fine. I think it's being interpreted as a string. I cannot figure a way to write this variable as anything other than a string without throwing a syntax error.
How would I resolve this, Is this even possible to install a pkgs
based off an environment variable?
"pkgs.nodejs_${builtins.getEnv "NODE_VERSION"}"
is a string, and so doesn't refer to a package. To create a dynamic reference to a package, you need to instead construct a string and convert the whole thing to a reference via string interpolation (${}
). That is, pkgs.${"nodejs_" + builtins.getEnv "NODE_VERSION"}
:
❯ NODE_VERSION=20 nix repl --file '<nixpkgs/nixos>'
Welcome to Nix 2.18.7. Type :? for help.
Loading installable ''...
Added 6 variables.
nix-repl> pkgs.${"nodejs_" + builtins.getEnv "NODE_VERSION"}
«derivation /nix/store/3hxn26fh3cpz4rnx3lcwm5cb0vg15rzk-nodejs-20.17.0.drv»