The greatest blocker for using Nix or complex Python projects like Plone, I think, is the work needed to make all required Python-packages (usally very specific versions) available in nix expression. Also, in the most extreme, that would require every version for every package in PyPI in nixpkgs.
Announcing collective.recipe.nix
collective.recipe.nix is my try for generating nix expressions for arbitrary Python projects. It's an experimental buildout recipe, which re-uses zc.recipe.egg for figuring out all the required packages and their dependencies.
It's a work in process and contributions are welcome. For example, it requires a lot more configurability to be usable for more various use cases.
Known issues:
- Python packages may have circular dependencies (e.g. Zope2 requirements also depend on Zope2, and e.g. Products and plone -namespaces have circular dependencies every now and then). These are currently solved by just removing those dependencies, resulting in kind of broken individual nix packages, but still making them work as whole.
- Python packages may have external build dependencies (like python-ldap requiring openldap). Currently these are hardcoded into recipe (usually by mapping the package to existing nixpkgs derivation), but they should be made configurable.
- Currently the recipe only works with PyPI, because it has nice API for getting download URLs and MD5 checksums required by nix.
Example of usage
At first, bootstrap your environment by defining python with buildout in ./default.nix:
with import <nixpkgs> {}; {
myEnv = stdenv.mkDerivation {
name = "myEnv";
buildInputs = [
pythonPackages.readline
pythonPackages.buildout
];
shellHook = ''
export SSL_CERT_FILE=~/.nix-profile/etc/ca-bundle.crt
'';
};
}
And example ./buildout.cfg:
[buildout]
extends=https://dist.plone.org/release/4-latest/versions.cfg
parts=
plone
zest.releaser
develop=.
versions=versions
[instance]
recipe=plone.recipe.zope2instance
eggs=
Plone
plone.app.ldap
user=admin:admin
[plone]
recipe=collective.recipe.nix
eggs=
${instance:eggs}
plone.recipe.zope2instance
[zest.releaser]
recipe=collective.recipe.nix
eggs=zest.releaser
[versions]
zc.buildout=
setuptools=
Run the buildout:
$ nix-shell --run buildout
Now you should be able to run zest.releaser with:
$ nix-shell zest.releaser.nix --run fullrelease
And launching python with all Plone dependencies (after removing buildout created site.py to remove references from buildout installed eggs) with:
$ rm -f parts/instance/site.py parts/instance/site.pyc
$ nix-shell plone.nix --run python
And Plone could be started by entering the following lines into the interpreter:
importplone.recipe.zope2instance.ctl
plone.recipe.zope2instance.ctl.main(['-C','parts/instance/etc/zope.conf','fg'])