i have some bash scripts i am converting to nix packages. in those i like to use a library script, so i would like to have it as its own nix package for reuse between scripts. now i only lack a way of elegantly sourcing/linking the library in the scripts. i know that packages in other languages have a way of getting dependencies from nix packages, but how could one accomplish the same for bash?
what i have so far and how i would like it to work
i have already turned the library into its own nix package. the script using the library is packaged using writeShellApplication and i’m reading the script from a separate sh file. i know one can get the path to a package in the nix store when writing the contents of the script into the text property as a string directly (something like text = "source ${pkgs.my-lib}/lib/my-lib.sh"), but i want to keep the script itself separate from the package file.
to have a similar way of getting to the path of the library, i have so far added a script that just outputs the path to itself/the package in the nix store, that i can then use in scripts. that however feels a bit hacky aswell and not really like the nix-way, if you understand what i mean.
maybe it will always have to be a bit inelegant like this (at least for my taste), but any help and advice on this niche problem is appreciated.
thanks in advance :)
Here are two simple-ish ways to think about accomplishing this without much change beyond what you’ve got right now:
The source builtin will search PATH, so I imagine if you moved the library script to /bin/my-lib.sh and use source my-lib.sh in the script, it might be able to pick it up if you add it as one of the runtimeInputs in writeShellApplication.
If you’re okay with using an environment variable in the source of your sourcing script (i.e., source MY_LIB), you could use writeShellApplication’s runtimeEnv attr to specify the path to the library.
One caveat is that there’s just one PATH–your library package can’t also have its own distinct runtime dependencies that come from the PATH without things starting to get cumbersome. Either each script that uses the library would have to include the library’s runtime dependencies, or the absolute path of each reference to those dependencies needs to get built into the library.
If you need to handle that, there are again a few approaches:
If the library’s shell source is in the .nix file, you can just inline all of the references.
You can do this semi-manually with the various substitute* functions in nixpkgs, but you’ll either need to be careful about overmatching or partially rewrite the library source with @thingToReplace@ placeholders to mitigate that risk.
It’s a little more complex (has its own levers to learn), but resholve is basically designed around satisfying this use-case without having to inline scripts or make their source unusable outside of a Nix package.
It’s a little contrived, but resholve’s Nix API ~demo exercises the ability to integrate shell libraries with their own dependencies: