Skip to content

feat: warn about R dependencies missing from conda-forge in generated recipes - #2622

Open
pb01ka wants to merge 3 commits into
prefix-dev:mainfrom
pb01ka:cf-check
Open

feat: warn about R dependencies missing from conda-forge in generated recipes#2622
pb01ka wants to merge 3 commits into
prefix-dev:mainfrom
pb01ka:cf-check

Conversation

@pb01ka

@pb01ka pb01ka commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Refer #2563

⚠️ Breaking: generate-recipe cran --tree now recurses only into dependencies missing from conda-forge by default, instead of the whole dependency tree. Pass the new --full flag alongside --tree to restore the old behavior.

Summary

cran.rs already collected an R package's dependencies into a remaining_deps set while generating a recipe, but the set was discarded after use - there was no signal to the user about which of those dependencies weren't yet packaged on conda-forge. The recipe would only fail much later, at solve time, with no clear diagnostic pointing back to the missing R package.

This PR checks each collected dependency against conda-forge right after the recipe is generated, and logs a warning for any that are missing. The check goes through rattler_repodata_gateway's Gateway, with every dependency batched into a single query rather than one request per package. This mirrors the existing behavior discussed for pypi.rs, minus the name-mapping step: CRAN package foo always maps to conda-forge r-foo by convention, so no lookup table is needed.

Important Points

@pb01ka
pb01ka marked this pull request as ready for review July 2, 2026 19:36
@pb01ka

pb01ka commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

This PR is ready for review. @wolfv Please feel free to take a look.

@isuruf You might be interested as well.

TY.

@isuruf

isuruf commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Should we also recurse specifically for the dependencies this PR flags as missing from conda-forge?

Yes, but not by default.

@pb01ka

pb01ka commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Noted. Will update this PR tomorrow using my best judgement.

@pb01ka

pb01ka commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Yes, but not by default.

Addressed using my best possible judgement. I have added a --recursive flag along side --tree flag. Once my changes are reviewed, I would like some thoughts on the following question I have in my mind.

Question: should --recursive just be folded into --tree?

Now that both flags exist side by side, I want to sanity-check the design. At a high level --recursive and --tree look very similar - both walk the dependency graph and generate recipes for what they find. The only real difference is which dependencies they recurse into:

  • --tree recurses into every dependency (am I right?), regardless of whether it's already on conda-forge.
  • --recursive recurses only into the dependencies that are missing from conda-forge.

Given how close they are on the surface, would you prefer we:

  1. Keep them as two separate flags (current state), or
  2. Merge them into one - e.g. drop --recursive and instead have --tree skip dependencies already available on conda-forge (or add a modifier to --tree that toggles that behavior)?

I'm happy either way; just want to avoid shipping two options that most users will find hard to tell apart (including me 😆).

@jsmolic

jsmolic commented Jul 21, 2026

Copy link
Copy Markdown
* `--tree` recurses into **every** dependency (**am I right?**), regardless of whether it's already on conda-forge.

I dont see this option in grayskull or conda-skeleton, only --recursive.

2. Merge them into one - e.g. drop `--recursive` and instead have `--tree` skip dependencies already available on conda-forge (or add a modifier to `--tree` that toggles that behavior)?

I think this makes most sense, having generated recipes for already available packages doesn't seem useful (especially given that boilerplate recipes may need further changes to be valid)

@pb01ka

pb01ka commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@jsmolic I used my best possible judgement to implement your suggestion,

  • --tree now by default recurses only into the dependencies that are missing from conda-forge.
  • --tree --full recurses into every dependency, regardless of whether it's already on conda-forge. (the older default behaviour of --tree)

The PR description is also updated to reflect the same. TY.

Please let me know if anything else needs to be done.

@pb01ka

pb01ka commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

@wolfv Kindly take a look. This PR is passing the tests and waiting for reviews/decision. TY.

/// Unlike PyPI, CRAN package names map to conda-forge by a fixed convention
/// (`foo` -> `r-foo`, see [`format_r_package`]), so no name-mapping lookup is
/// needed here, only an existence check via the anaconda.org API.
async fn conda_forge_package_exists(conda_name: &str) -> bool {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should use the Repodata Gateway here and query conda-forge that way. Is it possible for you to try that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I implemented the repodata gateway approach using my best judgement. Please take a look and let me know your feedback. TY.

@wolfv

wolfv commented Aug 7, 2026

Copy link
Copy Markdown
Member

Looks good except that one comment!

@pb01ka

pb01ka commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

@wolfv I addressed your comment to the best of my abilities and understanding. The tests are also passing. Please take a look. TY.

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.

4 participants