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

Ensure that channels match expected value in conda-build #365

Merged
merged 28 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
be6bbc7
add reproducer test
jaimergp Nov 8, 2023
615ebd6
move test
jaimergp Nov 8, 2023
00a3f78
use canonical channel name when available
jaimergp Nov 8, 2023
1e0f373
pre-commit
jaimergp Nov 8, 2023
45dea9e
add news
jaimergp Nov 8, 2023
487fa6b
only for conda-build
jaimergp Nov 8, 2023
c436dbd
parametrize recipes
jaimergp Nov 8, 2023
d95a0e1
try with just the string
jaimergp Nov 9, 2023
45658cd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 9, 2023
5fe3b41
Merge branch 'main' into fix-363
jaimergp Nov 9, 2023
e299c0b
fix merge artifact
jaimergp Nov 9, 2023
336646b
use the full channel, not just the name
jaimergp Nov 9, 2023
b188daa
pre-commit
jaimergp Nov 9, 2023
1653234
detect whether channel belongs to multichannel via url
jaimergp Nov 9, 2023
cb328b1
Merge branch 'main' into fix-363
jaimergp Nov 11, 2023
44a6b49
use separate CONDA_BLD_PATH dirs
jaimergp Nov 11, 2023
74b26aa
Merge branch 'fix-363' of github.com:conda/conda-libmamba-solver into…
jaimergp Nov 11, 2023
9c6773e
only the channels test needs to be isolated
jaimergp Nov 12, 2023
cbef76c
cache this called_from_conda_build call a bit
jaimergp Nov 12, 2023
8d9d6c0
make sure we clear the repo before reloading it
jaimergp Nov 12, 2023
cf3f2c8
try shorter env path on windows
jaimergp Nov 13, 2023
9aaa8b4
use restricted unicode on windows
jaimergp Nov 13, 2023
f7bda4a
pre-commit
jaimergp Nov 13, 2023
1da19fe
unicode restrictions on this test only
jaimergp Nov 13, 2023
cee4693
extend stackvana example
jaimergp Nov 13, 2023
093b3e0
pre-commit [ci skip]
jaimergp Nov 13, 2023
a576cfb
retrigger
jaimergp Nov 13, 2023
1bfe170
Merge branch 'main' into fix-363
jaimergp Nov 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions conda_libmamba_solver/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
SpecsConfigurationConflictError,
UnsatisfiableError,
)
from conda.models.channel import Channel
from conda.models.channel import Channel, MultiChannel
from conda.models.match_spec import MatchSpec
from conda.models.records import PackageRecord, PrefixRecord
from conda.models.version import VersionOrder
Expand Down Expand Up @@ -160,7 +160,6 @@ def solve_final_state(
# From now on we _do_ require a solver and the index
init_api_context()
subdirs = self.subdirs
conda_bld_channels = ()
if self._called_from_conda_build():
log.info("Using solver via 'conda.plan.install_actions' (probably conda build)")
# Problem: Conda build generates a custom index which happens to "forget" about
Expand All @@ -179,6 +178,7 @@ def solve_final_state(
IndexHelper = _CachedLibMambaIndexHelper
else:
IndexHelper = LibMambaIndexHelper
conda_bld_channels = ()

all_channels = [
*conda_bld_channels,
Expand Down Expand Up @@ -844,7 +844,8 @@ def _export_solved_records(
# Fixes conda-build tests/test_api_build.py::test_croot_with_spaces
if on_win and self._called_from_conda_build():
for record in out_state.records.values():
record.channel.location = percent_decode(record.channel.location)
if record.channel.location: # multichannels like 'defaults' have no location
record.channel.location = percent_decode(record.channel.location)
record.channel.name = percent_decode(record.channel.name)

def _package_record_from_json_payload(
Expand Down Expand Up @@ -880,7 +881,13 @@ def _package_record_from_json_payload(

# Otherwise, these are records from the index
kwargs["fn"] = pkg_filename
kwargs["channel"] = channel_info.channel
cname = channel_info.channel.canonical_name
if self._called_from_conda_build() and cname in context.custom_multichannels:
# conda-build expects multichannel instances in the Dist->PackageRecord mapping
# see https://github.com/conda/conda-libmamba-solver/issues/363
kwargs["channel"] = cname
else:
kwargs["channel"] = channel
kwargs["url"] = join_url(channel_info.full_url, pkg_filename)
if not kwargs.get("subdir"): # missing in old channels
kwargs["subdir"] = channel_info.channel.subdir
Expand Down
19 changes: 19 additions & 0 deletions news/365-canonical-channel-names
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Enhancements

* <news item>

### Bug fixes

* Use canonical channel names (if available) in exported `PackageRecord` objects. Fixes an issue with conda-build and custom multichannels. (#363 via #365)

### Deprecations

* <news item>

### Docs

* <news item>

### Other

* <news item>
40 changes: 36 additions & 4 deletions tests/test_channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from .channel_testing.helpers import create_with_channel
from .utils import conda_subprocess, write_env_config

DATA = Path(__file__).parent / "data"


def test_channel_matchspec():
stdout, *_ = conda_inprocess(
Expand Down Expand Up @@ -89,9 +91,19 @@ def test_channels_installed_unavailable():
assert retcode == 0


def _setup_channels_alias(prefix):
def _setup_conda_forge_as_defaults(prefix, force=False):
write_env_config(
prefix,
force=force,
channels=["defaults"],
default_channels=["conda-forge"],
)


def _setup_channels_alias(prefix, force=False):
write_env_config(
prefix,
force=force,
channels=["conda-forge", "defaults"],
channel_alias="https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud",
migrated_channel_aliases=["https://conda.anaconda.org"],
Expand All @@ -103,9 +115,10 @@ def _setup_channels_alias(prefix):
)


def _setup_channels_custom(prefix):
def _setup_channels_custom(prefix, force=False):
write_env_config(
prefix,
force=force,
channels=["conda-forge", "defaults"],
custom_channels={
"conda-forge": "https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud",
Expand Down Expand Up @@ -219,6 +232,25 @@ def test_encoding_file_paths(tmp_path: Path):
assert list((tmp_path / "env" / "conda-meta").glob("test-package-*.json"))


def test_conda_build_with_aliased_channels():
"https://github.com/conda/conda-libmamba-solver/issues/363"
condarc = Path.home() / ".condarc"
condarc_contents = condarc.read_text() if condarc.is_file() else None
try:
_setup_conda_forge_as_defaults(Path.home(), force=True)
conda_subprocess(
"build",
DATA / "conda_build_recipes" / "jedi",
"--channel=defaults",
capture_output=False,
)
finally:
if condarc_contents:
condarc.write_text(condarc_contents)
else:
condarc.unlink()


def test_http_server_auth_none(http_server_auth_none):
create_with_channel(http_server_auth_none)

Expand Down Expand Up @@ -247,12 +279,12 @@ def test_http_server_auth_token_in_defaults(http_server_auth_token):
)
reset_context()
conda_subprocess("info", capture_output=False)
conda_inprocess(
conda_subprocess(
"create",
"-p",
_get_temp_prefix(),
"--solver=libmamba",
"test-package",
no_capture=True,
)
finally:
if condarc_contents:
Expand Down
27 changes: 15 additions & 12 deletions tests/test_downstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,30 @@
DATA = Path(__file__).parent / "data"


def test_build_recipes():
@pytest.mark.parametrize(
"recipe",
[
pytest.param(x, id=x.name)
for x in sorted((DATA / "conda_build_recipes").iterdir())
if (x / "meta.yaml").is_file()
],
)
def test_build_recipe(recipe):
"""
Adapted from
https://github.com/mamba-org/boa/blob/3213180564/tests/test_mambabuild.py#L6

See /tests/data/conda_build_recipes/LICENSE for more details
"""
recipes_dir = DATA / "conda_build_recipes"

recipes = [str(x) for x in recipes_dir.iterdir() if x.is_dir()]
expected_fail_recipes = ["baddeps"]
env = os.environ.copy()
env["CONDA_SOLVER"] = "libmamba"
expected_fail_recipes = ["baddeps"]
for recipe in recipes:
recipe_name = Path(recipe).name
print(f"Running {recipe_name}")
if recipe_name in expected_fail_recipes:
with pytest.raises(CalledProcessError):
check_call(["conda-build", recipe], env=env)
else:
recipe_name = Path(recipe).name
if recipe_name in expected_fail_recipes:
with pytest.raises(CalledProcessError):
check_call(["conda-build", recipe], env=env)
else:
check_call(["conda-build", recipe], env=env)


def test_conda_lock(tmp_path):
Expand Down
Loading