Repository navigation
feat(config): add exclude-newer - #7385
Merged
Merged
Conversation
7 tasks done
pavelzw
commented
Oct 28, 2026
pavelzw
marked this pull request as ready for review
October 28, 2026 01:55
Member
|
Shouldn't or couldn't this go to the rattler configuration so that we can use it in rattler-build as well? |
Collaborator
Author
|
yes you are right. was too late for me yesterday night i guess... |
5 tasks done
Collaborator
Author
pavelzw
force-pushed
the
default-exclude-newer
branch
2 times, most recently
from
October 28, 2026 14:26
4ddbda6 to
4335319
Compare
Hashing a missing cutoff as `false` changed the key of every backend environment and metadata cache entry, so upgrading would have rebuilt them once for every user, including those without `exclude-newer`. Hashing the discriminant writes the same bytes as `Option::hash` did.
lucascolley
force-pushed
the
default-exclude-newer
branch
from
October 28, 2026 14:58
4335319 to
fae97ce
Compare
`pixi init` on a `pyproject.toml` that already has a pixi table prints "Nothing to do here", but it still writes the configured `exclude-newer` into it, overwriting the workspace's own cutoff and making its lock file stale. This documents the problem where it happens, and adds a test that fails until it is fixed.
An invalid `exclude-newer` in the configuration only failed after `pixi init` had written the manifest. The workspace was left without a cutoff, and re-running `pixi init` failed because the manifest already existed. The value is now parsed before anything is written.
`pixi global` created an empty manifest before parsing the configured `exclude-newer`. If parsing failed, the empty manifest was left behind, and once the configuration was fixed it was treated as existing, so the cutoff never got written. The new manifest is now built in memory and only written once the value has been parsed.
Collaborator
Author
|
depends on prefix-dev/rattler-build#2914 |
Member
|
I found a few more things that we might want to change in rattler, so no rush on that release... nothing hugely blocking but seems like we would still have some workarounds on the Pixi side |
A configured exemption that combines a package archive `url` with fields such as `version` is accepted by `rattler_config`, but pixi's manifest rejects it, so `pixi init` and `pixi global` write a manifest that doesn't parse. Rejecting it belongs in `rattler_config`, where it would apply whenever the configuration loads, rather than in pixi's conversion only.
`pixi config unset` falls back to an empty configuration when the file doesn't load, so it can remove an invalid value. For a key inside `exclude-newer`, the empty value was then written back over the whole `exclude-newer`, silently dropping its cutoff and every other exemption. This is the very command the parse error suggests for repairing the file. When the file doesn't load, such a key is now removed from the document like any other key.
Unsetting a key inside `exclude-newer` that isn't there, such as an exemption of a package that isn't exempted, succeeded and printed "Updated config". It now fails like unsetting any other missing key.
The `exclude-newer` part of the name of a cached `pixi exec` environment was hashed with `DefaultHasher`, whose algorithm can change between Rust releases. A toolchain update could then rename every cached environment and solve again, picking up newer packages for a relative cutoff. The configured value is now hashed with xxh3 like the rest of the name.
`pixi init --script` ignored the `exclude-newer` of the configuration, although a script's workspace accepts one. A new PEP 723 or conda-script block now gets it under `[tool.pixi.workspace]`, like a new workspace does. The configuration is loaded from the script's directory, as when the script is run, and checked against the manifest before anything is written.
lucascolley
requested changes
Oct 30, 2026
The pinned rattler adds conda/rattler#3082 on top of the previous rev: `rattler_config` now rejects an exemption that combines a `url` with fields other than `md5` and `sha256`, so a configuration that pixi writes into a manifest as a url spec can no longer lose fields.
`pixi config set/unset exclude-newer.*` wrote back the whole value, dropping the comments and layout inside it, e.g. turning a `[exclude-newer.exemptions]` table into an inline table. Only the edited key is now written, with `write_exclude_newer_edit` of `rattler_config`. An exemption keeps its name as written in the file when it is edited under a differently cased name.
The pinned rattler moves to bf11b568b3 of conda/rattler#3082, which does the whole `exclude-newer` edit in `set_exclude_newer` and `set_exclude_newer_in_document`. That replaces the throwaway `ConfigBase` in `Config::set` and the before/after comparison in `pixi config`, and nothing is written when an edit changes nothing. Removing the last exemption now keeps a `[exclude-newer]` table and its comments, which the layout test covers. A `url` exemption with other fields fails with rattler's shorter message. The branch is based on a newer rattler release, so `rattler_cache`, `rattler_config`, `rattler_repodata_gateway` and `rattler_virtual_package_detectors` move to their next versions, along with the `rattler_build_*` crates that require them.
`rattler_config` accepts an exclude-newer exemption such as
`{ url = "…/libbaz-1-0.conda", flags = [] }`, as empty `flags` and
`track-features` select nothing. `pixi init`, `pixi global` and
`pixi init --script` write the configured exemption as written, so the
new manifest failed to parse with "`flags` cannot be used with `url`".
pixi now ignores empty `flags` and `track-features` next to an archive
too, rather than rattler rejecting them.
`rattler_config` writes the source of an invalid value into its own message and also reports it as the source, so `pixi config set` and `pixi config unset` of an `exclude-newer` key printed the reason twice. pixi now keeps only the source, under its own message.
`pixi workspace exclude-newer unexempt` and its `pixi global` counterpart turned a `[exclude-newer]` table without exemptions into a bare cutoff, dropping the comments in and above it. Only an inline table is now collapsed, like `rattler_config` does for `pixi config unset`.
The rattler crates come from their release in conda/rattler#3084, which includes conda/rattler#3082 and conda/rattler#3085, instead of a git revision. The `rattler_build_*` crates on crates.io require `rattler_config` 0.11, so they come from prefix-dev/rattler-build#2920 until it is released.
exclude-newer
rattler_build_core 0.2.24 builds with rattler_config 0.12, so the git patch on prefix-dev/rattler-build#2920 can go.
lucascolley
approved these changes
Nov 2, 2026
lucascolley
left a comment
Member
There was a problem hiding this comment.
thank you for working through this, Pavel!
lucascolley
enabled stacked auto-merge (squash)
November 2, 2026 16:52
stacked auto-merge was automatically disabled
November 2, 2026 17:10
Auto-merge was disabled for another pull request in the stack
# Conflicts: # crates/pixi_manifest/src/exclude_newer.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Stacked on #7384.
Fixes #5810.
Adds
exclude-newerto the pixi configuration, with the same shape asexclude-newerin a manifest:As settled in #5810, it is the starting point for new manifests and for
pixi exec, and never applies implicitly to an existing workspace, so a lock file doesn't depend on the configuration of whoever runs pixi:pixi initwrites it into theexclude-newerof the new workspace (pixi.toml,pyproject.tomland from an environment file). The cutoff is written as configured, e.g.7d.pixi globalwrites it into theexclude-newerof a new, empty global manifest. A global manifest created from an existing installation doesn't get it, as those environments were installed without a cutoff.pixi execsolves its environments with it. The cached exec environment is keyed by the configured value (a relative cutoff stays7d, like in fix: reuse the build backend environment with a relative exclude-newer #7384), and only when it is set, so existing exec environments keep their names.The key is part of the configuration shared by all rattler-based tools (conda/rattler#3020), so it can also be set in a
rattlerconfig file and rattler-build can use it as well.rattler_configkeeps the cutoff and exemptions as written; pixi parses them with the manifest's ownexclude-newerparser via the newExcludeNewerConfig::from_toml_value, so they have the same syntax and errors.Note
The rattler crates point to the commit of conda/rattler#3020 on a fork for now. This will be replaced with the released version of
rattler_configbefore merging.pixi config set exclude-newer 7dsets a cutoff, and a table is given as JSON like the other complex config values.Per-channel cutoffs for
default-channels(the other idea in #5810) are not part of this, asdefault-channelsonly takes channel names.How Has This Been Tested?
pixi config set/unset.pixi initwrites the configured cutoff and exemptions;pixi execfails with a cutoff before every package of the test channel and succeeds once the package is exempted;pixi global installwrites the default into the new global manifest and applies the cutoff to packages that are not exempted.AI Disclosure
Tools: Claude Code
Checklist:
schema/model.py.