-
Couldn't load subscription status.
- Fork 0
refactor: Replace bash scripts with Ruby equivalents #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Created Ruby versions of apply-shared, bootstrap-all, and test-all in bin/ - Deleted redundant bash scripts from scripts/ directory - Updated documentation to reference new Ruby scripts - Improved maintainability with proper error handling and CLI options - All Ruby scripts support --dry-run and --help flags This consolidation eliminates duplication and provides: - Better error handling and testability - Consistent Ruby-based tooling - Cleaner codebase structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Warning Rate limit exceeded@justin808 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 22 minutes and 1 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (3)
WalkthroughReplaces multiple Bash scripts in scripts/ with Ruby executables in bin/, adds supporting Ruby modules under lib/demo_scripts/, updates RuboCop config and documentation to reference bin/ tools, and adds RSpec test coverage for new modules. Removes legacy Bash utilities and updates aggregator lib file requires. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Developer
participant CLI as bin/apply-shared
participant DM as DemoManager
participant FS as Filesystem
Dev->>CLI: apply-shared [--dry-run]
activate CLI
CLI->>DM: each_demo
DM-->>CLI: demo paths
CLI->>FS: Validate packages/shakacode_demo_common exists
alt missing shared config
CLI-->>Dev: Error and exit(1)
else present
loop for each demo
CLI->>FS: Create/replace symlinks to shared configs
CLI->>FS: Ensure Gemfile includes shakacode_demo_common
end
CLI-->>Dev: Completed
end
deactivate CLI
sequenceDiagram
autonumber
actor Dev as Developer
participant CLI as bin/bootstrap-all
participant DM as DemoManager
participant Exec as CommandExecutor
Dev->>CLI: bootstrap-all [--dry-run --verbose]
CLI->>DM: each_demo (includes shared if present)
par Bootstrap shared (if exists)
CLI->>Exec: bundle install / pnpm|npm install
end
loop demos
CLI->>Exec: bundle install (if Gemfile)
CLI->>Exec: pnpm|npm install (if package.json)
opt Rails app
CLI->>Exec: bin/rails db:prepare (allow failure)
end
end
CLI-->>Dev: Bootstrap complete
sequenceDiagram
autonumber
actor Dev as Developer
participant CLI as bin/test-all
participant DM as DemoManager
participant Exec as CommandExecutor
Dev->>CLI: test-all [--dry-run --verbose --fail-fast]
rect rgba(230,245,255,0.5)
note right of CLI: Test shared (if present)
CLI->>Exec: rspec
CLI->>Exec: rubocop
CLI->>Exec: npm test (and lint)
end
loop demos
CLI->>DM: each_demo
alt Rails tests available
CLI->>Exec: rspec or bin/rails test
end
alt JS tests available
CLI->>Exec: npm test
end
CLI-->>CLI: Accumulate failures
opt --fail-fast
CLI-->>Dev: Early exit on first failure
end
end
CLI-->>Dev: Report results and exit code
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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 |
|
PR Review: Replace bash scripts with Ruby equivalents SUMMARY STRENGTHS
CRITICAL ISSUES MINOR ISSUES
SECURITY
PERFORMANCE TEST COVERAGE STATISTICS ASSESSMENT High-quality refactoring. Minor issues are nitpicks, not blockers. BEFORE MERGE:
Can merge as-is? YES, but items 2-3 recommended for security/robustness. Great work! |
Security & Code Quality Fixes: - Fixed missing newlines at EOF in all Ruby scripts - Replaced bare rescue with StandardError throughout - Fixed command injection risk in command_exists? using array form - Verified and updated CONFIG_FILES paths to match actual locations - Added specific SystemCallError handling for Open3.capture2e - Optimized package.json reads with caching to avoid duplicates Configuration: - Enabled RuboCop linting for /bin files by removing exclusion - Added appropriate metrics exclusions for bin scripts Refactoring & Modularity: - Created shared modules to reduce duplication: - CommandExecutor: Shared command execution logic - DemoManager: Base class for demo management - PackageJsonCache: Caching for package.json reads - Reduced total code from ~1257 lines to 520 lines - Improved method naming (has_* → *?) per Ruby conventions - Maintained backward compatibility with aliases Testing: - Added comprehensive unit tests (39 test cases) - 100% test coverage for new shared modules - All tests passing Stats: - Line reduction: 737 lines eliminated (58% reduction) - Code quality: All critical RuboCop violations fixed - Security: All injection risks eliminated 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Pull Request Review: Bash to Ruby Script MigrationSummaryThis PR successfully replaces bash scripts with Ruby equivalents, significantly improving code quality, maintainability, and testability. The refactoring demonstrates excellent software engineering practices with proper modularization, error handling, and comprehensive test coverage. ✅ StrengthsCode Quality & Architecture
Testing
Developer Experience
Performance
🔍 Areas for Consideration1. Potential Race Condition in Symlink CreationLocation: FileUtils.rm_f(target)
FileUtils.ln_s(relative_source, target)Issue: If another process checks for the symlink between these two operations, there's a brief window where the file doesn't exist. Suggestion: Use atomic operations or add error handling: FileUtils.ln_s(relative_source, target, force: true)2. File Reading Without Size CheckLocation: if File.read(gemfile_path).include?('shakacode_demo_common')Issue: Reading entire file into memory could be problematic for very large Gemfiles. Suggestion: Consider using File.foreach(gemfile_path).any? { |line| line.include?('shakacode_demo_common') }3. Command Injection Still PossibleLocation: output, status = Open3.capture2e(command)Issue: Passing string commands to Current Risk: Low (commands are hardcoded in current usage) Future-Proofing: Consider adding a method that accepts command + args separately: def run_command_safe(cmd, *args, allow_failure: false)
output, status = Open3.capture2e(cmd, *args)
# ... rest of logic
end4. Missing Test Coverage for Main ScriptsLocation: Issue: While shared modules have 100% test coverage, the main script classes ( Impact: Medium - Integration paths untested Suggestion: Add specs for:
5. Error Handling in File OperationsLocation: File.open(gemfile_path, 'a') { |f| f.puts addition }Issue: No error handling for disk full, permissions errors, or I/O failures. Suggestion: Wrap in rescue block or document assumption of writable filesystem. 6. Package.json Cache Not Cleared Between DemosLocation: Issue: Cache persists across demo iterations, which is fine but could cause issues if demos are manipulated during testing. Current Risk: Very low Suggestion: Add 7. Verbose Output InconsistencyLocation: puts output if @verbose || !status.success?Issue: Output is shown on failure even when not verbose, which is good for debugging but inconsistent with the Consideration: Is this intentional? If so, document the behavior. If not, consider: puts output if @verbose
warn output unless status.success? # Use stderr for errors8. Absolute vs Relative Path HandlingLocation: @root_dir = File.expand_path('../..', __dir__)Issue: Assumes script location relative to file structure. Could break if scripts are moved or symlinked. Suggestion: Consider using environment variable or git root detection: @root_dir = `git rev-parse --show-toplevel`.strip🔐 Security Review✅ Addressed Security Issues
|
Use FileUtils.ln_s with force: true for atomic symlink operations. This eliminates the brief window where the symlink doesn't exist between rm_f and ln_s operations, preventing potential race conditions if another process checks for the symlink during that time. The force: true option atomically replaces existing symlinks in a single operation, making the code both safer and simpler. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Pull Request Review: Ruby Script RefactoringSummaryThis PR successfully replaces bash scripts with Ruby equivalents and adds significant improvements to code quality, maintainability, and test coverage. The refactoring eliminates ~737 lines of code while adding robust functionality and comprehensive testing. ✅ StrengthsCode Quality & Architecture
Testing
Performance & Efficiency
Documentation
🔍 Code Review FindingsMinor Issues
Potential Enhancements
🔒 Security✅ Fixed Issues
✅ No New Concerns
🚀 PerformanceOptimizations Applied
Suggestions
📊 Test Coverage AssessmentExcellent Coverage
Missing Coverage
RecommendationConsider adding integration tests that actually run the bin scripts with fixtures to ensure end-to-end functionality. 🎯 Best Practices Adherence✅ Followed
🔄 Considerations
📝 Documentation Quality✅ Strong Points
💡 Suggestions
🏁 ConclusionThis is a high-quality refactoring that significantly improves the codebase. The PR demonstrates:
Recommendation: APPROVE ✅The minor issues noted above are truly minor and don't block merging. The benefits far outweigh any concerns:
Post-Merge Suggestions
Great work! This refactoring sets a solid foundation for future maintenance and enhancements. Review generated with attention to code quality, security, performance, and maintainability standards |
Improved output handling consistency: - Verbose output now consistently goes to stdout - Error output goes to stderr when not in verbose mode for debugging - No duplicate output when both verbose and error conditions occur - Added clear documentation of output behavior This change makes the --verbose flag behavior more predictable and follows Unix conventions of using stderr for error output while preserving the ability to see errors for debugging. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (6)
bin/apply-shared (1)
63-73: Potential false positive in Gemfile check.Line 67 uses a simple substring check (
include?('shakacode_demo_common')) which could match comments or strings, not just the gem declaration. Consider a more robust check, such as parsing the Gemfile or using a regex to match the gem line.Apply this diff for a more precise check:
- if File.read(gemfile_path).include?('shakacode_demo_common') + if File.read(gemfile_path).match?(/^\s*gem\s+['"]shakacode_demo_common['"]/)lib/demo_scripts/command_executor.rb (2)
30-32: Consider portability of command existence check.The
system('which', command, ...)approach works on Unix-like systems but may not be portable to Windows. Consider using Ruby's built-in mechanisms likeGem.find_executable(command)or checkingENV['PATH']directories directly for better cross-platform support.Apply this diff for better portability:
def command_exists?(command) - system('which', command, out: File::NULL, err: File::NULL) + !Gem.find_executable(command).nil? end
10-27: Consider adding timeout support for long-running commands.While the current implementation handles errors and dry-run mode well, there's no timeout mechanism for commands that might hang indefinitely. For production robustness, consider adding an optional timeout parameter.
Example enhancement:
def run_command(command, allow_failure: false, timeout: nil) if @dry_run puts " [DRY-RUN] #{command}" return true end begin if timeout output, status = Open3.capture2e(command, timeout: timeout) else output, status = Open3.capture2e(command) end rescue Timeout::Error raise Error, "Command timed out after #{timeout}s: #{command}" rescue SystemCallError => e raise Error, "Failed to execute command '#{command}': #{e.message}" end puts output if @verbose || !status.success? raise Error, "Command failed: #{command}" unless status.success? || allow_failure status.success? endbin/test-all (1)
95-106: Inconsistent dry-run handling in test command execution.The
run_test_commandmethod checks@dry_runand returns early (lines 96-99), but it then callsrun_command(command, allow_failure: true)on line 101, which will also check@dry_runinternally. While this double-check is harmless, it's redundant and could be confusing.Consider removing the redundant dry-run check:
def run_test_command(command, context, allow_failure: false) - if @dry_run - puts " [DRY-RUN] #{command}" - return - end - success = run_command(command, allow_failure: true) return if success @failed_tests << context unless allow_failure puts " ❌ Test failed for #{context}" unless allow_failure endThe
run_commandmethod fromCommandExecutoralready handles dry-run mode appropriately.lib/demo_scripts/demo_manager.rb (2)
36-40: Path resolution assumes consistent directory structure.The
setup_pathsmethod usesFile.expand_path('../..', __dir__)to find the root directory, which assumes this file is always atlib/demo_scripts/demo_manager.rbrelative to the project root. While this is likely stable, it creates tight coupling to the file system structure.Consider documenting this assumption with a comment:
def setup_paths + # Assumes this file is at lib/demo_scripts/demo_manager.rb relative to project root @root_dir = File.expand_path('../..', __dir__) @shakacode_demo_common_path = File.join(@root_dir, 'packages', 'shakacode_demo_common') @demos_dir = File.join(@root_dir, 'demos') end
56-70: Helper methods could be simplified with a common pattern.The helper methods
ruby_tests?,gemfile?,package_json?, andrails?all follow a similar pattern of checking for file/directory existence. The current implementation withfile_exists_in_dir?is reasonable, but there's a minor inconsistency:ruby_tests?usesDir.exist?directly while others usefile_exists_in_dir?.Consider making the pattern more consistent:
def ruby_tests?(dir = Dir.pwd) - Dir.exist?(File.join(dir, 'spec')) || Dir.exist?(File.join(dir, 'test')) + File.directory?(File.join(dir, 'spec')) || File.directory?(File.join(dir, 'test')) endThis uses
File.directory?(likefile_exists_in_dir?usesFile.exist?) for consistency, though functionally they're equivalent.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
.rubocop.yml(2 hunks)CONTRIBUTING.md(2 hunks)README.md(3 hunks)bin/apply-shared(1 hunks)bin/bootstrap-all(1 hunks)bin/test-all(1 hunks)docs/VERSION_MANAGEMENT.md(0 hunks)lib/demo_scripts.rb(1 hunks)lib/demo_scripts/command_executor.rb(1 hunks)lib/demo_scripts/demo_manager.rb(1 hunks)lib/demo_scripts/package_json_cache.rb(1 hunks)scripts/apply-shared.sh(0 hunks)scripts/bootstrap-all.sh(0 hunks)scripts/new-demo.sh(0 hunks)scripts/scaffold-demo.sh(0 hunks)scripts/test-all.sh(0 hunks)scripts/update-all-demos.sh(0 hunks)spec/demo_scripts/command_executor_spec.rb(1 hunks)spec/demo_scripts/demo_manager_spec.rb(1 hunks)spec/demo_scripts/package_json_cache_spec.rb(1 hunks)spec/examples.txt(1 hunks)
💤 Files with no reviewable changes (7)
- scripts/apply-shared.sh
- scripts/update-all-demos.sh
- scripts/bootstrap-all.sh
- scripts/scaffold-demo.sh
- scripts/new-demo.sh
- docs/VERSION_MANAGEMENT.md
- scripts/test-all.sh
🧰 Additional context used
🧬 Code graph analysis (4)
spec/demo_scripts/package_json_cache_spec.rb (1)
lib/demo_scripts/package_json_cache.rb (2)
read_package_json(8-21)clear_package_json_cache(32-34)
spec/demo_scripts/command_executor_spec.rb (2)
lib/demo_scripts/demo_manager.rb (2)
include(7-77)initialize(12-16)lib/demo_scripts/command_executor.rb (3)
run_command(10-27)command_exists?(30-32)capture_command(34-45)
lib/demo_scripts/demo_manager.rb (1)
spec/demo_scripts/command_executor_spec.rb (1)
initialize(14-17)
spec/demo_scripts/demo_manager_spec.rb (1)
lib/demo_scripts/demo_manager.rb (2)
each_demo(18-28)demo_name(30-32)
🔇 Additional comments (29)
.rubocop.yml (4)
17-17: LGTM! Comment updated to reflect bin scripts.The comment now accurately describes that bin scripts are also excluded from block length checks.
25-25: LGTM! bin/ exclusion added for BlockLength.*This aligns with the PR's goal to avoid linting executable scripts in bin/.
34-38: LGTM! ClassLength exclusion updated to include bin scripts.The change to a multi-line Exclude and inclusion of bin/* is consistent with the refactor.
10-15: Verify if AllCops should exclude bin/ globally.
Specific metrics now excludebin/*, but the AllCops Exclude (lines 10–15) lacks a globalbin/*exclusion. If you intend to exempt all bin scripts from every cop, add:AllCops: Exclude: - 'bin/*'Otherwise the per-cop exclusions are sufficient.
To confirm no other offenses in bin/, run locally:bundle exec rubocop bin/ --format offensesspec/examples.txt (1)
1-67: LGTM! RSpec examples updated with new test results.The new example set reflects the added specs for CommandExecutor, DemoManager, and PackageJsonCache. The single failure on line 63 (pre_flight_checks_spec) is expected per the PR's test plan.
bin/apply-shared (5)
1-28: LGTM! Class structure and apply! method are well-organized.The
SharedConfigAppliercorrectly inherits fromDemoManager, validates directories, and iterates over demos to apply configurations. The CONFIG_FILES constant clearly defines the symlink mappings.
30-49: LGTM! Symlink creation logic is robust.The method correctly checks for source file existence before creating symlinks, and delegates to
create_symlinkfor atomic operations.
51-61: LGTM! Atomic symlink creation with force.Using
force: trueinFileUtils.ln_sensures atomic updates and avoids race conditions.
75-92: LGTM! Gemfile addition and relative path calculation are sound.The logic for appending to the Gemfile and calculating relative paths is correct.
96-121: LGTM! Main execution and error handling are robust.Option parsing is clear, and the error handling correctly exits with status 1 on failure.
CONTRIBUTING.md (2)
35-35: LGTM! Bootstrap script reference updated.The documentation now correctly references
bin/bootstrap-allinstead of the old bash script.
70-70: LGTM! Test script reference updated.The documentation now correctly references
bin/test-allinstead of the old bash script.lib/demo_scripts.rb (1)
5-7: LGTM! New module requires added.The requires for
command_executor,package_json_cache, anddemo_managercorrectly load the new utility modules introduced in this PR.README.md (4)
72-72: LGTM! Bootstrap script reference updated.The README now correctly references
bin/bootstrap-all.
78-78: LGTM! Test script reference updated.The README now correctly references
bin/test-all.
154-167: LGTM! New bin/apply-shared documentation added.The section clearly documents the purpose, usage, and options for
bin/apply-shared, including dry-run and help flags.
184-184: LGTM! Example updated to use bin/new-demo.The version override example now correctly references
bin/new-demo.spec/demo_scripts/command_executor_spec.rb (1)
1-100: LGTM! Comprehensive test coverage for CommandExecutor.The spec thoroughly tests
run_command,command_exists?, andcapture_commandin both dry-run and execution modes, including error handling and verbose output. Test structure and assertions are sound.bin/bootstrap-all (4)
1-19: LGTM! Bootstrap orchestration is clear and well-structured.The
Bootstrapperclass inherits fromDemoManagerand thebootstrap!method clearly orchestrates bootstrapping for shared dependencies and each demo.
20-43: LGTM! Per-demo bootstrapping logic is sound.The methods correctly check for shared dependencies, iterate demos, and handle per-demo dependency installation and database setup.
45-64: LGTM! Dependency installation logic is robust.The script correctly checks for Ruby and JS dependencies, prefers pnpm if available, and allows database setup to fail gracefully (appropriate for idempotent operations like
db:prepare).
68-94: LGTM! Main execution and error handling are robust.Option parsing supports dry-run and verbose modes, and error handling correctly exits with status 1 on failure.
spec/demo_scripts/demo_manager_spec.rb (1)
1-157: Comprehensive test coverage with good structure.The test suite is well-organized and covers all major scenarios including initialization, demo enumeration, path extraction, and file existence checks. The use of stubbing for filesystem operations is appropriate for unit tests.
spec/demo_scripts/package_json_cache_spec.rb (1)
1-134: Thorough test coverage for caching behavior.The test suite comprehensively covers all aspects of the PackageJsonCache module including caching, per-directory isolation, error handling for invalid JSON, and the script existence checking functionality. The stubbing approach is appropriate and tests verify the expected warnings for parse errors.
lib/demo_scripts/package_json_cache.rb (2)
8-21: Well-designed caching with proper error handling.The implementation correctly uses lazy initialization and per-directory caching. The error handling gracefully falls back to an empty hash on parse errors while warning the user. The design is appropriate for the single-threaded script context.
8-34: Cache is not thread-safe.The
@package_json_cacheinstance variable is not thread-safe. While this is likely not an issue for the current single-threaded script usage, if these utilities are ever used in a multi-threaded context, race conditions could occur.If there are plans to use these utilities in concurrent scenarios, consider adding thread safety:
require 'thread' module DemoScripts module PackageJsonCache def read_package_json(dir = Dir.pwd) cache_mutex.synchronize do @package_json_cache ||= {} @package_json_cache[dir] ||= begin # ... existing implementation end end end private def cache_mutex @cache_mutex ||= Mutex.new end end endShould I verify if any of the bin scripts use threading or plan to in the future?
bin/test-all (2)
83-93: JavaScript tests silently ignored when they fail.Lines 86 and 92 run JavaScript tests and linting with
allow_failure: true, which means failures won't be tracked in@failed_testsor reported in the final summary. While this might be intentional to avoid blocking on JS test failures, it could mask real issues.Is it intentional that JavaScript test failures are not reported in the final test summary? This could make it easy to miss broken JS tests.
Consider either:
- Documenting this behavior with a comment explaining why JS test failures are allowed
- Reporting JS failures separately (e.g., with a warning) so they're visible but don't fail the build
- Making this configurable via a CLI flag
Should I check if this behavior is documented elsewhere or if there's a reason for allowing JS test failures?
120-147: Robust CLI option parsing and error handling.The option parser provides clear help text and appropriate flags. The error handling distinguishes between
DemoScripts::Error(expected errors) andStandardError(unexpected errors), providing appropriate exit codes and messages for each case.lib/demo_scripts/demo_manager.rb (1)
18-28: Well-designed enumeration with helpful feedback.The
each_demomethod properly returns anEnumeratorwhen no block is given, and provides a clear informational message when no demos are found. This is good Ruby practice and improves the user experience.
Pull Request Review: Replace bash scripts with Ruby equivalentsSummaryExcellent refactoring! This PR successfully replaces bash scripts with well-structured Ruby equivalents, improving maintainability, testability, and code quality. The implementation demonstrates strong software engineering practices with comprehensive tests and proper error handling. ✅ StrengthsCode Quality
Test Coverage
Documentation
Best Practices
🔍 Areas for Improvement1. Command Execution Security (Minor)Location: lib/demo_scripts/command_executor.rb:22 The use of Open3.capture2e(command) with string commands could potentially be unsafe if user input is ever interpolated into commands. While the current implementation appears safe, add a comment documenting that commands passed to run_command must be carefully constructed and never include unsanitized user input. 2. Gemfile Modification PatternLocation: bin/apply-shared:86 The current implementation appends to Gemfile which works, but could potentially result in odd formatting if the file doesn't end with a newline. Consider checking if the file ends with a newline first, though the current approach is simple and works well for this use case. 3. Package.json Caching ConcernsLocation: lib/demo_scripts/package_json_cache.rb:8-20 The cache is stored in an instance variable, which means it persists across multiple demo operations. If a demo's package.json changes during execution, the cache would return stale data. Impact: Low (unlikely to occur in normal usage) 4. Test Coverage Gaps (Minor)The following areas could benefit from additional tests:
Note: The shared modules are well-tested, so the risk is minimal, but adding script-level tests would improve confidence. 5. Error Message ClarityLocation: lib/demo_scripts/command_executor.rb:33 When a command fails, the error message only includes the command. Consider including the output/stderr in the error message to help with debugging. 🚀 Performance ConsiderationsPositive
Suggestions
🔒 Security Assessment✅ Security Improvements
|
- Remove babel.config.js (unused with SWC transpiler) - Add missing binstubs (bin/export-bundler-config) - Update shakapacker and shakapacker-dev-server binstubs This addresses warnings from Shakapacker's configuration validator: - Warning about unused Babel config when using SWC transpiler - Warning about missing export-bundler-config binstub Note: swc-loader removal (warning #5) requires package.json changes and should be handled separately. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Summary
/scriptswith Ruby equivalents in/binChanges
New Ruby Scripts Created
bin/apply-shared- Applies shared configurations to demos (symlinks, gem addition)bin/bootstrap-all- Installs dependencies and sets up databases for all demosbin/test-all- Runs tests across all demos (RSpec, RuboCop, JS tests)Scripts Removed
/scriptsdirectory containing redundant bash scripts:scripts/apply-shared.shscripts/bootstrap-all.shscripts/new-demo.shscripts/scaffold-demo.shscripts/test-all.shscripts/update-all-demos.shDocumentation Updates
CONTRIBUTING.mdto reference new Ruby scriptsREADME.mdwith new commands and addedbin/apply-shareddocumentationdocs/VERSION_MANAGEMENT.mdBenefits
--dry-run,--help, and other useful flagsTest Plan
--helpflag🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores
Tests