@@ -40,7 +40,11 @@ trap 'rm -rf "$work"' EXIT
4040
4141# The store this run installs into, so "how many versions of X are here" is a
4242# question about THIS run and not about the machine.
43- XPKGS=" $HOME /.mcpp/registry/data/xpkgs"
43+ # `MCPP_HOME` first: the sandbox does not set it, so `$HOME/.mcpp` is right
44+ # there -- but a rehearsal on the host does set it, and reading the real home
45+ # instead answers "one version installed" from a registry this run never
46+ # touched. Measured: section D passed on the host for exactly that reason.
47+ XPKGS=" ${MCPP_HOME:- $HOME / .mcpp} /registry/data/xpkgs"
4448count_versions () { ls -1 " $XPKGS /xim-x-$1 " 2> /dev/null | wc -l | tr -d ' ' ; }
4549list_versions () { ls -1 " $XPKGS /xim-x-$1 " 2> /dev/null | sort | tr ' \n' ' ' ; }
4650
@@ -220,22 +224,78 @@ if [ -d "$work/c/target" ]; then
220224 tail -10 " $work /d/build.log"
221225 fi
222226
223- # ── E. a pin below the rule's floor is refused, naming both ─────────────
224- section " E. a pin below the rule's stated floor is refused"
225- mk_spirv_project " $work /e" '
226- [target.' " '" ' cfg(accelerator = "vulkan")' " '" ' .xlings.workspace]
227- "xim:glslang" = "1.0.0"
228- '
229- if ( cd " $work /e" && " $STORE " build > build.log 2>&1 ); then
230- fail " a pin below the rule's floor was accepted"
231- else
232- miss=" "
233- for needle in ' xim:glslang' ' 1.0.0' ' mcpp' ' drop the pin' ; do
234- grep -q -- " $needle " " $work /e/build.log" || miss=" $miss $needle "
235- done
236- if [ -z " $miss " ]; then ok " refused, naming both sides and the way out"
237- else fail " refused, but the message omits:$miss " ; fi
238- fi
227+ fi
228+
229+ # ── E. a pin below a stated floor is refused, naming both sides ─────────────
230+ #
231+ # NOT THROUGH A RULE PACKAGE, and the reason is worth recording: no published
232+ # rule states a floor that a published version can sit below. `rules-spirv`
233+ # requires `>=15.1.0` and 15.1.0 is the only glslang in the index; the same
234+ # holds for dpcpp and for the CANN toolkit. A fixture pinning `1.0.0` to get
235+ # under the floor is refused one step earlier, by provisioning, with
236+ # `not found in the synced index` -- the root's own pins are resolved before
237+ # the graph's constraints are known, so that refusal always wins. Measured:
238+ # the first draft of this section asserted the conflict message and read back
239+ # the provisioning one.
240+ #
241+ # So the construction is a local dependency and `xim:zoxide`, which publishes
242+ # three versions. What it verifies here rather than in the e2e suite is the
243+ # RELEASED binary.
244+ section " E. a pin below a stated floor is refused"
245+ mkdir -p " $work /e/dep/src" " $work /e/app/src"
246+ printf ' int dep_touch() { return 1; }\n' > " $work /e/dep/src/lib.cpp"
247+ cat > " $work /e/dep/mcpp.toml" << 'EOF '
248+ [package]
249+ name = "toolowner"
250+ version = "0.1.0"
251+ [modules]
252+ sources = ["src/**/*.cpp"]
253+ [xlings.workspace]
254+ "xim:zoxide" = ">=0.9.9"
255+ [targets.toolowner]
256+ kind = "lib"
257+ EOF
258+ printf ' int main(){return 0;}\n' > " $work /e/app/src/main.cpp"
259+ cat > " $work /e/app/mcpp.toml" << 'EOF '
260+ [package]
261+ name = "consumer"
262+ version = "0.1.0"
263+ [dependencies]
264+ toolowner = { path = "../dep" }
265+ [xlings.workspace]
266+ "xim:zoxide" = "0.9.7"
267+ [targets.consumer]
268+ kind = "bin"
269+ main = "src/main.cpp"
270+ EOF
271+ if ( cd " $work /e/app" && " $STORE " build > build.log 2>&1 ); then
272+ fail " a pin below a dependency's stated floor was accepted"
273+ else
274+ miss=" "
275+ for needle in ' xim:zoxide' ' 0.9.7' ' >=0.9.9' ' toolowner' ' drop the pin' ; do
276+ grep -q -- " $needle " " $work /e/app/build.log" || miss=" $miss $needle "
277+ done
278+ if [ -z " $miss " ]; then ok " refused, naming both sides and the way out"
279+ else fail " refused, but the message omits:$miss " ; fi
280+ fi
281+
282+ # …and raising it clears the refusal. Without this leg the section also passes
283+ # on an engine that refuses every project naming a tool its dependency names.
284+ sed ' s/"0.9.7"/"0.9.9"/' " $work /e/app/mcpp.toml" > " $work /e/app/mcpp.toml.new"
285+ mv " $work /e/app/mcpp.toml.new" " $work /e/app/mcpp.toml"
286+ rm -rf " $work /e/app/target"
287+ #
288+ # NO VERSION COUNT HERE. The refused leg above already installed 0.9.7: the
289+ # root's own pins are provisioned before the graph's constraints are known, so
290+ # a build that is about to be refused has already paid for what the project
291+ # asked for. Counting across both legs therefore reads two, and it is not the
292+ # defect this section is about -- section D owns "one package, one version",
293+ # on a store that only one build has touched.
294+ if ( cd " $work /e/app" && " $STORE " build > build2.log 2>&1 ); then
295+ ok " raising the pin to satisfy the floor builds"
296+ else
297+ fail " a pin that satisfies the floor was still refused"
298+ tail -10 " $work /e/app/build2.log"
239299fi
240300
241301# ── summary ────────────────────────────────────────────────────────────────
0 commit comments