Add bin/check-links for local link checking#2238
Conversation
Matches CI behavior exactly by checking only git-tracked, user-facing docs: - docs/**/*.md - *.md (root level only) - react_on_rails_pro/docs/**/*.md - react_on_rails_pro/*.md Uses `git ls-files` to ensure untracked files don't cause local/CI mismatches. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
WalkthroughAdds a new executable Bash script Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
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 |
Code Review - PR #2238Thanks for adding this helpful script! Overall this looks good and solves a real problem. Strengths
Potential Issues1. Missing -o pipefail for better error handling The script uses set -e but is missing set -o pipefail. This is important because the script uses a pipeline with grep and sort, and you want to catch failures in any part of the pipeline. Current: set -e Compare with bin/ci-rerun-failures:9 which uses the stricter settings. 2. Potential issue with grep -v failing when no root .md files exist The line git ls-files *.md | grep -v / could fail with exit code 1 if there are no root-level .md files (because grep returns 1 when no matches are found). While this is unlikely in this project, it could cause the script to fail unexpectedly. Possible fix: git ls-files *.md | grep -v / || true Suggested Improvements
Required Changes
Overall, this is a solid addition to the developer tooling. The required changes are minor, and the optional enhancements would make it more user-friendly to match other bin scripts in the project. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
bin/check-links (2)
11-16: Consider verifying lychee is installed.The script will fail with a cryptic error if
lycheeis not installed or not in PATH. Consider adding a check at the beginning of the script to provide a helpful error message.Add this check after line 9:
set -e if ! command -v lychee &> /dev/null; then echo "Error: lychee is not installed. Install it with: cargo install lychee" >&2 exit 1 fi
12-12: Optional: Remove redundant glob patterns.The patterns
docs/**/*.mdandreact_on_rails_pro/docs/**/*.mdalready match files that would be matched bydocs/*.mdandreact_on_rails_pro/docs/*.mdrespectively (the**glob includes zero or more directory levels). While harmless due tosort -udeduplication, the explicit single-level patterns are redundant.Consider simplifying to:
{ - git ls-files 'docs/*.md' 'docs/**/*.md' + git ls-files 'docs/**/*.md' git ls-files '*.md' | grep -v '/' || true - git ls-files 'react_on_rails_pro/docs/*.md' 'react_on_rails_pro/docs/**/*.md' + git ls-files 'react_on_rails_pro/docs/**/*.md' git ls-files 'react_on_rails_pro/*.md' } | sort -u | lychee --config .lychee.toml --files-from -Also applies to: 14-14
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
bin/check-links(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: examples (3.4, latest)
- GitHub Check: precompile-check
- GitHub Check: rspec-package-tests (3.4, latest)
- GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22, latest)
- GitHub Check: pro-lint-js-and-ruby
- GitHub Check: build
- GitHub Check: build-dummy-app-webpack-test-bundles
- GitHub Check: build-dummy-app-webpack-test-bundles
- GitHub Check: claude-review
🔇 Additional comments (2)
bin/check-links (2)
1-8: LGTM! Clear documentation.The shebang and comments clearly explain the script's purpose and behavior, making it easy to understand which paths are checked.
9-9: Strict error handling is appropriate.The
set -eflag ensures the script fails fast on errors, which is good for a utility script.
Code Review: bin/check-linksStrengths
Issues Found1. CRITICAL: Pattern mismatch with CI workflowThe CI workflow (.github/workflows/check-markdown-links.yml:36) uses: Your script has: git ls-files 'docs/.md' 'docs/**/.md' Problem: The 'docs/.md' pattern only matches files directly in docs/, not subdirectories. This is redundant with 'docs/**/.md' which already matches everything. Solution: Remove 'docs/.md' from line 12 - keep only 'docs/**/.md' Same issue on line 14: remove 'react_on_rails_pro/docs/*.md' 2. Missing error handling for lycheeIf lychee is not installed, the script will fail with an unclear error. Suggestion: Add a check before the main command 3. Script doesn't verify it matches CIConsider testing locally that the file list matches what CI checks Testing ChecklistBefore merging, verify:
PriorityHIGH: Fix the docs/*.md pattern mismatch to ensure script truly matches CI behavior. Overall, this is a useful addition! Just need to fix the glob patterns. Great work solving a real pain point. |
- Add Usage comment for consistency with other bin scripts - Use set -eo pipefail for stricter error handling in pipelines - Add || true to grep to prevent failure when no root .md files exist 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
@claude Thanks for the review! However, the "CRITICAL" pattern mismatch issue is actually incorrect. Testing shows both patterns are needed$ git ls-files 'docs/*.md' | wc -l
92
$ git ls-files 'docs/**/*.md' | wc -l
83
$ comm -23 <(git ls-files 'docs/*.md' | sort) <(git ls-files 'docs/**/*.md' | sort)
docs/CI_OPTIMIZATION.md
docs/DIRECTORY_LICENSING.md
docs/introduction.md
docs/JS_PRO_PACKAGE_SEPARATION_PLAN.md
docs/LICENSING_FAQ.md
docs/MONOREPO_MERGER_PLAN.md
docs/MONOREPO_MERGER_PLAN_REF.md
docs/README.md
docs/swc-migration.mdIn git's pathspec,
The 9 files above (like Other feedback
The script is correct as-is. CodeRabbit made the same incorrect claim about redundant patterns. |
|
Claude finished @ihabadham's task in 43s —— View job Code Review Update - bin/check-linksThank you for the correction! You're absolutely right - I was wrong about the pattern matching. ✅ Correction AcknowledgedYour testing clearly demonstrates that in git pathspec:
The 9 files only matched by Updated ReviewStrengths:
Pattern Analysis: The script correctly translates CI's lychee args into git pathspecs:
Optional Improvements (not required):
Recommendation: ✅ Approve - Script is correct as-is. The pattern matching is accurate and properly handles all edge cases. |
Code Review - PR #2238Overall, this is a well-designed utility script that solves a real problem. The implementation is clean and the documentation is clear. Here are my observations: ✅ Strengths
📝 Suggestions for Enhancement1. Add dependency check (Medium Priority)The script requires # Add before line 17
if \! command -v lychee >/dev/null 2>&1; then
echo "Error: lychee is not installed."
echo ""
echo "Install with:"
echo " cargo install lychee (or brew install lychee)"
echo ""
echo "See: https://lychee.cli.rs/#/installation"
exit 1
fiWhy: Provides helpful error message instead of cryptic 2. Consider adding
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
bin/check-links (1)
17-22: Consider adding a check for lychee availability.If lychee is not installed, the script will fail with a potentially confusing "command not found" error. A pre-flight check could improve the user experience.
+if ! command -v lychee &> /dev/null; then + echo "Error: lychee is not installed. Install it with: cargo install lychee" >&2 + exit 1 +fi + { git ls-files 'docs/*.md' 'docs/**/*.md'
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
bin/check-links(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: rspec-package-tests (3.4, latest)
- GitHub Check: examples (3.4, latest)
- GitHub Check: build-dummy-app-webpack-test-bundles
- GitHub Check: build
- GitHub Check: pro-lint-js-and-ruby
- GitHub Check: build-dummy-app-webpack-test-bundles
- GitHub Check: claude-review
🔇 Additional comments (1)
bin/check-links (1)
1-22: LGTM! Script correctly mirrors CI behavior for local link checking.The implementation is well-structured:
- Documentation clearly explains purpose and paths
set -eo pipefailprovides appropriate error handling|| trueon line 19 correctly handles the case when no root-level .md files existsort -uproperly deduplicates files that may match multiple patterns- Command grouping cleanly collects all file sources
Provides helpful error message if lychee is not installed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Code Review FeedbackGreat addition! This script will definitely help developers catch link issues before CI. Here's my analysis: ✅ Strengths
🔍 Observations & Suggestions1. Minor Pattern Discrepancy with CI (Low Priority)The CI workflow uses directory-based args: args: --config .lychee.toml docs/ *.md react_on_rails_pro/docs/ react_on_rails_pro/*.mdYour script uses more explicit glob patterns: git ls-files 'docs/*.md' 'docs/**/*.md'
git ls-files 'react_on_rails_pro/docs/*.md' 'react_on_rails_pro/docs/**/*.md'Impact: Minimal - both approaches should produce the same results since Verification: I tested the logic and confirmed it correctly matches:
2. Bash Best Practices Comparison (Informational)Looking at similar scripts in the repo (e.g.,
However, for a simple utility script like this, the current implementation is perfectly adequate. The trade-off between simplicity and feature-richness is well-balanced here. 3. Edge Case: Empty File List (Very Low Priority)If all git-tracked .md files were somehow deleted, the script would pass empty input to lychee. Testing this: echo "" | lychee --files-from -
# This works fine - lychee just reports 0 files checkedSo no issue here. 4. Potential Enhancement: Cache Support (Optional)The CI workflow uses caching via # Note: Cache is configured in .lychee.toml and stored in .lycheecache/But this is purely informational - the script already benefits from caching since it uses the same config file. 🎯 Code Quality Assessment
🧪 Testing RecommendationBefore merging, verify the script works as expected: # Ensure lychee is installed
cargo install lychee
# Run the script
bin/check-links
# Compare output with what CI would check (file count should match)📋 Final VerdictApprove with no blocking issues. This is a well-crafted utility script that achieves its purpose elegantly. The suggestions above are optional enhancements, not required changes. The script correctly:
Great work! 🚀 |
Summary
Adds a
bin/check-linksscript for running lychee link checker locally with the same behavior as CI.Problem
Running
lycheedirectly locally can produce different results than CI because:*.mdmatch untracked files that CI never seesSolution
The script uses
git ls-filesto ensure only git-tracked files are checked, matching the exact paths CI checks:docs/**/*.md*.md(root level only)react_on_rails_pro/docs/**/*.mdreact_on_rails_pro/*.mdUsage
🤖 Generated with Claude Code
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.