Skip to content

Commit a46bd78

Browse files
committed
ci: 两个新断言步骤从来没跑过,而其中一个跑起来会误报
## 1. `$MCPP` 这个变量不存在 本 workflow 把构建出来的 mcpp 目录写进 `$GITHUB_PATH`,后续步骤直接叫 `mcpp`。 我新加的两个步骤自己发明了 `"$MCPP"`,展开成空 ⇒ 四个 job 全部 line 19: : command not found exit 127 ⚠️ 也就是说这两条断言**一次都没有真正执行过**。它是硬失败而不是静默跳过,所以被 逮住了 —— 但判据本身的「否」和「没测成」曾经同读数,这正是要避免的形状。 ## 2. 内部覆盖层的判据是**整文件 grep**,而提供者的行就在同一个文件里 `examples/cross-hello` 通过 `path = "../.."` 依赖本包,所以 openkal-musl **自己的** 编译行也在这份 compile_commands.json 里,并且**理应**带着 `musl/src/include` —— 那正是「私有,而不是没用」的意思。整文件 grep 分不开两者,会把本包自己的构建 判成泄漏。⇒ 改成按行取:jq 先按 `.file` 分出消费者行和提供者行。 ⚠️ 顺带归一化分隔符:Windows runner 写的是 `…\musl\src\include`,不归一化的判据 在那台机器上会**悄悄不再匹配**。 ⭐ 同一个键的另一半也补上:三个目录必须**出现在提供者的行里**。只断言「消费者没有」 的话,把这三个目录整个丢掉也一样绿。 ⭐ 双侧分母(consumer=N provider=M 打印出来),任一为 0 直接报「什么都没检查」。 实测(本地合成 CDB,两种分隔符各一行):正向 bad=0;把覆盖层塞进消费者行后 bad=1 并逐条打印。另:错误信息里的反引号在双引号串里是命令替换,已去掉。
1 parent 867fefe commit a46bd78

1 file changed

Lines changed: 31 additions & 10 deletions

File tree

.github/workflows/ci.yml

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ jobs:
251251
TOML
252252
sed -i 's/^ //' "$d/mcpp.toml"
253253
printf '#include <unistd.h>\n#include <stdio.h>\nint main(void){ printf("%%d\\n", isatty(1)); return 0; }\n' > "$d/src/main.c"
254-
( cd "$d" && "$MCPP" build --toolchain '${{ matrix.toolchain }}' )
254+
( cd "$d" && mcpp build --toolchain '${{ matrix.toolchain }}' )
255255
bin="$(find "$d/target" -name isattyprobe -type f | head -1)"
256256
test -n "$bin" || { echo "::error::the probe did not build"; exit 1; }
257257
@@ -291,26 +291,47 @@ jobs:
291291
run: |
292292
extra=''
293293
[ -n '${{ matrix.target }}' ] && extra='--target ${{ matrix.target }}'
294-
"$MCPP" build --toolchain '${{ matrix.toolchain }}' $extra
294+
mcpp build --toolchain '${{ matrix.toolchain }}' $extra
295295
test -s compile_commands.json \
296296
|| { echo "::error::no compile_commands.json — nothing to check"; exit 1; }
297297
298-
# ⚠️ A DENOMINATOR. With no consumer row the greps below are
299-
# vacuously true, which is the false green this check must not have.
300-
rows="$(grep -c '"file"' compile_commands.json || true)"
301-
[ "${rows:-0}" -ge 1 ] \
302-
|| { echo "::error::compile_commands.json has no rows"; exit 1; }
298+
# ⚠️⚠️ PER ROW, NOT OVER THE FILE. This example depends on the
299+
# package by path, so THE PROVIDER'S OWN ROWS ARE IN THIS SAME FILE
300+
# and they carry the overlay legitimately — that is what "private,
301+
# not unused" means. A `grep` over the whole file cannot tell the two
302+
# apart and would call the package's own build a leak.
303+
#
304+
# ⚠️ Separators are normalised because the Windows runner writes
305+
# `…\musl\src\include`, and a check that silently stops matching on
306+
# one platform is a check that platform does not have.
307+
norm='(.arguments // (.command | split(" "))) | join(" ") | gsub("\\\\"; "/")'
308+
jq -r ".[] | select((.file | gsub(\"\\\\\\\\\"; \"/\")) | test(\"examples/cross-hello\")) | $norm" \
309+
compile_commands.json > consumer.txt
310+
jq -r ".[] | select((.file | gsub(\"\\\\\\\\\"; \"/\")) | test(\"examples/cross-hello\") | not) | $norm" \
311+
compile_commands.json > provider.txt
312+
313+
# ⚠️ DENOMINATORS ON BOTH SIDES. With no consumer row every absence
314+
# below is vacuously true; with no provider row the control is.
315+
cons="$(wc -l < consumer.txt)"; prov="$(wc -l < provider.txt)"
316+
echo " rows: consumer=$cons provider=$prov"
317+
[ "$cons" -ge 1 ] && [ "$prov" -ge 1 ] \
318+
|| { echo "::error::consumer=$cons provider=$prov — nothing was checked"; exit 1; }
303319
304320
bad=0
305321
for d in musl/src/include musl/src/internal musl-generated/internal; do
306-
if grep -q -- "$d" compile_commands.json; then
322+
if grep -q -- "$d" consumer.txt; then
307323
echo "::error::the internal overlay '$d' reached a consumer"
308324
bad=1
309325
fi
326+
# The other half of the same key: private is not the same as
327+
# dropped. musl's own sources must still reach their declarations.
328+
grep -q -- "$d" provider.txt \
329+
|| { echo "::error::'$d' is on nobody's command line — private_include_dirs withheld it from this package too"
330+
bad=1; }
310331
done
311-
# The control: a PUBLIC directory must still be there, or this check
332+
# And something PUBLIC must still cross the boundary, or this check
312333
# would pass for a build that published nothing at all.
313-
grep -q -- 'port/include' compile_commands.json \
334+
grep -q -- 'port/include' consumer.txt \
314335
|| { echo "::error::no public include directory reached the consumer — the check above proves nothing"
315336
exit 1; }
316337
[ "$bad" = 0 ] || exit 1

0 commit comments

Comments
 (0)