Using Nix to replace language package managers for library versioning and dependencies
So I am investigating using Nix/NixOS to build/deploy a ruby application. (By the way I have no idea what the canonical way to do that is right now) but somewhere along the way a thought occurred to me, and wanted to run it by other people. I'll start with ruby but there is more below.
Why not build a parallel universe for ruby packages that actually abandons ruby gems, and just packages raw ruby code in some semi-standardized source tree? Then use nix to manage the dependencies between them, and have the nix expression place all dependencies into the $LOAD_PATH of the depending package automatically? One simply specifies dependencies for the app, and all of the relevant code appears on the ruby interpreter's $LOAD_PATH for your application automatically (presumably injected into the shell by nix).
Moreover, only the specified dependencies appear in $LOAD_PATH for any given package. One could even depend on different versions of the same library in the same interpreter session (assuming, again, no namespace pollution).
This idea would mean redoing gems, especially those that try to do their own version management (i.e., nokogiri), but I'd wager a good portion would be convertible with semi-automated systems. Besides that, the clean-break from rubygems means we get to do it right for a subset of packages.
Putting aside ruby, imagine what could be done for C and C++. Both have no real library manager right now. Same scheme: for new code that wants to build with nix as the lib manager, just specify library dependencies in the nix expression. In your own code, #include <libpng/png.h> and start coding/compiling in a nix-shell. The nix expression manages injecting the loaded dependencies into the include path and lib path for you. This is sort-of-like-but-better-than OS X frameworks in that if you have that bundle included in your dependency list you can start working with it with no further configuration. It's better because you get actual exact version pinning. In fact thinking of this idea as "invent a .framework clone and use Nix to manage dependencies" is not too far off base as a description.
Again this would be a clean break from existing tools, but arguably C/C++ need that clean break even more than ruby.
Because the development dependencies are so strict, we wouldn't even need configure scripts or automake anymore. Makefiles would only specify inter-file dependencies under this scheme, and not the miriad of platform-specific compiler option gunk. The nix expression would present build options and detect platform differences (like x86_64, arm or stdlib versions). The nix expression would furthermore eliminate the need for detecting compiler versions. If you want to use the latest bleeding-edge g++ for c++17 features go right ahead, the platform compiler will not be affected, and no one on your team will have to figure out how to juggle installing all of those compiler versions without breaking their other projects. Just means a longer initial build. Oh and getting rid of those ancient bespoke build tools means simpler dependency graphs for nix, leading to faster builds and more time on Hydra.
Under this model, getting started developing a source base would be vastly simplified. Just grab your project's nix expression, nix-shell, and run make or gcc and enjoy your successful build. You now have development binaries ready for testing and iterating, regardless of the prior state of your machine.
Posted Jan 5, 2015, 4:27 AM UTC
I know nothing about ruby, even less ruby on nix.
But the answer is that you can. If you have enough man power :) Gem is used because it's there already, knows the dependencies etc. and knows how to build a ruby project?
Also I think that such questions are more suited for the nix-dev mailing list, where you can find people that work on ruby packaging.