This exact thing is what trips me up about using Nix and I haven't been able to figure out how to get around it. Sometimes you want a global Python library. Here's one example from my own use case: I want to use a Weechat Python script that depends on a Python library called "pync". With e.g. MacPorts I can just run
sudo port install py-pync
and now the Weechat Python script will be able to "import pync". But this doesn't work with Nix since every package is completely isolated from each other.
I spent quite a bit of time trying to figure this out and was unsuccessful. I'd love to know what Nix's answer to use cases like this is.
The (idiomatic) answer is based on the fact that your global environment doesn't need pync, weechat needs pync. Therefore, you override weechat's dependencies and inject the package into it's private environment like so: https://nixos.org/manual/nixpkgs/stable/#sec-weechat
But you don't want to install globally. One of major strengths (for me at least) is that when combined with nix-shell you have something like virtualenv, but for all packages, not just the ones from python.
This means that someone else who checks out your project can get the same environment you had for the development.
If this is combined with direnv, then you don't even need to invoke nix-shell you just enter the project directory and everything is there.
If you use something like poetry2nix[1] it will automatically have the dependencies your project has.
I do want to install globally, as outlined in my original comment. Unless you can tell me how to somehow modify the installation of Weechat to also include this one Python package.
I think Nix is a really cool concept and no doubt there are certain use cases that it solves really well. But my experience with it as a day to day package manager was that it just made simple things hard without a proportional benefit to make all the trouble worth it.
That Nix expression defines a package meaning 'just like Weechat, but with pync in the build paths'. There are examples with links to more docs on the unofficial NixOS wiki: https://nixos.wiki/wiki/Weechat
I understand that this may still feel like 'making a simple thing hard', but it does, I hope, answer your question. Modifying existing packages in just a few lines of code in order to include additional dependencies is very much part of Nix's paradigm. :)
There's a way you could write all that inline to install it with nix-env, too, but I can't be arsed.
Once you apply the override concept with Weechat, you'll have a feel for what is a very general suite of customization mechanisms in Nixpkgs. That'll be unlikely to miss a similar opportunity with other packages.
NixOS Discourse is a great place to clear stumbling blocks like these, by the way :)
> I do want to install globally, as outlined in my original comment. Unless you can tell me how to somehow modify the installation of Weechat to also include this one Python package.
The goal that Nix tries to solve, is to make all implicit dependencies explicit. The proper way of doing is to list these packages in the WeeChat.
> I think Nix is a really cool concept and no doubt there are certain use cases that it solves really well. But my experience with it as a day to day package manager was that it just made simple things hard without a proportional benefit to make all the trouble worth it.
Yes, it indeed it makes simple things hard, but then this approach makes hard things easy. Because every package in Nix repo have explicit dependencies it solves many other problems. You no longer have dll hell for example a project that uses nix to build, generally just builds without issues.
I use Nix for development and the great thing is that I can use it to describe all tooling that I need for development. So another person can replicate the same environment. I was able for example to write a custom modules to standardize dev environment. And if someone uses it I can easily use the same mechanism to produce:
- nix package
- wheel package (it is for Python project)
- package application into docker with just only the necessary pieces (can also slim python by only compiling features that are actually used)
When using nix for building, I can speed up the work, because Nix only rebuilds things when things change. For example in traditional pipeline when you work on dev branch when you merge branch it typically rebuilds the whole thing. Nix is smart, and tracks what actually changed. If no actual files changed the build will return immediately with the binary that was produced on the branch. If during the merge our branch was integrated with some other changes that happened in the master branch, Nix will know to rebuild it again. In addition to that, on average built time was cut in half for me.
I spent quite a bit of time trying to figure this out and was unsuccessful. I'd love to know what Nix's answer to use cases like this is.