Skip to content

Commit 3878dc1

Browse files
fix: channel order was not what got this fork's package, a version pin is
The install line documented one commit ago still fetched upstream's build, and the reasoning I committed beside it was wrong. `d66e4a4` claimed pixi resolves with strict channel priority, so the first channel carrying a package wins and the version is never consulted. That claim came from one observation: with both channels at 0.37.0, reordering them did change which package the solve chose. It changed because the reorder broke a version *tie*, which is not the same thing at all. Pixi's default resolves the highest version across every channel, and once upstream's channel reached 0.40.0 the documented line fetched `prefix.dev/blooop/linux-64/devlaunch-0.40.0` again, order notwithstanding. Three arrangements were solved rather than argued about: - a plain range with this fork's channel first: upstream's 0.40.0 - `channel-priority = "strict"` with a plain `[dependencies]` entry: this fork's - an exact `==` pin: this fork's `pixi global install` has no `--channel-priority` flag, so a one-liner can only express this as a version. The documented command carries one, and `test_the_install_line_pins_the_version_that_ships` diffs it against `rust/Cargo.toml` so it cannot go stale silently. Asserted by watching it fail against the unpinned line first. The channel order stays. It costs nothing, and it is what decides a genuine tie. The docstring that explained it now says what actually holds and records the wrong version of the rule, because the wrong version is the plausible one: the words "strict channel priority" appear in pixi's own documentation and it is easy to conclude the default behaves that way. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdSFnBdxie6TosHVmjLY28
1 parent d66e4a4 commit 3878dc1

2 files changed

Lines changed: 48 additions & 20 deletions

File tree

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ one argument instead of a clone, a config file and a build command.
3434
## Quickstart
3535

3636
```bash
37-
pixi global install --channel https://prefix.dev/jsmithrobotics/jsmithrobotics --channel https://prefix.dev/blooop --channel conda-forge devlaunch
37+
pixi global install --channel https://prefix.dev/jsmithrobotics/jsmithrobotics --channel https://prefix.dev/blooop --channel conda-forge devlaunch=0.37.0+fork.1
3838
```
3939

4040
### 1. Name a repo, land in a shell inside it
@@ -105,7 +105,7 @@ Workspaces pile up. A verb with no workspace opens the same selector, TAB marks
105105
### pixi (recommended)
106106

107107
```bash
108-
pixi global install --channel https://prefix.dev/jsmithrobotics/jsmithrobotics --channel https://prefix.dev/blooop --channel conda-forge devlaunch
108+
pixi global install --channel https://prefix.dev/jsmithrobotics/jsmithrobotics --channel https://prefix.dev/blooop --channel conda-forge devlaunch=0.37.0+fork.1
109109
```
110110

111111
That brings `devpod` and everything else along with it.

‎test/test_conda_source_repo.py‎

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -194,24 +194,35 @@ def test_the_recipe_default_agrees_with_cargo_tomls_repository(self):
194194
class TestTheDocumentedInstallGetsThisForksPackage:
195195
"""The publish side being right does not make the consume side right.
196196
197-
Pixi resolves with strict channel priority: the first channel in the list
198-
that carries a package wins, and the version is not consulted. Upstream's
199-
channel carries `devlaunch` too, at the same build string
200-
(`h8eb5a96_0` -- the recipe hash is unchanged by who builds it), so an
201-
install line naming upstream's channel before this fork's silently installs
202-
upstream's build. It resolves, it runs, and `pixi list` prints the version
203-
without the `+fork.1` segment, so nothing about the result announces which
204-
package arrived.
205-
206-
Measured rather than reasoned about: solving the previous form of this line
207-
produced
208-
`https://prefix.dev/blooop/linux-64/devlaunch-0.37.0-h8eb5a96_0.conda`,
209-
and solving this one produces
210-
`.../jsmithrobotics/jsmithrobotics/linux-64/devlaunch-0.37.0+fork.1-...`.
211-
212-
Upstream's channel cannot simply be dropped: the package's one run
213-
dependency is `devpod >=0.26.1` and devpod is not on conda-forge at all, so
214-
the line needs both channels and needs them in this order.
197+
Upstream's channel carries `devlaunch` too, so an install line naming both
198+
channels can resolve to upstream's build. It resolves, it runs, and `pixi
199+
list` prints the version with the `+fork.1` segment dropped, so nothing
200+
about the result announces which package arrived. The build string is
201+
identical either way (`h8eb5a96_0`: the recipe hash does not depend on who
202+
builds it).
203+
204+
**What protects against it is the version pin, not the channel order.**
205+
That correction is worth recording because the order was believed to be the
206+
protection for one commit: with both channels at 0.37.0, reordering them
207+
did change which package was resolved, and that single observation was
208+
generalised into "pixi uses strict channel priority, so the first channel
209+
wins and the version is never consulted". That is not pixi's default here.
210+
The reorder worked only because it broke a version *tie*. Once upstream's
211+
channel reached 0.40.0, the higher version won from the lower-priority
212+
channel and the install line silently fetched upstream again, order
213+
notwithstanding.
214+
215+
Measured three ways: `channel-priority = "strict"` in a workspace manifest
216+
does hold this fork's channel, and so does an exact `==` pin, while the
217+
default with a plain range resolves
218+
`https://prefix.dev/blooop/linux-64/devlaunch-0.40.0-h8eb5a96_0.conda`.
219+
`pixi global install` has no `--channel-priority` flag, so a one-liner can
220+
only say this with a version, which is why the documented command carries
221+
one.
222+
223+
The order is kept anyway: it costs nothing and it is what decides a genuine
224+
tie. Upstream's channel cannot be dropped, because the package's one run
225+
dependency is `devpod >=0.26.1` and devpod is not on conda-forge at all.
215226
"""
216227

217228
FORK_CHANNEL = "https://prefix.dev/jsmithrobotics/jsmithrobotics"
@@ -248,3 +259,20 @@ def test_the_forks_channel_is_the_namespaced_url(self):
248259
assert "prefix.dev/jsmithrobotics/jsmithrobotics" in line, (
249260
f"the single-segment channel URL does not resolve: {line!r}"
250261
)
262+
263+
def test_the_install_line_pins_the_version_that_ships(self):
264+
"""The pin is what actually gets this fork's package, so it has to be
265+
this fork's version. A stale pin documents an install of something the
266+
tree no longer is; a missing one documents an install of upstream's
267+
build, which is the defect this class exists for."""
268+
cargo = cargo_toml_text()
269+
version = next(
270+
line.split("=", 1)[1].strip().strip('"')
271+
for line in cargo.splitlines()
272+
if line.strip().startswith("version")
273+
)
274+
for line in self._install_lines():
275+
assert f"devlaunch={version}" in line, (
276+
f"install line does not pin devlaunch={version}, so it can resolve "
277+
f"upstream's higher-versioned build instead: {line!r}"
278+
)

0 commit comments

Comments
 (0)