Skip to content

Conversation

@baszalmstra
Copy link
Contributor

@baszalmstra baszalmstra commented Nov 20, 2025

Description

Adds a pixi.platform variable to the MiniJinja task context, allowing users to reference the current platform in their task commands.

This is useful for creating platform-specific tasks without needing to define separate tasks for each platform:

[tasks]
build = { cmd = "cargo build --target {{ pixi.platform }}", args = [] }
download-binary = { cmd = "curl -O https://example.com/binary-{{ pixi.platform }}.tar.gz", args = [] }

The platform is accessed via the pixi namespace (pixi.platform) to avoid potential clashes with user-defined task arguments.

Closes #4940
Implementation details:

  • Introduced TaskRenderContext struct to manage rendering context (platform and args)
  • Uses environment.best_platform() to determine the platform, which respects environment-specific platform settings

Discussion
I suppose we want more useful variables in pixi. like is_win, os, or arch. I can add these if thats convenient?

How Has This Been Tested?

  • All existing 250 tests pass
  • Added unit tests in crates/pixi_manifest/src/task.rs:
    • test_template_string_renders_platform_variable - verifies platform renders correctly
    • test_template_string_renders_platform_with_args - verifies platform works alongside user arguments

AI Disclosure

  • This PR contains AI-generated content.
    • I have tested any AI-generated content in my PR.
    • I take responsibility for any AI-generated content in my PR.

Tools: Claude Code (Claude Sonnet 4.5)

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added sufficient tests to cover my changes.
  • I have verified that changes that would impact the JSON schema have been made in schema/model.py.

Add a `platform` variable to the MiniJinja context when rendering task
commands. This variable contains the best platform for the environment
in which the task will run (e.g., linux-64, osx-arm64, win-64).

This enables users to create platform-specific tasks without hardcoding
platform names:

```toml
[tasks]
build = { cmd = "cargo build --target {{ platform }}", args = [] }
download-binary = {
    cmd = "curl -O https://example.com/binary-{{ platform }}.tar.gz",
    args = []
}
```

The platform is automatically determined from the environment's
best_platform() method, which respects the environment configuration
and handles platform fallback (e.g., osx-64 on Apple Silicon when
osx-arm64 is not available).

Changes:
- Add platform parameter to TemplateString::render() and related methods
- Pass environment's best_platform() from ExecutableTask to render calls
- Add tests for platform variable rendering
- Update documentation with platform variable usage examples
Replace separate args and platform parameters with a unified
`TaskRenderContext` struct for passing rendering context. This makes
the API cleaner and more extensible for future system variables.

Key changes:
- `TaskRenderContext` now contains:
  - `platform: Platform` (non-optional, defaults to Platform::current())
  - `args: Option<&ArgValues>` (the task arguments)
- Add `with_args(platform, args)` constructor
- Create `pixi` object in Jinja context with system variables
- Access platform via `{{ pixi.platform }}` to avoid clashes with args
- Update all render methods to only take `&TaskRenderContext`

Usage example:
```rust
let context = TaskRenderContext::with_args(
    env.best_platform(),
    Some(&args)
);
task.as_single_command(&context)?;
```

Task template example:
```toml
[tasks]
build = { cmd = "cargo build --target {{ pixi.platform }}", args = [] }
```

This design allows easy addition of new system variables to the pixi
object without changing method signatures throughout the codebase.
Change platform variable access from {{ platform }} to {{ pixi.platform }}
to avoid potential clashes with user-defined task arguments. Also fixes
unused import warning and applies code formatting.
Update render_args and from_dependency methods to accept TaskRenderContext
instead of args directly, ensuring consistent platform handling throughout
the dependency rendering pipeline.
Extract MiniJinja context building into a dedicated method on
TaskRenderContext. The context now always includes pixi system
variables (like pixi.platform), even when no typed args are provided.
Update test code in pixi_core and pixi crates to use the new
TaskRenderContext API instead of passing None directly.
@ruben-arts
Copy link
Contributor

I like this, I would love to extend this with more variables. Here are some ideas:

pixi.environment # would equal to $PIXI_ENVIRONMENT_NAME

pixi.platform.is_win 
pixi.platform.is_unix
pixi.platform.is_linux
pixi.platform.is_osx

pixi.manifest-path # The absolute path to the manifest
pixi.version # The version of pixi

@tdejager
Copy link
Contributor

This seems like a really nice addition! <3

Add new system variables available in task templates under the pixi namespace:
- pixi.environment - The name of the current environment
- pixi.manifest-path - Absolute path to the manifest file
- pixi.version - The version of pixi
- pixi.is_win, pixi.is_unix, pixi.is_linux, pixi.is_osx - Platform detection booleans

Note: The platform detection booleans are accessible as pixi.is_win, etc.
rather than pixi.platform.is_win to avoid minijinja type complexity.

Updated TaskRenderContext to optionally include environment name and manifest path.
@baszalmstra
Copy link
Contributor Author

@ruben-arts I added those! Although I changed pixi.platform.is_win to pixi.is_win instead. Because otherwise pixi.platform wouldnt work. Let me know what you think!

Update the documentation to include all available pixi template variables
in a clear markdown table format. Added examples showing how to use:
- Platform detection booleans for conditional logic
- Environment-aware tasks
- Manifest path access with bracket notation
Change pixi.manifest-path to pixi.manifest_path to avoid issues with
dashes being interpreted as minus signs in MiniJinja. This is consistent
with the variable naming convention and avoids the need for bracket notation.
@baszalmstra
Copy link
Contributor Author

Instead of pixi.environment should we do pixi.current_environment maybe?

claude and others added 5 commits November 21, 2025 08:43
- Changed manifest_path from Option<&Path> to Option<PathBuf> to avoid lifetime issues
- Added render_context() method to ExecutableTask for consistent context construction
- Removed new() and with_args() methods, using struct initialization syntax instead
- Ensures environment name and manifest path are properly passed in all contexts
- All tests passing
…ject

- Changed manifest_path back to Option<&'a Path> to properly use lifetimes
- Made environment_name required (non-optional) with &'a EnvironmentName
- Changed pixi.environment to pixi.environment.name (environment is now an object)
- Updated TaskNode::full_command to accept &TaskRenderContext parameter
- Use TaskRenderContext::default() where appropriate with spread syntax
- Removed command rendering from TaskNode Display impl
- All tests passing
@ruben-arts ruben-arts marked this pull request as ready for review November 21, 2025 15:44
Copy link
Contributor

@ruben-arts ruben-arts left a comment

Choose a reason for hiding this comment

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

I think this is a great addition! Thanks @baszalmstra and claude'tje

@baszalmstra baszalmstra merged commit e8967b4 into prefix-dev:main Nov 25, 2025
42 checks passed
@bollwyvl
Copy link
Contributor

bollwyvl commented Dec 8, 2025

Neat! Opened #5078 to update the schema to reflect the new reserved name.

bollwyvl added a commit to bollwyvl/pixi that referenced this pull request Dec 9, 2025
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.

Resolve environment variable in task inputs/outputs

5 participants