feat: Husky v8→v9 移行チェックを repo-maintenance に追加 - #540
Conversation
## 変更内容 - Step 3.2.2 として `Husky v8 → v9 Migration Check` を追加 - `core.hooksPath = .husky/_`(v8スタイル)を自動検出 - `full` モード時に `git config core.hooksPath ".husky"` で v9 へ更新 - 各フックファイルから旧 shebang(`_/husky.sh`)を削除 - `#!/usr/bin/env sh` → `#!/bin/sh` に統一 - サマリーレポートに `Husky v8→v9` ステータス行を追加 - 既存の Step 3.2.1(Check-file-length)を 3.2.3 に採番更新 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughA markdown file documenting repository maintenance checks has been updated to introduce a new Husky v8 to v9 migration verification check. The change includes detection logic for v8-style hooks, migration steps, and status reporting enhancements to track migration state. Changes
Possibly related PRs
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce6e8d3a7e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # 旧 husky v8 の source 行を削除 | ||
| grep -v "_/husky.sh" "$hook" > "$hook.tmp" && mv "$hook.tmp" "$hook" | ||
| # #!/usr/bin/env sh を #!/bin/sh に統一 | ||
| sed -i "" "s|#!/usr/bin/env sh|#!/bin/sh|" "$hook" |
There was a problem hiding this comment.
Replace BSD-only sed flag in Husky migration
The migration snippet uses sed -i "" ..., which is BSD/macOS-specific; on GNU sed (the default in Linux devcontainers/Codespaces) -i expects an optional suffix attached to the flag, so this form fails with sed: can't read ... instead of editing the hook file. In --mode full on repositories still using Husky v8, this can abort or partially apply the migration, leaving hooks unconverted on the primary Linux execution environment.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/commands/repo-maintenance.md:
- Line 752: The fenced sample currently contains literal "\n" sequences instead
of real line breaks; locate the fenced block containing the string "├── Husky: ✅
Git hooks configured\n├── hooksPath: ✅ Valid (.husky) (or 🔧 Fixed / ❌ Manual
required)\n├── Husky v8→v9: ✅ v9スタイル済み (or 🔧 移行しました / ✅ スキップ)" and replace it
with three actual lines (one per item) or a proper Markdown list so the output
renders as three separate lines rather than showing "\n" characters.
- Around line 395-405: The loop currently iterates only over the three explicit
hook names (".husky/pre-commit .husky/pre-push .husky/commit-msg"), which
contradicts "各フックファイル" and misses other hooks like "prepare-commit-msg"; change
the loop to iterate over all files in the .husky directory (e.g., replace the
explicit list with a glob like ".husky/*") so every hook is processed, and
ensure the body (grep/sed/chmod/echo) works for arbitrary hook filenames (update
the echo text if needed to avoid implying only those three hooks).
- Around line 399-401: Replace the macOS-only sed usage with a portable in-place
edit: detect or avoid the BSD-specific sed -i "" call and instead perform a
portable edit flow for the hook rewrite (the line invoking sed -i ""
"s|#!/usr/bin/env sh|#!/bin/sh|" "$hook"); for example, write the sed output to
a temporary file and move it back (similar to the grep temp approach) or use sed
-i.bak and then remove the .bak file so the same transformation works on both
GNU and BSD sed without failing the migration step.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 617ba4f8-2938-4b61-be3d-8ab3578f3b57
📒 Files selected for processing (1)
.claude/commands/repo-maintenance.md
| for hook in .husky/pre-commit .husky/pre-push .husky/commit-msg; do | ||
| [ ! -f "$hook" ] && continue | ||
| if grep -q "_/husky.sh" "$hook"; then | ||
| # 旧 husky v8 の source 行を削除 | ||
| grep -v "_/husky.sh" "$hook" > "$hook.tmp" && mv "$hook.tmp" "$hook" | ||
| # #!/usr/bin/env sh を #!/bin/sh に統一 | ||
| sed -i "" "s|#!/usr/bin/env sh|#!/bin/sh|" "$hook" | ||
| chmod +x "$hook" | ||
| echo "🔧 $hook から旧 shebang を削除しました" | ||
| fi | ||
| done |
There was a problem hiding this comment.
The migration only updates three hook names.
The text says 各フックファイルですが、実際には pre-commit / pre-push / commit-msg だけです。prepare-commit-msg など他の Git hooks を使う repo では移行が中途半端になります。ループを .husky/* ベースに広げるか、説明をこの 3 つ限定に寄せた方がよいです。
Suggested fix
-for hook in .husky/pre-commit .husky/pre-push .husky/commit-msg; do
- [ ! -f "$hook" ] && continue
+for hook in .husky/*; do
+ [ ! -f "$hook" ] && continue
+ [ "$(basename "$hook")" = "_" ] && continue
+ [ "$(basename "$hook")" = ".gitignore" ] && continue
if grep -q "_/husky.sh" "$hook"; then🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/commands/repo-maintenance.md around lines 395 - 405, The loop
currently iterates only over the three explicit hook names (".husky/pre-commit
.husky/pre-push .husky/commit-msg"), which contradicts "各フックファイル" and misses
other hooks like "prepare-commit-msg"; change the loop to iterate over all files
in the .husky directory (e.g., replace the explicit list with a glob like
".husky/*") so every hook is processed, and ensure the body
(grep/sed/chmod/echo) works for arbitrary hook filenames (update the echo text
if needed to avoid implying only those three hooks).
| grep -v "_/husky.sh" "$hook" > "$hook.tmp" && mv "$hook.tmp" "$hook" | ||
| # #!/usr/bin/env sh を #!/bin/sh に統一 | ||
| sed -i "" "s|#!/usr/bin/env sh|#!/bin/sh|" "$hook" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
tmp="$(mktemp)"
printf '#!/usr/bin/env sh\n' > "$tmp"
echo "Testing BSD-style: sed -i \"\" ..."
if sed -i "" 's|#!/usr/bin/env sh|#!/bin/sh|' "$tmp" 2>/dev/null; then
echo "BSD-style in-place edit is supported here"
else
echo "BSD-style in-place edit is NOT supported here"
fi
echo "sed version:"
sed --version 2>/dev/null | head -n1 || echo "BSD sed (no --version output)"
rm -f "$tmp"Repository: keito4/config
Length of output: 166
🏁 Script executed:
fd "repo-maintenance.md" --type fRepository: keito4/config
Length of output: 39
🏁 Script executed:
# Search for repo-maintenance in any location
find . -name "*repo-maintenance*" -o -name "*.md" | grep -i "maintenance" | head -20Repository: keito4/config
Length of output: 95
🏁 Script executed:
# Check if .claude directory exists
ls -la .claude/ 2>/dev/null || echo ".claude directory not found"Repository: keito4/config
Length of output: 815
🏁 Script executed:
# Check total lines in the file
wc -l ./.claude/commands/repo-maintenance.mdRepository: keito4/config
Length of output: 99
🏁 Script executed:
# Read lines around 399-401 with context
sed -n '390,410p' ./.claude/commands/repo-maintenance.mdRepository: keito4/config
Length of output: 616
🏁 Script executed:
# Get exact lines 399-401
sed -n '399,401p' ./.claude/commands/repo-maintenance.mdRepository: keito4/config
Length of output: 224
🏁 Script executed:
# Get broader context around line 400 to understand the full section
sed -n '375,415p' ./.claude/commands/repo-maintenance.md | cat -nRepository: keito4/config
Length of output: 1740
🏁 Script executed:
# Check line 752 context
sed -n '745,760p' ./.claude/commands/repo-maintenance.mdRepository: keito4/config
Length of output: 761
Use a portable in-place edit for hook rewrites.
sed -i "" is BSD/macOS-specific and fails on GNU sed. In Linux/devcontainer environments this step will fail, breaking the migration workflow right where it's most likely to run.
Suggested fix
- # #!/usr/bin/env sh を #!/bin/sh に統一
- sed -i "" "s|#!/usr/bin/env sh|#!/bin/sh|" "$hook"
+ # #!/usr/bin/env sh を #!/bin/sh に統一(GNU/BSD sed 両対応)
+ tmp_hook="$(mktemp)"
+ sed 's|#!/usr/bin/env sh|#!/bin/sh|' "$hook" > "$tmp_hook" && mv "$tmp_hook" "$hook"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| grep -v "_/husky.sh" "$hook" > "$hook.tmp" && mv "$hook.tmp" "$hook" | |
| # #!/usr/bin/env sh を #!/bin/sh に統一 | |
| sed -i "" "s|#!/usr/bin/env sh|#!/bin/sh|" "$hook" | |
| grep -v "_/husky.sh" "$hook" > "$hook.tmp" && mv "$hook.tmp" "$hook" | |
| # #!/usr/bin/env sh を #!/bin/sh に統一(GNU/BSD sed 両対応) | |
| tmp_hook="$(mktemp)" | |
| sed 's|#!/usr/bin/env sh|#!/bin/sh|' "$hook" > "$tmp_hook" && mv "$tmp_hook" "$hook" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/commands/repo-maintenance.md around lines 399 - 401, Replace the
macOS-only sed usage with a portable in-place edit: detect or avoid the
BSD-specific sed -i "" call and instead perform a portable edit flow for the
hook rewrite (the line invoking sed -i "" "s|#!/usr/bin/env sh|#!/bin/sh|"
"$hook"); for example, write the sed output to a temporary file and move it back
(similar to the grep temp approach) or use sed -i.bak and then remove the .bak
file so the same transformation works on both GNU and BSD sed without failing
the migration step.
| ## Setup (2/4) | ||
| ├── Team Protection: ✅ Branch protection enabled | ||
| ├── Husky: ✅ Git hooks configured\n├── hooksPath: ✅ Valid (.husky) (or 🔧 Fixed / ❌ Manual required) | ||
| ├── Husky: ✅ Git hooks configured\n├── hooksPath: ✅ Valid (.husky) (or 🔧 Fixed / ❌ Manual required)\n├── Husky v8→v9: ✅ v9スタイル済み (or 🔧 移行しました / ✅ スキップ) |
There was a problem hiding this comment.
Split the sample summary into actual lines.
この fenced block だと \n は改行されず、そのまま表示されます。サンプル出力としては 3 行に分けた方が正しいです。
Suggested fix
-├── Husky: ✅ Git hooks configured\n├── hooksPath: ✅ Valid (.husky) (or 🔧 Fixed / ❌ Manual required)\n├── Husky v8→v9: ✅ v9スタイル済み (or 🔧 移行しました / ✅ スキップ)
+├── Husky: ✅ Git hooks configured
+├── hooksPath: ✅ Valid (.husky) (or 🔧 Fixed / ❌ Manual required)
+├── Husky v8→v9: ✅ v9スタイル済み (or 🔧 移行しました / ✅ スキップ)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ├── Husky: ✅ Git hooks configured\n├── hooksPath: ✅ Valid (.husky) (or 🔧 Fixed / ❌ Manual required)\n├── Husky v8→v9: ✅ v9スタイル済み (or 🔧 移行しました / ✅ スキップ) | |
| ├── Husky: ✅ Git hooks configured | |
| ├── hooksPath: ✅ Valid (.husky) (or 🔧 Fixed / ❌ Manual required) | |
| ├── Husky v8→v9: ✅ v9スタイル済み (or 🔧 移行しました / ✅ スキップ) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/commands/repo-maintenance.md at line 752, The fenced sample
currently contains literal "\n" sequences instead of real line breaks; locate
the fenced block containing the string "├── Husky: ✅ Git hooks configured\n├──
hooksPath: ✅ Valid (.husky) (or 🔧 Fixed / ❌ Manual required)\n├── Husky v8→v9:
✅ v9スタイル済み (or 🔧 移行しました / ✅ スキップ)" and replace it with three actual lines (one
per item) or a proper Markdown list so the output renders as three separate
lines rather than showing "\n" characters.
|
コードレビュー 全体的に実用的な追加で、背景と対応パターンの説明も明確です。 sed -i の Linux/GNU 非互換: chatgpt-codex-connector が指摘の通り、BSD sed の sed -i 空文字列構文は macOS 専用です。Linux の GNU sed では空文字列をファイル名として解釈するため DevContainer / Codespaces 環境で失敗します。修正案として sed -i.bak を使用することを推奨します(GNU/BSD 両対応)。 mv 後のパーミッション消失: grep -v + mv でファイルを置き換えると新規作成扱いとなり実行権限が失われます。直後の chmod +x で回復しますが sed 失敗時にリスクがあります。 検出対象フックが限定的: pre-commit, pre-push, commit-msg のみです。.husky/ 配下を動的スキャンする方が堅牢です。 shebang 変換について: Husky v9 の移行要件は _/husky.sh の source 行削除のみです。変換の意図をコメントで補足することを推奨します。 良い点: v8/v9 の違いを表形式で整理、core.hooksPath 未設定時も安全に処理、full モード限定の自動修正は適切。 sed -i の修正が最優先です。 |
|
🎉 This PR is included in version 1.88.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
概要
repo-maintenanceスキルに Husky v8→v9 の自動移行チェックステップを追加しました。変更内容
Husky v8 → v9 Migration Checkcore.hooksPath = .husky/_(v8スタイル)を自動検出fullモード時にgit config core.hooksPath ".husky"で v9 スタイルへ自動更新pre-commit,pre-push,commit-msg)から旧 shebang(_/husky.sh)を削除#!/usr/bin/env sh→#!/bin/shに統一chmod +x)を付与Husky v8→v9ステータス行を追加背景
nomad_japanリポジトリでcore.hooksPath = --version/_(破損)を発見・修正した際に、Husky v8(
.husky/_)スタイルのリポジトリが複数存在することが判明しました。repo-maintenanceで自動検出・移行できるようにしました。v8 と v9 の違い
.husky/_.husky_/h経由_/husky.shsource 行が必要🤖 Generated with Claude Code
Summary by CodeRabbit