Skip to content

feat(scaffold): honor per-target core-dependency overrides in the scripting bindings#164

Merged
Goldziher merged 2 commits into
xberg-io:mainfrom
tobocop2:feat/target-dep-overrides-scripting-backends
Jul 3, 2026
Merged

feat(scaffold): honor per-target core-dependency overrides in the scripting bindings#164
Goldziher merged 2 commits into
xberg-io:mainfrom
tobocop2:feat/target-dep-overrides-scripting-backends

Conversation

@tobocop2

@tobocop2 tobocop2 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #163.

What this changes

alef generates a Rust crate for each language binding and writes its Cargo.toml. You can tell alef to build the core crate with different features on a specific platform, via target_dep_overrides in alef.toml — but until now only the FFI, JNI, Dart, and Swift bindings honored it. The Python, Node, Ruby, PHP, and Elixir bindings ignored it and always wrote a single, platform-independent core dependency.

This makes those five bindings honor it too.

Before — a Python binding's Cargo.toml, override silently ignored:

[dependencies]
core-lib = { version = "1.0", path = "", features = ["full"] }

After — same binding, with an override configured for Intel macOS:

[target.'cfg(not(all(target_os = "macos", target_arch = "x86_64")))'.dependencies]
core-lib = { version = "1.0", path = "", features = ["full"] }

[target.'cfg(all(target_os = "macos", target_arch = "x86_64"))'.dependencies]
core-lib = { version = "1.0", path = "", features = ["macos-intel-target"] }

How

The FFI backend already does exactly this, so the change is a straight port, not new design:

  • moved the "split the core dependency into per-target sections" logic into a shared helper (render_core_dep_with_overrides);
  • added the target_dep_overrides option to the Python/Node/Ruby/PHP/Elixir configs (reusing the FFI backend's FfiTargetDepOverride, as JNI already does), which regenerates the JSON schema;
  • wired each of the five scaffolds to use the helper.

The override sets the features for the matched platform (same shape as FFI/JNI). The default_features = false variant that Dart/Swift also support is not included here — it can be a follow-up if needed.

Verification

cargo fmt --check and cargo check are clean. New tests cover the helper directly and assert that all five bindings emit the per-platform sections. The full library test run adds no failures: origin/main is 4181 passed / 14 failed, this branch is 4184 passed / 14 failed — the same 14 pre-existing, environment-sensitive test_scaffold_* failures (they read the real workspace Cargo.toml), plus the 3 new passing tests.

Follow-up commit ebcbaaa extends the new config field to the struct literals in the tests/ integration suites (backends_pyo3_gen_bindings/*, backends_napi_gen_bindings_test.rs), so --all-targets compiles cleanly — the Validate check is green as of that commit. The red Test / poly-validate checks reproduce identically on main (the 14 environment-sensitive failures above, and repo-wide poly fmt drift in files this PR doesn't touch).

Extend target_dep_overrides (previously ffi/jni/dart/swift only) to the
pyo3/napi/magnus/php/rustler backends, mirroring the FFI backend: when
overrides are set, the core dependency moves out of [dependencies] into a
cfg(not(...)) default block plus one [target.'cfg(<cfg>)'.dependencies] block
per override.

- shared render_core_dep_with_overrides helper in scaffold/mod.rs
- target_dep_overrides config field on Python/Node/Ruby/Php/Elixir (+ schema)
- wired all five scaffolds
- unit tests for the renderer + an all-five-backends integration test

Fixes xberg-io#163.
@tobocop2 tobocop2 force-pushed the feat/target-dep-overrides-scripting-backends branch from 020dda9 to f804399 Compare July 2, 2026 23:34
@tobocop2 tobocop2 marked this pull request as ready for review July 2, 2026 23:34
@tobocop2 tobocop2 requested a review from Goldziher as a code owner July 2, 2026 23:34
@tobocop2 tobocop2 changed the title feat(scaffold): target_dep_overrides for the scripting backends Honor per-target core-dependency overrides in the Python/Node/Ruby/PHP/Elixir bindings Jul 2, 2026
The new field was added to the src/scaffold/tests literals but the
integration tests under tests/ also construct PythonConfig/NodeConfig
as full struct literals; --all-targets compilation failed with E0063.
cargo check --all-targets, clippy (CI flags), and both affected test
binaries are green.
@tobocop2 tobocop2 changed the title Honor per-target core-dependency overrides in the Python/Node/Ruby/PHP/Elixir bindings feat(scaffold): honor per-target core-dependency overrides in the scripting bindings Jul 3, 2026
@Goldziher Goldziher merged commit 8d1f9f1 into xberg-io:main Jul 3, 2026
7 of 12 checks passed
Goldziher added a commit that referenced this pull request Jul 3, 2026
Two related issues introduced by feat(scaffold): emit canonical rustfmt.toml:

1. language_files() in scaffold/tests.rs did not filter rustfmt.toml.
   scaffold_poly() now emits [poly.toml, rustfmt.toml]; the helper already
   filtered poly.toml but not rustfmt.toml, so every language-specific
   file-count assertion was off by one.  Fix: add rustfmt.toml to the
   project-level file filter, mirroring the existing poly.toml exclusion.

2. crates/alpha/Cargo.toml fixture in sync_versions_patches_dep_tables_on_
   version_change lacked a src/lib.rs stub.  cargo update --workspace
   --offline (called via run_optional) printed "no targets specified in the
   manifest" to the test output on every run.  Fix: write an empty
   src/lib.rs alongside each member Cargo.toml so cargo's manifest
   validation is satisfied.

Fixes #164.
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.

Python/Node/Ruby/PHP/Elixir bindings ignore per-target core-dependency overrides

2 participants