feat(kyberforge): execute the plugin→APM conversion #95

Merged
Defame1297 merged 49 commits from feat/90-execute-apm-conversion into main 2026-08-14 14:32:36 +00:00
2 changed files with 83 additions and 6 deletions
Showing only changes of commit a8beff7d2c - Show all commits

View File

@@ -29,4 +29,53 @@ if [[ ${#TEST_FILES[@]} -eq 0 ]]; then
exit 0
fi
"$BATS" "${TEST_FILES[@]}"
# Each file gets its own `bats` process, run concurrently (bounded by core
# count) instead of one `bats` invocation working through all files serially.
# A single test file is still serial internally -- this only overlaps the
# fixed per-process startup cost (git/apm subprocess spawns dominate several
# of these suites) across files, which is where the wall-clock actually goes.
# Output is buffered per file so concurrent TAP streams can't interleave, then
# flushed in stable sorted order once every job has finished.
SCRATCH_ROOT="$(mktemp -d)"
trap 'rm -rf "$SCRATCH_ROOT"' EXIT
# A failing test is the normal case a CI runner must handle, and a failing
# background job makes `wait`/`wait -n` return non-zero -- under `set -e` that
# would abort the script right here, before the per-file report below ever
# runs. Every wait in this dispatcher is therefore explicitly guarded.
JOBS="$(nproc 2>/dev/null || echo 4)"
running=0
i=0
for f in "${TEST_FILES[@]}"; do
i=$((i + 1))
( "$BATS" "$f" >"$SCRATCH_ROOT/$i.log" 2>&1; echo $? >"$SCRATCH_ROOT/$i.status" ) &
running=$((running + 1))
if [[ "$running" -ge "$JOBS" ]]; then
wait -n || true
running=$((running - 1))
fi
done
wait || true
FAIL=0
TOTAL_OK=0
TOTAL_NOT_OK=0
i=0
for f in "${TEST_FILES[@]}"; do
i=$((i + 1))
rel="${f#"$REPO_ROOT"/}"
echo "=== $rel ==="
cat "$SCRATCH_ROOT/$i.log"
echo ""
file_ok="$(grep -c '^ok ' "$SCRATCH_ROOT/$i.log" || true)"
file_not_ok="$(grep -c '^not ok ' "$SCRATCH_ROOT/$i.log" || true)"
status="$(cat "$SCRATCH_ROOT/$i.status" 2>/dev/null || echo 1)"
TOTAL_OK=$((TOTAL_OK + file_ok))
TOTAL_NOT_OK=$((TOTAL_NOT_OK + file_not_ok))
if [[ "$file_not_ok" -gt 0 || "$status" -ne 0 ]]; then
FAIL=1
fi
done
echo "$((TOTAL_OK + TOTAL_NOT_OK)) tests, $TOTAL_NOT_OK failures"
exit "$FAIL"

View File

@@ -49,14 +49,42 @@ done < <(
| sort
)
# bash before 4.4 treats "${arr[@]}" on an empty array as unbound under
# `set -u`, so every array expansion here uses the ${arr[@]+"${arr[@]}"} guard,
# including the SKIPPED/FAILED loops already fenced by a count check.
# Each test-*.sh is independent (fixtures live under its own mktemp dir, none
# write back into the live repo tree -- verified before adding this), so they
# run concurrently in fixed-size batches instead of one at a time. Batches
# (not a rolling pool) because a bounded rolling pool needs `wait -n`, which
# is bash 4.3+ and this script is explicitly bash-3.2-safe (see the hazard
# scan in test-vale-wrap.sh); plain `wait` -- waiting for every job in the
# current batch -- is available since ancient bash. `getconf` over `nproc`
# for the same reason: `nproc` doesn't exist on macOS.
SCRATCH_ROOT="$(mktemp -d)"
trap 'rm -rf "$SCRATCH_ROOT"' EXIT
JOBS_LIMIT="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 4)"
running=0
idx=0
for script in ${SCRIPTS[@]+"${SCRIPTS[@]}"}; do
idx=$((idx + 1))
(
rc=0
bash "$script" >"$SCRATCH_ROOT/$idx.log" 2>&1 || rc=$?
echo "$rc" >"$SCRATCH_ROOT/$idx.status"
) &
running=$((running + 1))
if [[ $running -ge $JOBS_LIMIT ]]; then
wait
running=0
fi
done
wait
idx=0
for script in ${SCRIPTS[@]+"${SCRIPTS[@]}"}; do
idx=$((idx + 1))
rel="${script#"$SEARCH_ROOT/"}"
echo "=== $rel ==="
rc=0
bash "$script" || rc=$?
cat "$SCRATCH_ROOT/$idx.log"
rc="$(cat "$SCRATCH_ROOT/$idx.status" 2>/dev/null || echo 1)"
if [[ $rc -eq 0 ]]; then
PASSED=$((PASSED + 1))
elif [[ $rc -eq $SKIP_EXIT ]]; then