pypa / hatch

Modern, extensible Python project management
https://hatch.pypa.io/latest/
MIT License
6.12k stars 310 forks source link

Custom dependency install / env variables for specific features in environments? #764

Open kratsg opened 1 year ago

kratsg commented 1 year ago

I'm ok if there is no solution for this (and I just need to do a bit of custom hacking in the meantime but) I have a private/internal python package which has a dependency on pycurl. This is interesting because there are situations where pycurl does not install out of the box correctly (and needs to have some other env variables set + force recompilation) to get things working.

For example, on Mac OSX, I have

$ export LDFLAGS="-L/usr/local/opt/openssl@3/lib"
$ export CPPFLAGS="-I/usr/local/opt/openssl@3/include"
$ python -m pip install --no-cache-dir --compile --ignore-installed --install-option="--with-openssl" pycurl

as instructions (assuming openssl is shipped with homebrew).

On a RedHat-like machine, those instructions might end up looking like

$ export LDFLAGS="-L/usr/local/lib/openssl"
$ export CPPFLAGS="-I/usr/local/include/openssl"
$ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig/
$ python -m pip install --no-cache-dir --compile --ignore-installed --install-option="--with-nss" pycurl

Notice the addition of PKG_CONFIG_PATH and the different --install-option here. Is there a way in hatch to specify this (optional) dependency correctly, so that

  1. it works for users to just pip install normally
  2. it works for hatch environments e.g. so that hatch run test also works (for isolated environments)

If the second is not possible, and one needs to use a non-isolated environment -- that's probably ok here. I would just like some guidance if possible.

jamesdow21 commented 1 year ago

Unsure about 1. but at least for 2. you should be able to use Defined Environment Variables and Pre-Install Commands to accomplish it.

You would run the pip install command as you described as a pre-install and then when hatch tries to install your project's requirements, it would see that pycurl is already satisfied

I would set that up in a template environment and then inherit all of your other environments from there

You may have to have a separate environment defined for each OS flavor you are trying to support, or write a shell script that handles the various if/elses and have the pre-install command run the shell script

kratsg commented 1 year ago

Thanks! I think [2] is satisfied for right now with

[tool.hatch.envs.dev.overrides]
platform.macos.set-env-vars = [
  "LDFLAGS=-L/usr/local/opt/openssl@3/lib",
  "CPPFLAGS=-I/usr/local/opt/openssl@3/include",
]
platform.macos.set-pre-install-commands = ["python -m pip install --no-cache-dir --compile --ignore-installed --install-option='--with-openssl' pycurl"]

since I'm currently the only developer and can live with this for now and extend later. [1] is going to be the interesting one.