Skip to content

test-pr-creation-log.sh の 6 箇所が jq -e の複数出力に依存しており、2 つ目の Bash matcher が入ると偽 PASS する #167

Description

概要

tests/unit/test-pr-creation-log.sh の 6 箇所(L53 / L54 / L73 / L74 / L93 / L94)が、#161 と同じ「jq -e は最後の出力で終了コードを決める」仕様に依存している。

現状は matcher: "Bash" を持つ PostToolUse エントリがキット内に 1 つしかないため誤判定しないが、2 つ目が追加された時点で発火する。否定形のアサーションは偽 PASS(退行を検出できない)になるため、テストが守っているつもりの性質が黙って守られなくなる。

該当箇所

# L53-54(肯定形)
jq -e '.hooks.PostToolUse[] | select(.matcher == "Bash") | .hooks[0].if == "Bash(gh pr create *)"'
jq -e '.hooks.PostToolUse[] | select(.matcher == "Bash") | .hooks[0].async == true'

# L93-94(否定形・legacy fallback の検査)
jq -e '.hooks.PostToolUse[] | select(.matcher == "Bash") | .hooks[0] | has("if") | not'
jq -e '.hooks.PostToolUse[] | select(.matcher == "Bash") | .hooks[0] | has("async") | not'

L73-74 は L53-54 と同型。

select は一致したエントリの数だけ出力を生成するため、matcher: "Bash" のエントリが 2 つ以上あると jq -e は最後の 1 件だけで判定する。

再現

matcher: "Bash"PostToolUse が 2 つあり、かつ 1 件目(pr-creation-log)が legacy 形に退行している状態を模したフィクスチャ。

{"hooks":{"PostToolUse":[
  {"matcher":"Bash","hooks":[{"type":"command","command":"log-pr.sh","if":"Bash(gh pr create *)","async":true}]},
  {"matcher":"Bash","hooks":[{"type":"command","command":"future-hook.sh"}]}
]}}

実測(jq-1.7.1-apple):

フィルタ rc 意味
現行の否定形(L93) 0 退行を見逃す偽 PASS
[...] | any(has("if") | not) 0 直っていない
[...] | all(has("if") | not) 1 正しく検出
現行の肯定形(L53) 1 正しい状態なのに偽 FAIL

否定形は any() では直らない。 #161 で採用した配列集約 + any() の型をそのまま当てると、L93/94 は偽 PASS のまま残る。

発火条件

_FEATURE_ORDERlib/features.sh)に matcher: "Bash"PostToolUse を持つ feature が追加されると成立する。CLAUDE.md の「Adding a New Feature」は新しい hook を既存の後ろに追記するよう案内しており、追記されたエントリは pr-creation-log より後ろに来る。これは L93/94 が偽 PASS になる並びそのもの。

現時点で PostToolUse を持つのは prettier-hooks / biome-hooksEdit|Write)、doc-size-guardWrite)、pr-creation-logBash)で、Bash は 1 つだけ。modern / legacy いずれの経路でも _versioned_hooks_fragmenthooks.jsonhooks.legacy.json のどちらか一方しか返さないため、二重にはならない。

提案する修正

意図は「pr-creation-log のエントリがどうなっているか」なので、matcher ではなくコマンドで対象を選ぶのが正確。

jq -e 'any(.hooks.PostToolUse[]?.hooks[]?;
           (.command? // "") | contains("pr-creation-log/log-pr.sh"))'

そのうえで、

  • 肯定形は対象エントリを 1 件に絞ったうえで属性を検査する
  • 否定形は all(...) で畳み込む(any() では直らない)

あわせて、退行を検出できることを担保する回帰テストを追加したい。合成した 2 件目の matcher: "Bash" エントリを足したフィクスチャに対し、否定形の検査が失敗することを確認する形。現行フィルタでは通ってしまい、修正後は落ちる。

補足

#161lib/update.sh_check_auto_update_health)と同じクラスだが、本番コード側の掃討では lib/update.sh:2101:2104 の 2 箇所のみが該当し、それらは PR #164 で修正済み。本 issue は tests/ 側に残っている同クラスの箇所。

環境

  • starter kit: v0.76.0(554e455
  • jq: jq-1.7.1-apple

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions