fix: bug: generator emits invalid env var name FORGE_BOT_USER_<service>^^ when service name contains hyphen (#852)
Acceptance items 1-4 landed previously: the primary compose emission (FORGE_BOT_USER_*) was fixed in #849 by re-keying on forge_user via `tr 'a-z-' 'A-Z_'`, and the load-project.sh AGENT_* Python emitter was normalized via `.upper().replace('-', '_')` in #862. Together they produce `FORGE_BOT_USER_DEV_QWEN2` and `AGENT_DEV_QWEN2_BASE_URL` for `[agents.dev-qwen2]` with `forge_user = "dev-qwen2"`. This patch closes acceptance item 5 — the defence-in-depth warn-and-skip in load-project.sh's two export loops. Hire-agent's up-front reject is the primary line of defence (a validated `^[a-z]([a-z0-9]|-[a-z0-9])*$` agent name can't produce a bad identifier), but a hand-edited TOML can still smuggle invalid keys through: - `[mirrors] my-mirror = "…"` — the `MIRROR_<NAME>` emitter only upper-cases, so `MY-MIRROR` retains its dash and fails `export`. - `[agents."weird name"]` — quoted TOML keys bypass the bare-key grammar entirely, so spaces and other disallowed shell chars reach the export loop unchanged. Before this change, either case would abort load-project.sh under `set -euo pipefail` — the exact failure mode the original #852 crash-loop was diagnosed from. Now each loop validates `$_key` against `^[A-Za-z_][A-Za-z0-9_]*$` and warn-skips offenders so siblings still load. - `lib/load-project.sh` — regex guard + WARNING on stderr in both `_PROJECT_VARS` and `_AGENT_VARS` export loops. - `tests/lib-load-project.bats` — two regressions: dashed mirror key, quoted agent section with space. Both assert (a) the load does not abort and (b) sane siblings still load. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
46b3d96410
commit
564e89e445
2 changed files with 89 additions and 0 deletions
|
|
@ -184,3 +184,70 @@ EOF
|
|||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"invalid agent name"* ]]
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# #852 defence: the export loops must warn-and-skip invalid identifiers
|
||||
# rather than tank `set -euo pipefail`. Hire-agent's up-front reject
|
||||
# (tests above) is the primary line of defence, but a hand-edited TOML —
|
||||
# e.g. [mirrors] my-mirror = "…" or a quoted [agents."weird name"] — can
|
||||
# still produce invalid shell identifiers downstream. The guard keeps
|
||||
# the factory loading the rest of the file instead of crash-looping.
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@test "[mirrors] dashed key: warn-and-skip, does not crash under set -e" {
|
||||
cat > "$TOML" <<EOF
|
||||
name = "test"
|
||||
repo = "test-owner/test-repo"
|
||||
forge_url = "http://localhost:3000"
|
||||
|
||||
[mirrors]
|
||||
good = "https://example.com/good"
|
||||
bad-name = "https://example.com/bad"
|
||||
EOF
|
||||
|
||||
run bash -c "
|
||||
set -euo pipefail
|
||||
source '${ROOT}/lib/load-project.sh' '$TOML' 2>&1
|
||||
echo \"GOOD=\${MIRROR_GOOD:-MISSING}\"
|
||||
"
|
||||
|
||||
# Whole load did not abort under set -e.
|
||||
[ "$status" -eq 0 ]
|
||||
# The valid mirror still loads.
|
||||
[[ "$output" == *"GOOD=https://example.com/good"* ]]
|
||||
# The invalid one triggers a warning; load continues instead of crashing.
|
||||
[[ "$output" == *"skipping invalid shell identifier"* ]]
|
||||
[[ "$output" == *"MIRROR_BAD-NAME"* ]]
|
||||
}
|
||||
|
||||
@test "[agents.*] quoted section with space: warn-and-skip, does not crash" {
|
||||
# TOML permits quoted keys with arbitrary characters. A hand-edited
|
||||
# `[agents."weird name"]` would survive the Python .replace('-', '_')
|
||||
# (because it has no dash) but still contains a space, which would
|
||||
# yield AGENT_WEIRD NAME_BASE_URL — not a valid identifier.
|
||||
cat > "$TOML" <<'EOF'
|
||||
name = "test"
|
||||
repo = "test-owner/test-repo"
|
||||
forge_url = "http://localhost:3000"
|
||||
|
||||
[agents.llama]
|
||||
base_url = "http://10.10.10.1:8081"
|
||||
model = "qwen"
|
||||
|
||||
[agents."weird name"]
|
||||
base_url = "http://10.10.10.1:8082"
|
||||
model = "qwen-bad"
|
||||
EOF
|
||||
|
||||
run bash -c "
|
||||
set -euo pipefail
|
||||
source '${ROOT}/lib/load-project.sh' '$TOML' 2>&1
|
||||
echo \"LLAMA=\${AGENT_LLAMA_BASE_URL:-MISSING}\"
|
||||
"
|
||||
|
||||
# The sane sibling must still be loaded despite the malformed neighbour.
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"LLAMA=http://10.10.10.1:8081"* ]]
|
||||
# The invalid agent's identifier triggers a warning and is skipped.
|
||||
[[ "$output" == *"skipping invalid shell identifier"* ]]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue