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

Fix canonical name for local channels in 1.x #3056

Merged
merged 7 commits into from
Dec 20, 2023

Conversation

isuruf
Copy link
Contributor

@isuruf isuruf commented Dec 11, 2023

Fixes #3055

@isuruf
Copy link
Contributor Author

isuruf commented Dec 11, 2023

cc @jaimergp

@jaimergp
Copy link
Contributor

This is one of those moments where one can only say "really?!". 😂 Thanks, I'll double check with conda-libmamba-solver later today!

@jaimergp
Copy link
Contributor

Hm, can we add a test? I have applied these changes locally but it doesn't seem to fix the local::spec problem with conda-libmamba-solver. See conda/conda-libmamba-solver#401 for reference.

@jaimergp
Copy link
Contributor

Ah, ok, it does work, but there's a gotcha compared to conda.

In conda, local refers to these paths:

                    for d in (
                        self._croot,
                        self.bld_path,
                        self.conda_build.get("root-dir"),
                        join(self.root_prefix, "conda-bld"),
                        "~/conda-bld",
                    )

So:

  • The value of bld_path in .condarc or CONDA_BLD_PATH env var
  • The value of conda_build.root-dir in .condarc
  • $CONDA_ROOT/conda-bld
  • ~/conda-bld

In mamba, it hardcodes this list:

  • $TARGET_PREFIX/conda-bld
  • $ROOT_PREFIX/conda-bld
  • ~/conda-bld

So, in order for conda to get a package from local, we need CONDA_BLD_PATH to be symlinked into those hardcoded locations.

I've tried redefining local via context.custom_multichannels, but I think we arrive too late. If I comment this block out, it does allow the custom (re)definition:

// Local channels
std::vector<std::string> local_channels = {
Context::instance().prefix_params.target_prefix.string() + "/conda-bld",
Context::instance().prefix_params.root_prefix.string() + "/conda-bld",
"~/conda-bld"
};
std::vector<std::string> local_names;
local_names.reserve(local_channels.size());
for (const auto& p : local_channels)
{
if (fs::is_directory(p))
{
std::string url = util::path_to_url(p);
auto channel = make_simple_channel(m_channel_alias, url, "", LOCAL_CHANNELS_NAME);
std::string name = channel.name();
auto res = m_custom_channels.emplace(std::move(name), std::move(channel));
local_names.push_back(res.first->first);
}
}
m_custom_multichannels.emplace(LOCAL_CHANNELS_NAME, std::move(local_names));

So I wonder if we can add a check to only instantiate the hardcoded local channels if context.custom_multichannels does not define local. WDYT @AntoinePrv @JohanMabille?

Btw, if that were to happen, I think we also need the same fix a few lines below, @isuruf. Just add url here in the same fashion:

auto channel = make_simple_channel(m_channel_alias, url, "", multichannelname);

@isuruf
Copy link
Contributor Author

isuruf commented Dec 12, 2023

custom_multichannels is not supposed override local though according to the docs at https://docs.conda.io/projects/conda/en/latest/configuration.html

@jaimergp
Copy link
Contributor

jaimergp commented Dec 12, 2023

We could only allow that via the API, not the user configuration. e.g. mamba has this check:

if el not in ["defaults", "local"]:

(I'm not sure where micromamba would define that behavior).

After all, I just want to inject the customizable conda's local into libmamba's hardcoded local.

Maybe it's a matter of adding the conda_build_root stuff to context too, but that feels like a bigger lift for an arguably niche feature (I hope very few folks are defining custom_multichannels to begin with, and even fewer trying to redefine local).

We could also use a secret key name if that's preferred, like _local_override or something.

@AntoinePrv
Copy link
Member

AntoinePrv commented Dec 15, 2023

@jaimergp I'm happy to add any hooks that will let you add what you need (a private private_conda_bld_paths in Context ?). In 2.0 the behavior is totally flexible from an API standpoint: local is a custom_multichannel that must be configured by the developer.

@jaimergp
Copy link
Contributor

(a private private_conda_bld_paths in Context ?)

That would be awesome @AntoinePrv! Whatever's easier from your point of view.

@isuruf isuruf force-pushed the canonical branch 3 times, most recently from 0d079dc to 6c85fc4 Compare December 18, 2023 06:40
Comment on lines +378 to +380
return { prefix_params.target_prefix.string() + "/conda-bld",
prefix_params.root_prefix.string() + "/conda-bld",
"~/conda-bld" };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here target_prefix is used and therefore we can't initialize the variable in the Context creation time and therefore we need to use a getter function here.

@@ -543,6 +543,11 @@ PYBIND11_MODULE(bindings, m)
.def_readwrite("custom_channels", &Context::custom_channels)
.def_readwrite("custom_multichannels", &Context::custom_multichannels)
.def_readwrite("default_channels", &Context::default_channels)
.def_property(
"conda_build_local_paths",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using conda_build_local_paths because conda has a read only property with the same name.

@isuruf
Copy link
Contributor Author

isuruf commented Dec 20, 2023

This is ready for a review.

@JohanMabille
Copy link
Member

Thanks @isuruf for this fix! The failure on Windows is unrelated to this change, see #3064

@JohanMabille
Copy link
Member

JohanMabille commented Dec 20, 2023

@jaimergp if the setter set_conda_build_local_paths, is enough for your need, I can merge this and release a 1.5.6 today.

@jaimergp
Copy link
Contributor

Thanks @JohanMabille, that would be awesome! Let me run a quick test locally to make sure this works with conda-libmamba-solver and I'll give you the thumbs up!

@jaimergp
Copy link
Contributor

Ok, conda/conda-libmamba-solver#401 passes locally with this branch so we have a beautiful green! @JohanMabille, you may proceed. Thanks to @isuruf too!

@JohanMabille JohanMabille merged commit e2de9db into mamba-org:1.x Dec 20, 2023
16 of 17 checks passed
{
if (conda_build_local_paths.empty())
{
return { prefix_params.target_prefix.string() + "/conda-bld",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if it has been intentional, but this differs from what conda.base.context.conda_build_local_paths would have:
https://github.com/conda/conda/blob/23.11.0/conda/base/context.py#L505-L523

  1. This adds non-existent folders whereas conda only adds existing ones.
  2. bld_path config value (and as such ${CONDA_BLD_PATH}) is not used.
  3. ${CONDA_PREFIX}/conda-bld is added whereas conda would never add this
    (unless it's the root prefix which always considered).
  4. conda_build: root-dir config values is not used.

TBH, I didn't even know that conda_build: root-dir existed -- and also not that conda-build uses that config entry but not bld_path (it only checks the environment variable):
https://github.com/conda/conda-build/blob/3.28.2/conda_build/config.py#L467-L468


So, yeah, the behavior in conda/conda-build is a bit convoluted..
But at least the ${CONDA_PREFIX}/conda-bld addition and ${CONDA_BLD_PATH} omission here seem rather unexpected to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This keeps the existing paths in mamba with the option to change this from the API. In conda-libmamba-solver, we set these values from conda's context, so they will be optional. So, if mamba is used from conda-libmamba-solver, the behaviour will be the same. I agree that it differs when using mamba directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, didn't see @jaimergp's comment in #3056 (comment) which iterates the same points.
So, why do we want different behaviors between the two implementations?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This keeps the existing paths in mamba with the option to change this from the API. In conda-libmamba-solver, we set these values from conda's context, so they will be optional. So, if mamba is used from conda-libmamba-solver, the behaviour will be the same. I agree that it differs when using mamba directly.

I'd consider this behavior a bug in Mamba and not worth preserving...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess in case we assume that we only use this via conda-libmamba-solver with the value overridden, then it's probably just a thing to change for the 2.x versions in main.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added #3124 to track this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants