I may have made mistakes in my research - please correct me if anything below is wrong or incomplete.
Background
rattler-build generate-recipe is the only R recipe generator in the conda ecosystem that works today, targets the v1 recipe.yaml format, and uses a reliable data source. The two alternatives have both effectively stalled:
Quoting the correction,
Yes, that's a misinterpretation. 99.9% of R packages are in CRAN so R packages in github is a niche problem. conda skeleton cran is still the best way to generate R recipes.
grayskull - active, unresolved CRAN bugs (#616, #615). AFAIK, it generates v0 meta.yaml by default; an extra conda-recipe-manager conversion step is required for v1 output. Scrapes CRAN DESCRIPTION files directly - fragile and CRAN-only. (#532)
conda_r_skeleton_helper (bgruening) - a post-processor only; calls conda skeleton cran internally and inherits all of its brokenness.
rattler-build generate-recipe already has the right foundations:
- Queries the R-universe JSON API - structured, reliable, and covers CRAN, Bioconductor, and GitHub-hosted R packages via
--universe. (cran.rs:build_cran_recipe_and_deps())
- Generates v1
recipe.yaml natively using ${{ }} Jinja syntax - the format conda-forge is migrating toward. (cran.rs:279-284)
- Detects compilation requirements via the
NeedsCompilation DESCRIPTION field and LinkingTo dependencies, and inserts C/C++ compilers automatically. (#2597)
- Adds
cross-r-base for cross-compilation support and sets rpaths for compiled packages. (#2597)
- Marks pure-R packages as
noarch: generic automatically. (#2597)
- References
r-base's bundled license texts via ${{ PREFIX }}/lib/R/share/licenses/ for standard SPDX licenses. (#2597)
- Correctly pins
r-base (with version constraint from Depends: R (>= x.y.z)) in both host and run. (#2597)
- Passes
${R_ARGS} to R CMD INSTALL, matching the conda-forge convention for build-time flag injection. (#2597)
- Written in Rust - fast, no subprocess calls, no arbitrary code execution.
- Python bindings exposed via
py-rattler-build (generate_cran_recipe(package, universe)). (recipe_generation.py:46)
Known gaps to address (As far as I could figure out - please correct me if I’m wrong or if there are others):
AFAICT, I have found no open issue currently tracks the following gaps.
Note: PR #2597 improved R recipe generation in several ways (cross-compilation, rpaths, noarch, license files, r-base pinning, R_ARGS) but did not address the two gaps below.
1. No conda-forge existence check for R dependencies
Impact: The generated recipe lists R dependencies by their CRAN name. If a dependency is not yet on conda-forge, the recipe will fail at solve time with no clear diagnostic.
Current behavior: cran.rs collects a remaining_deps HashSet for Imports, Depends, and LinkingTo packages but never uses it to check conda-forge availability - the set is silently dropped after dependency processing. The --tree flag only checks whether a local folder already exists, not whether the package is available on conda-forge.
Contrast with PyPI generator: pypi.rs fetches a live conda-forge name mapping from regro/cf-graph-countyfair at runtime (pypi.rs:225-228) and uses it to resolve PyPI -> conda-forge names. No equivalent exists for CRAN.
2. Suggests dependencies are commented out rather than conditionally handled
Impact: CRAN Suggests are optional test/example dependencies. The current output comments them out entirely (as # - r-foo # suggested inline in the run: block), losing structural information that downstream packagers or automated tools may need. A better default would be to emit them in a clearly marked optional section (e.g. under a run_constrained: block or a dedicated labelled comment block) so packagers know they exist and can make an informed choice.
Note: PR #2597 did not change this behavior - Suggests remain inline commented-out entries in the run: block.
TODO
Why invest here
rattler-build generate-recipe is the best option (AFAICT) for R recipe generator that is both working and targeting the right output format. The gaps above are bounded and well-understood. Closing them would make the tool production-ready for conda-forge R packaging workflows, without the dependency on conda skeleton or the CRAN scraper in grayskull.
I would re-iterate that I might have made incorrect claims. Please feel free to point out my incorrect claims. I would update the content of my issue as per the incoming feedback/comments. Thank you so much for reading till here. <3.
Background
rattler-build generate-recipeis the only R recipe generator in the conda ecosystem that works today, targets the v1recipe.yamlformat, and uses a reliable data source. The two alternatives have both effectively stalled:conda skeleton cran- broken in all recent conda-build releases; requires a downgrade to v3.27.0; users are being directed away from it; refer - Monitoring grayskull support for R package recipes bgruening/conda_r_skeleton_helper#58 and specifically, Monitoring grayskull support for R package recipes bgruening/conda_r_skeleton_helper#58 (comment). Also note the correction pointed out by @isuruf feat(generate-recipe): close remaining gaps in R recipe generation #2563 (comment),Quoting the correction,
grayskull- active, unresolved CRAN bugs (#616, #615). AFAIK, it generates v0meta.yamlby default; an extraconda-recipe-managerconversion step is required for v1 output. Scrapes CRAN DESCRIPTION files directly - fragile and CRAN-only. (#532)conda_r_skeleton_helper(bgruening) - a post-processor only; callsconda skeleton craninternally and inherits all of its brokenness.rattler-build generate-recipealready has the right foundations:--universe. (cran.rs:build_cran_recipe_and_deps())recipe.yamlnatively using${{ }}Jinja syntax - the format conda-forge is migrating toward. (cran.rs:279-284)NeedsCompilationDESCRIPTION field andLinkingTodependencies, and inserts C/C++ compilers automatically. (#2597)cross-r-basefor cross-compilation support and setsrpathsfor compiled packages. (#2597)noarch: genericautomatically. (#2597)r-base's bundled license texts via${{ PREFIX }}/lib/R/share/licenses/for standard SPDX licenses. (#2597)r-base(with version constraint fromDepends: R (>= x.y.z)) in bothhostandrun. (#2597)${R_ARGS}toR CMD INSTALL, matching the conda-forge convention for build-time flag injection. (#2597)py-rattler-build(generate_cran_recipe(package, universe)). (recipe_generation.py:46)Known gaps to address (As far as I could figure out - please correct me if I’m wrong or if there are others):
AFAICT, I have found no open issue currently tracks the following gaps.
1. No conda-forge existence check for R dependencies
Impact: The generated recipe lists R dependencies by their CRAN name. If a dependency is not yet on conda-forge, the recipe will fail at solve time with no clear diagnostic.
Current behavior:
cran.rscollects aremaining_depsHashSetforImports,Depends, andLinkingTopackages but never uses it to check conda-forge availability - the set is silently dropped after dependency processing. The--treeflag only checks whether a local folder already exists, not whether the package is available on conda-forge.Contrast with PyPI generator:
pypi.rsfetches a live conda-forge name mapping fromregro/cf-graph-countyfairat runtime (pypi.rs:225-228) and uses it to resolve PyPI -> conda-forge names. No equivalent exists for CRAN.2.
Suggestsdependencies are commented out rather than conditionally handledImpact: CRAN
Suggestsare optional test/example dependencies. The current output comments them out entirely (as# - r-foo # suggestedinline in therun:block), losing structural information that downstream packagers or automated tools may need. A better default would be to emit them in a clearly marked optional section (e.g. under arun_constrained:block or a dedicated labelled comment block) so packagers know they exist and can make an informed choice.TODO
pypi.rs. The mapping could be fetched fromcf-graph-countyfairat runtime or bundled. Warn (or skip) when a dependency has no conda-forge equivalent, rather than silently discarding it. - feat: warn about R dependencies missing from conda-forge in generated recipes #2622Suggestshandling - instead of commenting out suggested dependencies, emit them in a clearly distinguished section so downstream packagers have the full picture.skipcondition and platform-split script in generated R recipes #2609Why invest here
rattler-build generate-recipeis the best option (AFAICT) for R recipe generator that is both working and targeting the right output format. The gaps above are bounded and well-understood. Closing them would make the tool production-ready for conda-forge R packaging workflows, without the dependency onconda skeletonor the CRAN scraper ingrayskull.