Skip to content

feat: support arbitrary selector expressions in package targets#5717

Open
wolfv wants to merge 9 commits into
mainfrom
claude/implement-platform-translation-IVMqR
Open

feat: support arbitrary selector expressions in package targets#5717
wolfv wants to merge 9 commits into
mainfrom
claude/implement-platform-translation-IVMqR

Conversation

@wolfv

@wolfv wolfv commented Mar 17, 2026

Copy link
Copy Markdown
Member

Description

This PR adds support for arbitrary selector expressions in the [package.target] section of manifests. Expressions are written using an if(...) wrapper and are passed through directly to rattler-build for evaluation, enabling more complex conditional logic in package configurations.

E.g. this should enable:

# 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]

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.

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
@wolfv wolfv marked this pull request as draft March 17, 2026 18:43
@wolfv wolfv closed this Mar 17, 2026
wolfv and others added 2 commits May 20, 2026 14:27
…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>
@wolfv wolfv reopened this May 20, 2026
@wolfv wolfv changed the title Support arbitrary selector expressions in package targets feat: support arbitrary selector expressions in package targets May 20, 2026
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>
@wolfv wolfv requested a review from baszalmstra May 20, 2026 15:29
@wolfv wolfv marked this pull request as ready for review May 20, 2026 15:29
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@baszalmstra baszalmstra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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(...)"?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's quite improved now.

wolfv and others added 4 commits May 22, 2026 13:57
…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>
@baszalmstra

baszalmstra commented May 28, 2026

Copy link
Copy Markdown
Contributor

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 ( is not a valid character in a package, so we can easily distinguish this case. WDYT @Hofer-Julian @wolfv ?

@wolfv

wolfv commented May 28, 2026

Copy link
Copy Markdown
Member Author

I would be perfectly fine with the syntax. Question would be mostly if we should also keep the target.linux ... syntax or completely rip that out?

@baszalmstra

Copy link
Copy Markdown
Contributor

I would completely deprecate that. With a warning with how it should be written.

@Hofer-Julian

Copy link
Copy Markdown
Contributor

That all sounds good to me!

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