feat: support arbitrary selector expressions in package targets#5717
feat: support arbitrary selector expressions in package targets#5717wolfv wants to merge 9 commits into
Conversation
Allow arbitrary selector expressions (e.g. "host_platform == build_platform") as target keys in the [package] section. These are passed through directly to rattler-build, enabling full control over conditional dependencies. Expression selectors are only valid in [package.target] and [package.build.target] sections. In workspace and feature sections, unknown platform strings still produce proper error messages. Closes #4625 https://claude.ai/code/session_013pXmuPTy8PtK6p6jrRKWJc
…form-translation-IVMqR # Conflicts: # crates/pixi_build_backend/src/specs_conversion.rs # crates/pixi_manifest/src/toml/package.rs
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expression selectors in [package.target] must now be wrapped in `if(<expression>)`, e.g. `[target."if(host_platform == 'linux-64')".build-dependencies]`, replacing the previous heuristic that auto-detected expressions by scanning for spaces or comparison operators. The stored Expression value is the bare inner expression; Display re-wraps with `if(...)` for round-tripping. Unknown keys that are neither a known platform/family nor wrapped in `if(...)` now produce a parse error instead of silently becoming an expression. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
baszalmstra
left a comment
There was a problem hiding this comment.
I vaguely remember that we have some places in the intermediate backend that try to evaluate selectors from a recipe. They simply parse the expression as a platform and error if that can happen. Im not sure if we really need those, can you check if Im correct?
| assertion_line: 980 | ||
| expression: "expect_parse_failure(r#\"\n [workspace]\n name = \"test\"\n channels = []\n platforms = ['linux-64']\n\n [target.\"host_platform == build_platform\".dependencies]\n foo = \"*\"\n \"#,)" | ||
| --- | ||
| × 'host_platform == build_platform' is not a known platform. Valid platforms are 'noarch', 'unknown', 'linux-32', 'linux-64', 'linux-aarch64', 'linux-armv6l', 'linux-armv7l', 'linux-loongarch64', |
There was a problem hiding this comment.
Maybe we can improve this error. If we see things like spaces, or anything not [a-z0-9-] that we add a hint with "did you mean if(...)"?
…form-translation-IVMqR # Conflicts: # crates/pixi_build_backend/src/specs_conversion.rs # crates/pixi_manifest/src/toml/package.rs
Add `ParseTargetSelectorError` that wraps `ParsePlatformError` and, when the offending string contains characters outside `[a-z0-9-]`, emits a miette `help:` section pointing at the required `if(...)` wrapper. Convert the relevant tests to inline snapshots so the new error rendering is locked in next to the code. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
I want to propose a different syntax: Instead of: # cross-compilation
[package.target."if(host_platform != build_platform)".build-dependencies]
# cross-compilation
[package.target."if(host_platform == 'linux-64')".build-dependencies]
# variant matching
[package.target."if(matches(python, '>=3.10'))".build-dependencies]We use: # cross-compilation
[package.build-dependencies."if(host_platform != build_platform)"]
# cross-compilation
[package.build-dependencies."if(host_platform == 'linux-64')"]
# variant matching
[package.build-dependencies."if(matches(python, '>=3.10'))"]This can easily work because |
|
I would be perfectly fine with the syntax. Question would be mostly if we should also keep the |
|
I would completely deprecate that. With a warning with how it should be written. |
|
That all sounds good to me! |
Description
This PR adds support for arbitrary selector expressions in the
[package.target]section of manifests. Expressions are written using anif(...)wrapper and are passed through directly to rattler-build for evaluation, enabling more complex conditional logic in package configurations.E.g. this should enable:
The
if(...)wrapper is required: bare expression strings without the wrapper are rejected as invalid platform names, so typos in platform names still fail loudly. Workspace[target.*]keys continue to accept platform/family names only.