Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to define conda channels in plugins via tljh_extra_user_conda_channels #942

Merged
merged 11 commits into from
Sep 4, 2024
9 changes: 8 additions & 1 deletion integration-tests/plugins/simplest/tljh_simplest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@

@hookimpl
def tljh_extra_user_conda_packages():
return ["tqdm"]
# tqdm installs from the conda-forge channel (https://conda-forge.org/packages/)
# csvtk installs from the bioconda channel (https://bioconda.github.io/conda-package_index.html)
return ["tqdm", "csvtk"]


@hookimpl
def tljh_extra_user_conda_channels():
return ["conda-forge", "bioconda"]


@hookimpl
Expand Down
11 changes: 11 additions & 0 deletions integration-tests/test_simplest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ def test_tljh_extra_hub_pip_packages():
subprocess.check_call([f"{HUB_ENV_PREFIX}/bin/python3", "-c", "import there"])


def test_conda_packages():
"""
Test extra user conda packages are installed from multiple channels.

- tqdm installs from the conda-forge channel (https://conda-forge.org/packages/)
- csvtk installs from the bioconda channel (https://bioconda.github.io/conda-package_index.html)
"""
subprocess.check_call([f"{USER_ENV_PREFIX}/bin/python3", "-c", "import tqdm"])
subprocess.check_call([f"{USER_ENV_PREFIX}/bin/csvtk", "cat", "--help"])


def test_tljh_extra_apt_packages():
assert os.path.exists("/usr/games/sl")

Expand Down
9 changes: 9 additions & 0 deletions tests/test_conda.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ def test_ensure_packages(prefix):
subprocess.check_call([os.path.join(prefix, "bin", "python"), "-c", "import numpy"])


def test_ensure_channel_packages(prefix):
"""
Test installing packages in conda environment
"""
conda.ensure_conda_packages(prefix, ["csvtk"], channels=("conda-forge", "bioconda"))
# Throws an error if this fails
subprocess.check_call([os.path.join(prefix, "bin", "csvtk"), "cat", "--help"])


def test_ensure_pip_packages(prefix):
"""
Test installing pip packages in conda environment
Expand Down
11 changes: 7 additions & 4 deletions tljh/conda.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,11 @@ def install_miniconda(installer_path, prefix):
fix_permissions(prefix)


def ensure_conda_packages(prefix, packages, force_reinstall=False):
def ensure_conda_packages(
prefix, packages, channels=("conda-forge",), force_reinstall=False
):
"""
Ensure packages (from conda-forge) are installed in the conda prefix.
Ensure packages (from channels) are installed in the conda prefix.

Note that conda seem to update dependencies by default, so there is probably
no need to have a update parameter exposed for this function.
Expand All @@ -118,13 +120,14 @@ def ensure_conda_packages(prefix, packages, force_reinstall=False):
# avoids problems with RemoveError upgrading conda from old versions
cmd += ["--force-reinstall"]

for channel in channels:
cmd += ["-c", channel]

abspath = os.path.abspath(prefix)

utils.run_subprocess(
cmd
+ [
"-c",
"conda-forge", # Make customizable if we ever need to
"--prefix",
abspath,
]
Expand Down
7 changes: 7 additions & 0 deletions tljh/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ def tljh_extra_user_conda_packages():
"""


@hookspec
def tljh_extra_user_conda_channels():
"""
Return a list of conda channels to be used during user environment installation.
"""


@hookspec
def tljh_extra_user_pip_packages():
"""
Expand Down
7 changes: 6 additions & 1 deletion tljh/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,13 +449,18 @@ def run_plugin_actions(plugin_manager):

# Install conda packages
conda_packages = list(set(itertools.chain(*hook.tljh_extra_user_conda_packages())))
conda_channels = list(itertools.chain(*hook.tljh_extra_user_conda_channels()))
if len(conda_channels) == 0:
conda_channels = ("conda-forge",)
if conda_packages:
logger.info(
"Installing {} user conda packages collected from plugins: {}".format(
len(conda_packages), " ".join(conda_packages)
)
)
conda.ensure_conda_packages(USER_ENV_PREFIX, conda_packages)
conda.ensure_conda_packages(
USER_ENV_PREFIX, conda_packages, channels=conda_channels
)

# Install pip packages
user_pip_packages = list(set(itertools.chain(*hook.tljh_extra_user_pip_packages())))
Expand Down