Hi! Let me share with you a simple use case that got me headaches.
I have a project with a bin/
subdirectory in which there are some shell scripts, the project has a shell.nix
that loads many packages and I wanted to add bin/myscript
to the $PATH
so users could run myscript
from your shell while working on the project.
Here is my shell.nix
file stripped down with the necessary bits remaining:
{ pkgs ? import <nixpkgs> {} }:
let
myscript-local = pkgs.writeShellScriptBin "myscript" (builtins.readFile ./bin/myscript);
in
with pkgs;
mkShell {
packages = [ myscript-local ];
}
As the script has many lines of code, I didn’t want to write it verbatim in shell.nix because it’s not practical for editing and testing. I needed to import the local file into writeShellScriptBin, this was possible thanks to builtins.readFile.
Note the ./
in ./bin/myscript
path, this is a syntax to turn the relative path into an absolute path, required for nix-shell, using bin/myscript
would return an error like “nix-shell needs absolute paths”. There was another trap here, paths are not string, so they shouldn’t be quoted.