Skip to content

Conversation

justin808
Copy link
Member

@justin808 justin808 commented Oct 11, 2025

Summary

This PR adds detection for shakapacker precompile hooks to prevent running react_on_rails:generate_packs twice when shakapacker is configured to run it automatically.

Changes

  • New Method: Added PackerUtils.shakapacker_precompile_hook_configured? to detect if shakapacker.yml has a precompile hook that runs react_on_rails:generate_packs
  • Skip in assets:precompile: Updated configuration.rb to skip invoking react_on_rails:generate_packs if the shakapacker hook is configured
  • Skip in bin/dev: Updated PackGenerator.generate to skip pack generation if the shakapacker hook is configured
  • Comprehensive Tests: Added test coverage for all new functionality

Why This Matters

When shakapacker supports precompile hooks (upcoming feature), users can configure:

yaml

config/shakapacker.yml

hooks:
precompile: "bundle exec rake react_on_rails:generate_packs"

Without this PR, generate_packs would run twice:

  1. Once by shakapacker's precompile hook
  2. Once by react_on_rails during assets:precompile or bin/dev

This PR ensures it only runs once by detecting the hook configuration.

Test Plan

  • Added unit tests for PackerUtils.shakapacker_precompile_hook_configured?
  • Added tests for PackGenerator.generate with hook configured
  • All existing tests pass
  • RuboCop passes with no violations

🤖 Generated with Claude Code


This change is Reviewable

Summary by CodeRabbit

  • Bug Fixes

    • Assets precompile now conditionally skips internal pack generation when a Shakapacker precompile hook is configured.
    • Verbose mode reports the skip; quiet mode remains silent. Behavior is unchanged when no hook is present.
    • Results in cleaner output and more efficient precompiles.
  • Tests

    • Added comprehensive tests for detecting configured precompile hooks and the resulting pack generation behavior.
    • Covered verbose/quiet outputs, success/failure paths, and edge cases (missing configs and exceptions).

This change prevents react_on_rails from running generate_packs twice
when shakapacker has a precompile hook configured that already runs it.

Changes:
- Add PackerUtils.shakapacker_precompile_hook_configured? to detect hook
- Skip generate_packs in assets:precompile if hook is configured
- Skip generate_packs in bin/dev if hook is configured
- Add comprehensive test coverage for new behavior

This ensures generate_packs runs only once during both:
- Production asset precompilation (assets:precompile)
- Development server startup (bin/dev)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

coderabbitai bot commented Oct 11, 2025

Walkthrough

Adds detection of a Shakapacker precompile hook and conditionally skips invoking react_on_rails:generate_packs during precompile and in the dev PackGenerator. Introduces PackerUtils.shakapacker_precompile_hook_configured? and updates specs to cover both the new conditional flow and utility behavior.

Changes

Cohort / File(s) Summary
Precompile task wiring
lib/react_on_rails/configuration.rb
Wraps generate_packs invocation in precompile task with a conditional check to skip when a Shakapacker precompile hook is configured.
Dev pack generation flow
lib/react_on_rails/dev/pack_generator.rb
Adds early return to skip pack generation when a Shakapacker precompile hook is configured; logs a verbose skip message.
Shakapacker integration utilities
lib/react_on_rails/packer_utils.rb
Adds public method shakapacker_precompile_hook_configured? to detect presence of a precompile hook referencing react_on_rails:generate_packs; safe-fails to false on errors.
Tests: Pack generator
spec/react_on_rails/dev/pack_generator_spec.rb
Adds contexts for hook-configured vs not-configured: verifies skip behavior, messaging, quiet mode, and existing success/failure paths.
Tests: Packer utils
spec/react_on_rails/packer_utils_spec.rb
Adds tests for hook detection across positive, negative, and error cases; includes duplicate blocks covering similar scenarios.

Sequence Diagram(s)

sequenceDiagram
  actor Dev as Developer
  participant Rake as Rake Precompile
  participant ROR as ReactOnRails::Dev::PackGenerator
  participant PU as ReactOnRails::PackerUtils
  participant SP as Shakapacker

  Dev->>Rake: assets:precompile
  Rake->>ROR: generate packs (conditionally)
  ROR->>PU: shakapacker_precompile_hook_configured?
  PU->>SP: read shakapacker.yml (hooks.precompile)
  alt Hook references react_on_rails:generate_packs
    PU-->>ROR: true
    ROR-->>Rake: Skip generate_packs
  else No hook / not defined / error
    PU-->>ROR: false
    ROR-->>Rake: Invoke generate_packs
  end
  Rake->>SP: assets:webpack
  Rake->>SP: shakapacker:clean (if applicable)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

bug

Suggested reviewers

  • Judahmeek
  • alexeyr-ci
  • AbanoubGhadban

Poem

I twitch my whiskers at the build so sleek,
Skip the double-hop, one jump per tweak.
Hooks are checked, the packs don’t duplicate,
Carrots saved, our CI runs straight. 🥕
With gentle thumps, I ship and squeak—
Precompile paths now clean and chic.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely summarizes the primary change introduced by the pull request: skipping the generate_packs task when a Shakapacker precompile hook is configured. It matches the new conditional logic added to both the configuration and pack generation code. The phrasing is specific, uses an imperative tone, and avoids unnecessary detail or noise, making it easy for readers to grasp the intent at a glance. It accurately reflects the key behavior change without overcomplicating the description.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch check-precompile-hook

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abef267 and eb2e714.

📒 Files selected for processing (5)
  • lib/react_on_rails/configuration.rb (1 hunks)
  • lib/react_on_rails/dev/pack_generator.rb (1 hunks)
  • lib/react_on_rails/packer_utils.rb (1 hunks)
  • spec/react_on_rails/dev/pack_generator_spec.rb (1 hunks)
  • spec/react_on_rails/packer_utils_spec.rb (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}

📄 CodeRabbit inference engine (CLAUDE.md)

{Gemfile,Rakefile,config.ru,**/*.{rb,rake,gemspec,ru}}: All Ruby code must pass RuboCop with zero offenses before commit/push
RuboCop is the sole authority for Ruby file formatting; never manually format Ruby files

Files:

  • lib/react_on_rails/configuration.rb
  • lib/react_on_rails/packer_utils.rb
  • spec/react_on_rails/dev/pack_generator_spec.rb
  • spec/react_on_rails/packer_utils_spec.rb
  • lib/react_on_rails/dev/pack_generator.rb
🧬 Code graph analysis (5)
lib/react_on_rails/configuration.rb (1)
lib/react_on_rails/packer_utils.rb (1)
  • shakapacker_precompile_hook_configured? (168-180)
lib/react_on_rails/packer_utils.rb (1)
lib/react_on_rails/engine.rb (1)
  • config (6-17)
spec/react_on_rails/dev/pack_generator_spec.rb (1)
lib/react_on_rails/dev/pack_generator.rb (2)
  • generate (7-31)
  • generate (9-29)
spec/react_on_rails/packer_utils_spec.rb (1)
lib/react_on_rails/packer_utils.rb (1)
  • shakapacker_precompile_hook_configured? (168-180)
lib/react_on_rails/dev/pack_generator.rb (1)
lib/react_on_rails/packer_utils.rb (1)
  • shakapacker_precompile_hook_configured? (168-180)
⏰ 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). (4)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.2, 20)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22)
  • GitHub Check: claude-review
  • GitHub Check: build-and-test
🔇 Additional comments (7)
lib/react_on_rails/configuration.rb (1)

250-253: LGTM! Clean conditional guard.

The conditional wrapper around react_on_rails:generate_packs invocation is implemented correctly and prevents duplicate execution when a shakapacker precompile hook is configured. The other precompile steps (webpack and clean) remain unchanged, which is the intended behavior.

lib/react_on_rails/dev/pack_generator.rb (1)

10-14: LGTM! Clear early-exit with helpful messaging.

The early-exit guard is implemented correctly and provides a clear verbose message explaining why pack generation is being skipped. The emoji prefix (⏭️) is consistent with the existing style in this file (📦, ✅, ❌).

spec/react_on_rails/packer_utils_spec.rb (1)

143-207: LGTM! Comprehensive test coverage.

The test suite thoroughly covers all branches and edge cases of the new shakapacker_precompile_hook_configured? method:

  • ✅ Shakapacker not defined
  • ✅ Single hook string containing generate_packs
  • ✅ Array of hooks with generate_packs
  • ✅ Hooks without generate_packs
  • ✅ Nil/missing hooks
  • ✅ Exception handling

The tests are well-structured and use proper RSpec conventions.

spec/react_on_rails/dev/pack_generator_spec.rb (3)

8-10: LGTM! Smart default setup.

Setting shakapacker_precompile_hook_configured? to return false by default in the outer before block ensures tests run in the not-configured state unless explicitly overridden. This is a clean approach that makes the test structure more maintainable.


12-27: LGTM! Thorough testing of skip behavior.

The tests correctly verify that when the hook is configured:

  • Verbose mode outputs the skip message with the appropriate emoji (⏭️)
  • Quiet mode produces no output

This covers both user experience scenarios effectively.


29-52: LGTM! Complete coverage of normal flow.

The tests thoroughly verify the not-configured scenario:

  • ✅ Verbose mode with success
  • ✅ Quiet mode with success (including emoji output)
  • ✅ Failure handling with SystemExit

The test structure clearly separates the two execution paths (configured vs not configured) and validates all relevant outcomes.

lib/react_on_rails/packer_utils.rb (1)

165-180: Verify Shakapacker’s public hooks API
In a Rails console or by reviewing the Shakapacker gem source, confirm if Shakapacker.config exposes a public method for hook configuration (e.g., config.hooks, config.precompile_hooks). For example:

Shakapacker.config.public_methods.grep(/hooks?/)

If no such API is available, continuing to use send(:data) with a rescue remains the safest approach.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai bot added the bug label Oct 11, 2025
Copy link

claude bot commented Oct 11, 2025

Code Review for PR #1861

Thanks for this well-structured PR! The implementation is solid and follows good practices. Here's my detailed review:

Strengths

  1. Well-Motivated Change: Clear justification for preventing duplicate generate_packs execution when shakapacker hooks are configured
  2. Comprehensive Test Coverage: Excellent test coverage including edge cases (nil hooks, errors, arrays vs strings)
  3. Defensive Programming: Good use of rescue StandardError with safe fallback to false
  4. Consistent Implementation: Applied the check in both precompile task and bin/dev contexts
  5. User Experience: Helpful verbose output message when skipping ("⏭️ Skipping pack generation...")

📝 Code Quality Observations

1. Use of .send(:data) - Minor Concern (packer_utils.rb:171)

The code uses .send(:data) to access a private method. This accesses a private API, which could break if shakapacker changes its internal structure. However, I notice this pattern is already used elsewhere in the file (packer_utils.rb:109), so it's consistent with existing code.

Recommendation: This is acceptable given the rescue StandardError safety net, but consider:

  • Adding a comment explaining why private API access is necessary
  • Or reaching out to shakapacker maintainers to expose a public API for hook inspection

2. String Matching Approach (packer_utils.rb:177)

The detection uses string inclusion which could theoretically match false positives (e.g., comments or echo statements containing that string).

Assessment: This is fine because:

  • The likelihood of false positives is very low in practice
  • A false positive (not running generate_packs when it should) would be caught immediately in development
  • It's better to err on the side of not running twice

🔒 Security

No security concerns identified. The code:

  • Doesn't execute user input
  • Safely handles errors with a fallback
  • Uses read-only operations on configuration

Performance

Excellent performance characteristics:

  • Prevents duplicate work (the main goal)
  • Minimal overhead: one config read with early returns
  • Proper memoization isn't needed as this check happens once per process

🧪 Test Coverage

Outstanding test coverage! Tests include:

  • ✅ Hook present/absent scenarios
  • ✅ Single hook vs array of hooks
  • ✅ Error handling
  • ✅ Shakapacker not defined
  • ✅ Integration with PackGenerator.generate

🎯 Suggestions for Consideration

  1. Add Explanatory Comment: Consider adding a brief comment explaining the private API usage

  2. Optional: More Specific Pattern Matching: If you want to be more precise, you could use a regex with word boundaries, but the current implementation is perfectly acceptable

  3. Documentation: Consider adding a note to the main README or documentation about this feature once shakapacker officially supports precompile hooks

📋 Checklist

  • ✅ Code quality: Excellent
  • ✅ Test coverage: Comprehensive
  • ✅ Performance: Optimal
  • ✅ Security: No concerns
  • ✅ Best practices: Follows project conventions
  • ✅ Error handling: Robust
  • ✅ Documentation: PR description is clear

🎉 Final Verdict

This PR is ready to merge! The implementation is clean, well-tested, and solves a real problem. The minor observations above are optional improvements, not blockers.

Great work on the comprehensive test coverage and clear PR description! 🚀


Review generated with Claude Code

Copy link

claude bot commented Oct 12, 2025

Code Review - PR #1861: Skip generate_packs when shakapacker precompile hook configured

Overall Assessment

Status: Approved with minor suggestions

This is a well-crafted PR that solves a real problem (duplicate pack generation) with a clean, testable solution. The code quality is excellent, and the test coverage is comprehensive.


Strengths

1. Excellent Problem Definition

  • Clear documentation of the issue (duplicate pack generation)
  • Well-explained rationale for the change
  • Good forward compatibility planning for upcoming shakapacker features

2. Clean Implementation

  • PackerUtils.shakapacker_precompile_hook_configured? is well-isolated and reusable
  • Proper error handling with rescue StandardError returning false
  • Consistent application across both precompile and bin/dev workflows

3. Comprehensive Test Coverage

  • Tests cover all edge cases (missing config, exceptions, different hook formats)
  • Both verbose and quiet mode behaviors tested
  • Mock usage is appropriate and follows RSpec best practices

4. Code Style

  • Follows project conventions (frozen_string_literal, RuboCop compliant)
  • Good use of early returns for readability
  • Helpful inline comments explaining the logic

Suggestions for Improvement

1. Configuration Caching (Minor Performance)

lib/react_on_rails/packer_utils.rb:168

Consider caching the hook check since config does not change at runtime. This method may be called multiple times during precompile, and caching would avoid repeated YAML parsing.

However, this is optional - the current implementation is fine for most use cases. Caching adds complexity and makes testing slightly harder. Only worth it if performance profiling shows it is a bottleneck.

2. String Matching Robustness (Low Risk)

lib/react_on_rails/packer_utils.rb:177

Current implementation uses simple .include? check which could theoretically match strings like "not_react_on_rails:generate_packs" (unlikely but possible). A regex with word boundary would be more precise:

Array(hooks).any? { |hook| hook.to_s.match?(/react_on_rails:generate_packs(?:\s|$)/) }

Verdict: Current implementation is probably fine given the context, but worth considering.

3. Logging Consistency (Minor UX)

lib/react_on_rails/configuration.rb:250-253

The precompile task silently skips without any log output. Consider adding logging to help users understand why pack generation was skipped during debugging.


Security Considerations

No security concerns identified:

  • No user input is processed
  • YAML parsing is done through Shakapacker's existing config loader
  • Proper exception handling prevents information leakage

Performance Considerations

Performance impact is minimal:

  • New check adds negligible overhead (one YAML access via existing config)
  • Early returns prevent unnecessary work when hook is configured
  • Overall performance improves by eliminating duplicate pack generation

Potential Issues

1. Edge Case: Multiple Hooks with Mixed Content

The current implementation correctly handles arrays of hooks. Tests cover this - good!

2. Shakapacker Version Compatibility

The PR assumes ::Shakapacker.config.send(:data) is available. This is a private method call (using send), which could break in future versions.

Risk Level: Low (Shakapacker maintains good backward compatibility)
Mitigation: Already handled with rescue StandardError - gracefully degrades to false


Test Coverage Analysis

Excellent test coverage. Tests cover:

  • Hook configured (single string)
  • Hook configured (array of strings)
  • Hook not configured (different task)
  • Missing hooks config
  • Shakapacker not defined
  • Exception handling
  • Verbose vs quiet mode behavior
  • Integration with PackGenerator

Suggestion: Consider adding one test for empty string hook to ensure robustness.


Documentation

Good documentation in PR description.

Consider adding:

  1. Inline documentation for the new method (RDoc/YARD comments)
  2. User-facing documentation about configuring shakapacker hooks (if not already documented)

Conclusion

This PR demonstrates excellent software engineering practices:

  • Clear problem statement
  • Minimal, focused solution
  • Comprehensive tests
  • Proper error handling
  • Follows project conventions

Recommendation: Merge after considering the minor suggestions above.

The suggestions are optional improvements - the PR is production-ready as-is.


Checklist Verification

From CLAUDE.md requirements:

  • RuboCop compliance (per PR description)
  • Test coverage added
  • Files end with newlines (based on diff)
  • Follows project conventions

Great work!

Copy link

claude bot commented Oct 12, 2025

Code Review - PR #1861: Skip generate_packs when shakapacker precompile hook configured

Overall Assessment

This is a well-implemented PR that solves a real problem (duplicate pack generation) with clean, defensive code. The implementation follows best practices and has comprehensive test coverage.

Strengths

1. Excellent Problem Solution

  • Addresses duplicate generate_packs execution when shakapacker hooks are configured
  • Clean detection mechanism using YAML configuration parsing
  • Prevents unnecessary work and potential race conditions

2. Defensive Programming

  • Proper guard clauses checking for ::Shakapacker constant existence
  • Rescue block catches exceptions and safely returns false
  • Handles both single hook strings and arrays of hooks
  • Graceful degradation if detection fails

3. Comprehensive Test Coverage

  • Tests cover all edge cases: Shakapacker not defined, hook configured (single and array), hook not configured, missing config sections, exception handling
  • Both verbose and quiet modes tested
  • Integration with existing test suite

4. Code Quality

  • Follows Ruby idioms (Array(hooks).any?)
  • Good error handling with StandardError rescue
  • Clear, self-documenting method names
  • Consistent with existing codebase patterns

Minor Observations

1. YAML Structure Assumptions
The code assumes string keys in YAML. If shakapacker uses symbol keys, dig("hooks", "precompile") might not work. Already mitigated via rescue block.

2. String Matching Precision
hook.to_s.include?("react_on_rails:generate_packs") would match edge cases like comments. Very low risk in practice.

3. Performance
Calls ::Shakapacker.config.send(:data) on every invocation, but only happens during asset precompilation and bin/dev startup, so impact is negligible.

Test Coverage Analysis

Excellent coverage across all scenarios with tests for: hook configured (single/array), hook not configured, Shakapacker undefined, exception handling, and integration tests.

Security Considerations

No security concerns identified:

  • Read-only configuration access
  • No user input processing
  • No code execution based on config values
  • Proper exception handling prevents information leakage

Recommendations (Optional)

  1. Consider caching the result (very low priority) - only beneficial if called multiple times
  2. Add log message when skipping in configuration.rb for debugging
  3. Add documentation comment showing exact hook format expected

Final Verdict

LGTM - Approve with Confidence

This PR is production-ready. The implementation is safe (defensive coding with proper error handling), well-tested (comprehensive coverage), maintainable (clean, readable code), and backwards compatible (gracefully degrades if detection fails).

The minor observations above are truly minor and do not warrant blocking this PR. Great work!


Review generated by Claude Code - focusing on defensive security, code quality, and best practices

Copy link

claude bot commented Oct 12, 2025

PR Review: Skip generate_packs when shakapacker precompile hook configured

Overall Assessment

This is a well-implemented PR that solves a real problem (duplicate pack generation) with a clean, defensive approach. The code quality is high, test coverage is comprehensive, and the implementation follows the repository conventions.

Strengths

  1. Problem-Solution Alignment: Correctly identifies and solves the duplicate execution issue
  2. Defensive Programming: Handles edge cases properly (Shakapacker not defined, StandardError rescue, both string and array hooks)
  3. Comprehensive Test Coverage: All critical paths covered including hook configured vs not, verbose vs quiet modes, error handling
  4. Non-Breaking: Backward compatible, only affects behavior when new shakapacker hook is configured

Code Quality

The new shakapacker_precompile_hook_configured? method (lib/react_on_rails/packer_utils.rb:167-183) is well-structured with early returns, safe navigation with dig, and Array() wrapper for flexible input handling.

Minor consideration: Using .send(:data) to access private data is slightly fragile, but acceptable given graceful failure handling and consistency with line 109.

Testing

Excellent coverage in packer_utils_spec.rb and pack_generator_spec.rb covering all scenarios including edge cases and error handling.

Performance & Security

No concerns - configuration checks are infrequent, no user input execution, proper exception handling.

Potential Issues

  1. Partial String Matching (Low Severity): Uses .include? which could match comments or echoed strings. Consider regex with word boundaries for precision. Impact is low since false positives just skip generation that would run via hook anyway.

  2. Documentation: Could add YARD docs and migration guide for users.

Recommendations

Required: None - ready to merge

Optional:

  • More precise regex matching with word boundaries
  • Add YARD documentation
  • Consider logging in configuration.rb when skipping

Final Verdict

Approved

Solid PR that solves the problem elegantly with excellent test coverage, follows conventions, introduces no breaking changes, and handles edge cases defensively.

Great work!


Review generated with assistance from Claude Code

Copy link

claude bot commented Oct 12, 2025

Code Review for PR #1861: Skip generate_packs when shakapacker precompile hook configured

✅ Overall Assessment

This is a well-implemented PR that solves a real problem with clear intention and good test coverage. The changes are focused, defensive, and follow the repository's coding standards.


🎯 Strengths

1. Clear Problem Statement & Solution

  • The PR addresses a legitimate issue: duplicate execution of generate_packs when shakapacker hooks are configured
  • The solution is elegant and minimally invasive

2. Excellent Test Coverage

  • Comprehensive test suite covering hook configured vs not configured scenarios, verbose and quiet modes, error handling, and edge cases
  • Tests are well-structured with proper context blocks

3. Defensive Error Handling

  • The rescue StandardError ensures graceful degradation
  • Returns false on errors, which is the safe default

4. Good User Experience

  • Verbose mode provides clear skip message with emoji for visibility
  • Quiet mode remains truly quiet when skipping

🔍 Potential Issues & Suggestions

1. String Matching Could Be More Robust (Minor)

The current string matching uses include? which could have false positives with comments. Consider using regex with word boundaries for more precise matching.

2. Missing Logging in Configuration.rb (Minor)

In lib/react_on_rails/configuration.rb:247-253, the skip happens silently. Consider adding logging when skipping for consistency with pack_generator.rb.

3. Method Uses Private API (Minor Security/Stability)

The method accesses Shakapacker's private API via .send(:data). Consider:

  • Adding a comment documenting why private API access is necessary
  • Requesting a public API from Shakapacker maintainers

🧪 Test Coverage: Excellent ✅

Comprehensive coverage including hook configured/not configured, verbose/quiet modes, error handling, and edge cases. No additional tests needed.


🔒 Security: No Concerns ✅

Code only reads configuration, has proper error handling, no injection vulnerabilities, and fails safely.


⚡ Performance: No Concerns ✅

Runs once per precompile with simple hash lookups and string checks.


🎬 Recommendations

Before merging:

  1. Optional: Add regex word boundaries for more precise matching
  2. Optional: Add logging in configuration.rb
  3. Recommended: Add comment explaining private API usage
  4. Required: Ensure bundle exec rubocop passes per CLAUDE.md

💬 Final Verdict

✅ APPROVED with minor suggestions. The PR is ready to merge after ensuring RuboCop passes. Great work identifying this edge case and implementing a clean solution! 🎉


Review generated with Claude Code following repository standards from CLAUDE.md

Copy link

claude bot commented Oct 12, 2025

Code Review Summary

I've reviewed PR #1861 and overall this is a well-implemented feature with excellent test coverage. Here's my detailed feedback:


✅ Strengths

1. Clean Design & Implementation

  • The new PackerUtils.shakapacker_precompile_hook_configured? method has a clear, single responsibility
  • Proper use of early returns for better readability
  • Good defensive programming with rescue StandardError fallback

2. Excellent Test Coverage

  • Comprehensive test cases covering all edge cases:
    • Hook configured vs not configured scenarios
    • Single hook string vs array of hooks
    • Missing config data
    • Exception handling
  • Tests for both verbose and quiet output modes
  • Good use of mocking to isolate behavior

3. User Experience

  • Informative verbose output: "⏭️ Skipping pack generation (handled by shakapacker precompile hook)"
  • Silent behavior in quiet mode (appropriate)
  • Prevents unnecessary duplicate work

4. Code Quality

  • Follows Ruby conventions and style
  • Proper use of dig for safe hash navigation
  • Array(hooks) idiom handles both string and array cases elegantly

🔍 Observations & Minor Suggestions

1. Error Handling Scope

The rescue StandardError in shakapacker_precompile_hook_configured? is appropriate, but consider logging a warning when an exception occurs (at least in verbose/debug mode). This would help users diagnose configuration issues.

Current:

rescue StandardError
  false
end

Suggestion (optional):

rescue StandardError => e
  ReactOnRails.logger.debug("Unable to check shakapacker precompile hook: #{e.message}") if ReactOnRails.logger
  false
end

2. Magic String

The string "react_on_rails:generate_packs" appears in multiple places. Consider extracting to a constant for maintainability:

GENERATE_PACKS_TASK = "react_on_rails:generate_packs".freeze

3. Documentation

Consider adding a brief comment or YARD documentation explaining:

  • What the shakapacker precompile hook feature is
  • Why detection is necessary (preventing duplicate runs)
  • When this returns true/false

Example:

# Detects if shakapacker.yml has configured a precompile hook that runs generate_packs.
# This prevents duplicate execution when both shakapacker and react_on_rails
# would otherwise invoke the same rake task during asset precompilation.
#
# @return [Boolean] true if hook is configured, false otherwise
def self.shakapacker_precompile_hook_configured?

4. Method Naming

While shakapacker_precompile_hook_configured? is descriptive, it's quite long. Consider alternatives like:

  • generate_packs_hook_configured?
  • delegating_to_shakapacker_hook?

(This is subjective - current name is clear and acceptable)


🎯 Specific Code Review Notes

lib/react_on_rails/packer_utils.rb:162-180

Positive:

  • Safe navigation with dig
  • Handles both string and array hook configurations
  • Good use of Array() for normalization

Question: Should the match be more strict? Currently uses .include? which would match:

  • "react_on_rails:generate_packs"
  • "react_on_rails:generate_packs_for_something_else" ✓ (possibly unintended?)

Consider using a more precise match if needed, though .include? is likely fine for this use case.

lib/react_on_rails/configuration.rb:250-253

Positive:

  • Clean conditional logic
  • Preserves existing functionality when hook not configured
  • Inline comment explains the skip

Minor: The blank line after the conditional (line 253) might not be necessary but doesn't hurt readability.

lib/react_on_rails/dev/pack_generator.rb:10-13

Positive:

  • Early return pattern keeps the method clean
  • Consistent with the skip logic elsewhere

Suggestion: The verbose message could optionally include a hint about where the hook is configured:

puts "⏭️  Skipping pack generation (configured in shakapacker.yml precompile hook)" if verbose

Test Coverage (spec/ files)

Excellent:

  • All new code paths are tested
  • Edge cases covered (nil, errors, arrays, strings)
  • Proper use of RSpec context blocks for organization
  • Good mocking strategy

🔐 Security Considerations

No security concerns identified

  • No user input is processed
  • No file system operations beyond reading existing config
  • Safe error handling prevents information leakage

⚡ Performance Considerations

Negligible performance impact

  • Check only runs during precompile/dev startup (not hot path)
  • Single YAML config read (already loaded by shakapacker)
  • String matching is trivial operation

📋 Testing Recommendations

The test coverage is excellent. Before merging, ensure:

  • All RuboCop violations are fixed (bundle exec rubocop)
  • All files end with newlines
  • Integration test with actual shakapacker.yml configuration (if not already covered in examples)

🎉 Overall Assessment

Rating: ✨ Excellent

This PR demonstrates:

  • Strong understanding of the codebase
  • Good software engineering practices
  • Thorough testing
  • Clear documentation in the PR description

The implementation solves the duplicate execution problem elegantly and safely. The code is production-ready with only minor optional improvements suggested above.

Recommendation: APPROVE ✅ (pending RuboCop/CI checks)


Review generated with attention to the project's CLAUDE.md guidelines

Copy link

claude bot commented Oct 12, 2025

Code Review - PR #1861: Skip generate_packs when shakapacker precompile hook configured

Summary

This PR adds intelligent detection for shakapacker precompile hooks to prevent duplicate execution of react_on_rails:generate_packs. The implementation is well-thought-out and addresses a real issue that will arise with upcoming shakapacker features.


Strengths

1. Clean Architecture

  • The new PackerUtils.shakapacker_precompile_hook_configured? method is properly scoped and follows single responsibility principle
  • Early returns in both PackGenerator.generate and Configuration#adjust_precompile_task keep code readable
  • Graceful degradation with rescue StandardError ensures robustness

2. Comprehensive Test Coverage

  • Excellent test coverage across all scenarios (packer_utils_spec.rb and pack_generator_spec.rb)
  • Tests cover edge cases: missing configs, exceptions, single/array hooks
  • Tests verify both verbose and quiet modes appropriately

3. User Experience

  • Clear skip message in verbose mode
  • Silent skip in quiet mode is appropriate
  • Maintains existing behavior when hook is not configured

Observations & Suggestions

1. Documentation Opportunity
The shakapacker_precompile_hook_configured? method would benefit from a comment explaining:

  • The expected format of shakapacker.yml hooks configuration
  • Example YAML structure that would return true
  • Why send(:data) is used instead of a public API

2. Configuration Access Pattern (lib/react_on_rails/packer_utils.rb:171)
Using send(:data) to access private methods is a code smell, though it's consistent with packer_source_path_explicit? on line 109. Consider:

  • Filing an issue with shakapacker to expose this as a public API
  • Adding a comment explaining why private access is necessary

3. Hook Detection Specificity
The current implementation uses .include?("react_on_rails:generate_packs"). This is practical and likely sufficient. Could use word boundaries for more specificity, but current approach is pragmatic.


Security

No security concerns. The code reads configuration but doesn't execute arbitrary commands or expose sensitive data.


Performance

Minimal performance impact:

  • Hook detection runs once during precompile/startup
  • File reading is already happening via Shakapacker.config
  • Early returns prevent unnecessary work

Potential Issues

None identified. The implementation is solid with proper error handling.


Overall Assessment

Rating: Excellent

This PR demonstrates strong software engineering practices:

  • Solves a real problem proactively
  • Maintains backward compatibility
  • Comprehensive test coverage
  • Clean, readable code
  • Good error handling

Minor improvements suggested:

  1. Add documentation comments to the new method
  2. Consider filing an issue with shakapacker about public API access
  3. Optional: Add integration test for completeness

Recommendation: Approve and merge after considering the documentation suggestions.


Checklist Compliance (per CLAUDE.md)

  • RuboCop: Need to verify bundle exec rubocop passes (mentioned in PR description)
  • Files should end with newline: Diff shows proper newline characters
  • Test coverage: Excellent
  • Code follows project conventions

Great work!

Copy link

claude bot commented Oct 13, 2025

Code Review for PR #1861: Skip generate_packs when shakapacker precompile hook configured

Overall Assessment

This is a well-implemented PR that solves a real problem: preventing duplicate execution of react_on_rails:generate_packs when shakapacker's precompile hook is configured. The implementation is clean, well-tested, and follows the project's conventions.

Strengths

  1. Clear Problem & Solution: The PR clearly identifies and solves the double-execution issue
  2. Comprehensive Test Coverage: Excellent test coverage with multiple scenarios including edge cases
  3. Error Handling: Proper rescue clause in shakapacker_precompile_hook_configured? prevents crashes
  4. User Experience: Appropriate verbose/quiet mode handling with helpful messaging
  5. Non-Breaking: Changes are backward compatible and gracefully handle missing configurations
  6. Code Style: Follows Ruby best practices and project conventions

Code Quality Observations

Excellent Patterns:

  1. Defensive Programming (packer_utils.rb:178-179): Returns false on any error, ensuring the system doesn't break if Shakapacker config is malformed.

  2. Flexible Input Handling (packer_utils.rb:177): Handles both single hooks and arrays elegantly with Array(hooks).any?

  3. Early Return Pattern (pack_generator.rb:10-13): Clean early return improves readability.

Copy link

claude bot commented Oct 13, 2025

Potential Improvements

1. String Matching Could Be More Robust (packer_utils.rb:177)

Current code uses .include? which would match false positives like comments or echo statements.

Suggestion: Consider a more precise regex match with word boundaries to reduce false positives.

2. Configuration Access Pattern (packer_utils.rb:172)

Using send(:data) to access a private method suggests this might be brittle if Shakapacker changes its internal API.

Suggestions:

  • Check if Shakapacker exposes a public API for accessing hooks
  • Consider adding a comment explaining why private method access is necessary
  • If this is an upstream limitation, consider proposing a public API to Shakapacker maintainers

3. Missing Configuration Example in Tests

The tests mock the configuration but don't show what real shakapacker.yml would look like. Consider adding a comment in the test file showing the actual YAML structure users would write.

Copy link

claude bot commented Oct 13, 2025

Test Coverage Analysis

Excellent coverage:

  • Shakapacker undefined
  • Single hook string
  • Array of hooks
  • Different hooks (no match)
  • Missing hooks section
  • Nil precompile hook
  • Exception handling
  • Verbose/quiet modes in PackGenerator
  • Success/failure paths

Potential additions (optional, low priority):

  • Edge case: Empty string hook
  • Edge case: Hook with extra whitespace

Security & Performance

Security: No concerns identified. The code doesn't execute user input, only reads configuration, and fails safely with rescue StandardError.

Performance: Negligible impact. Config read is cached by Shakapacker, string check is O(n) where n = number of hooks (typically 1-3), and only runs during precompile/dev startup (not request path).

Copy link

claude bot commented Oct 13, 2025

Pre-Merge Checklist

Before merging, please verify:

  • bundle exec rubocop passes with zero violations
  • All files end with newline character
  • Full test suite passes (rake)
  • Manual test: Verify behavior with actual shakapacker.yml configuration
  • Documentation: Consider updating docs to mention this feature

Recommendation

APPROVED with suggestion to consider the string matching improvement.

This is production-ready code. The potential improvements mentioned are enhancements, not blockers. The current implementation is safe, well-tested, and solves the problem effectively.

Great work! 🎉


Review completed by Claude Code

Copy link

claude bot commented Oct 13, 2025

Pull Request Review

This PR successfully addresses the issue of duplicate pack generation when shakapacker precompile hooks are configured. The implementation is well-thought-out and follows good defensive programming practices.

Strengths

  1. Code Quality: Clean separation of concerns with the new shakapacker_precompile_hook_configured? method properly placed in PackerUtils module. Excellent use of early returns and safe error handling.

  2. Test Coverage: Comprehensive test coverage including edge cases like missing Shakapacker constant, single/array hooks, missing configs, and error handling.

  3. User Experience: Clear messaging in verbose mode, silent in quiet mode, and non-intrusive for users without hooks configured.

  4. Backward Compatibility: No breaking changes, defaults to existing behavior when hook not configured.

Recommendations (Minor/Optional)

  1. String Matching: The .include? check could match false positives like comments. Consider using word boundaries for more robust matching, though this is a very minor edge case.

  2. Documentation: Add method documentation with params, return values, and examples.

  3. Private Method Access: Add a comment explaining why send(:data) is needed to access private methods.

  4. Performance: Consider caching the result since shakapacker.yml doesn't change at runtime (not critical).

  5. Test Gap: Add test for false positive case where task name appears in different context.

Security & Performance

  • No security concerns identified
  • Minimal performance impact (only called during precompile/startup)

Pre-Merge Checklist

  • Ensure bundle exec rubocop passes with zero violations (per CLAUDE.md)
  • Ensure all files end with newline (per CLAUDE.md)
  • Verify rake run_rspec passes
  • Manual testing with actual shakapacker hook configured

Final Verdict

APPROVE with minor suggestions

The core logic is sound, well-tested, and solves the problem effectively. All suggestions are optional enhancements. Ready to merge after mandatory lint checks pass.

Copy link

claude bot commented Oct 13, 2025

Code Review - PR #1861

I've reviewed the code changes and here's my comprehensive feedback:

Strengths

Code Quality & Best Practices

  • Clean implementation following Ruby conventions
  • Good use of early returns and guard clauses
  • Consistent style following RuboCop standards
  • Descriptive method names
  • Proper exception handling

Test Coverage

  • Comprehensive test suite covering edge cases
  • Well-organized with clear context blocks
  • Proper use of mocks and stubs

Performance & Security

  • Minimal performance impact (only runs during precompile/startup)
  • No security concerns
  • Safe error handling

Suggestions for Improvement

1. Private Method Access (packer_utils.rb:169)
Using send(:data) creates tight coupling to Shakapacker internals. Consider adding a comment explaining this is necessary until Shakapacker provides a public API.

2. String Matching Precision (packer_utils.rb:177)
Current substring matching could match false positives. Consider using word boundaries with match? and regex pattern.

3. Logging Enhancement
Consider adding Rails.logger.debug for quiet mode debugging.

4. Documentation
Add YARD documentation explaining purpose, return value, and examples.


Final Verdict: APPROVE with minor suggestions

Well-implemented PR solving a real problem. Code is clean, well-tested, and follows conventions. Suggestions are minor improvements, not blockers.

Critical requirements met:

  • RuboCop passes
  • Comprehensive tests
  • Files end with newlines
  • Clean, maintainable code

Nice work!

Copy link

claude bot commented Oct 13, 2025

Code Review

Summary

This PR implements a clean solution to prevent duplicate execution of react_on_rails:generate_packs when Shakapacker precompile hooks are configured. The implementation is well-tested and follows good Ruby practices.

✅ Strengths

1. Code Quality

  • Clean separation of concerns: detection logic in PackerUtils, usage in Configuration and PackGenerator
  • Defensive programming with proper exception handling (rescue StandardError returning false)
  • Good use of Ruby idioms (Array(hooks).any?, dig, early returns)
  • Follows repository conventions (frozen_string_literal, proper indentation)

2. Test Coverage

  • Comprehensive test suite covering all scenarios: hook configured vs not configured, verbose vs quiet modes, single hook vs array of hooks, edge cases (missing config, exceptions), success and failure paths
  • Tests properly use mocking to avoid external dependencies

3. User Experience

  • Clear, informative messages with emoji for visual clarity
  • Respects verbose/quiet modes appropriately
  • Skip message only shown in verbose mode (clean output by default)

🔍 Observations & Suggestions

1. String Matching Robustness (packer_utils.rb:177)

The current implementation uses include? to detect the rake task. This could match false positives like echo "react_on_rails:generate_packs disabled" or comments containing the string.

Suggestion: Consider using word boundaries: hook.to_s.match?(/\breact_on_rails:generate_packs\b/)

However, this might be over-engineering for a low-risk scenario. The current implementation is likely fine given that users would need to explicitly configure this, false positives would just skip an unnecessary task (safe failure mode), and the simple approach is more maintainable.

2. Configuration Access (packer_utils.rb:172)

Using send(:data) accesses a private API. If Shakapacker later changes this internal structure, the code will gracefully fail (returns false).

Suggestion: Consider adding a comment explaining this is accessing internal API and why it is safe.

3. Performance (Minor)

The method shakapacker_precompile_hook_configured? is called on every bin/dev run and during assets:precompile. Could consider memoization, though this is likely premature optimization since it is only called a few times per process and the operation is very fast.

🎯 Best Practices Applied

✅ DRY: Single source of truth for detection logic
✅ Defensive coding: Graceful handling of missing constants/errors
✅ Test coverage: Excellent coverage with edge cases
✅ User feedback: Clear messaging in appropriate verbosity levels
✅ Backward compatibility: No breaking changes, safe defaults
✅ Documentation: Clear PR description and code comments where needed

🔒 Security Considerations

✅ No security concerns identified

  • No user input is directly executed
  • Config parsing is read-only
  • Exception handling prevents information leakage

🚀 Performance Considerations

✅ Minimal performance impact

  • O(n) where n = number of precompile hooks (typically 0-2)
  • No file I/O beyond existing Shakapacker config loading
  • Prevents duplicate work (improves overall performance)

✅ Ready to Merge

This PR is well-implemented, thoroughly tested, and solves a real problem elegantly. The minor suggestions above are optional refinements rather than blockers.

Recommendation:Approve and merge

Great work on this feature! The detection mechanism is clever and the implementation is robust.

Copy link

claude bot commented Oct 13, 2025

Code Review: PR #1861 - Skip generate_packs when shakapacker precompile hook configured

✅ Overall Assessment

This is a well-implemented PR that solves a real problem (duplicate pack generation) with a clean, defensive approach. The code quality is high, tests are comprehensive, and the implementation follows best practices.


🎯 Strengths

1. Problem-Solution Fit

  • Clearly addresses the duplicate execution issue when shakapacker precompile hooks are configured
  • Smart detection mechanism that works proactively to prevent issues

2. Code Quality

  • Clean, readable implementation with appropriate error handling
  • Follows existing codebase patterns and conventions
  • Proper use of frozen_string_literal: true
  • Good defensive programming with the rescue clause in shakapacker_precompile_hook_configured?

3. Test Coverage

  • Excellent test coverage with 66 new lines in packer_utils_spec.rb
  • Tests cover all edge cases: missing config, nil values, arrays, exceptions
  • Both verbose and quiet modes tested in pack_generator_spec.rb
  • Tests properly isolate behavior with mocks

4. Documentation

  • Excellent PR description with clear motivation and examples
  • Inline comments explain the "why" (preventing duplicate runs)
  • User-facing messages are clear and helpful

🔍 Code Analysis

lib/react_on_rails/packer_utils.rb:165-183

The new shakapacker_precompile_hook_configured? method is well-designed:

Positives:

  • ✅ Returns early if Shakapacker is not defined
  • ✅ Uses Array() wrapper to handle both single strings and arrays
  • ✅ Rescue clause provides safe fallback
  • ✅ String inclusion check is appropriate for detecting the rake task

Potential Improvements:

  1. Consider more precise matching - The current implementation uses .include?("react_on_rails:generate_packs") which could match false positives like comments or echo statements. Consider using a regex for more precise matching:

    Array(hooks).any? { |hook| hook.to_s.match?(/\breact_on_rails:generate_packs\b/) }
  2. Log the rescue - Silent failures can be hard to debug. Consider logging when an exception occurs:

    rescue StandardError => e
      Rails.logger.debug("Error checking shakapacker precompile hook: #{e.message}") if defined?(Rails)
      false

lib/react_on_rails/dev/pack_generator.rb:9-16

Positives:

  • ✅ Clean early return pattern
  • ✅ Helpful skip message in verbose mode
  • ✅ Silent in non-verbose mode (good UX)

lib/react_on_rails/configuration.rb:250-256

Positives:

  • ✅ Minimal change with clear comment
  • ✅ Maintains existing task invocation for webpack assets

🧪 Test Coverage Assessment

The test coverage is comprehensive and well-structured:

spec/react_on_rails/packer_utils_spec.rb (lines 141-207)

  • ✅ Tests all branches: Shakapacker undefined, hooks present/absent, single/array hooks
  • ✅ Tests error handling
  • ✅ Uses proper mocking to avoid external dependencies

spec/react_on_rails/dev/pack_generator_spec.rb (lines 8-52)

  • ✅ Tests both code paths (hook configured vs not configured)
  • ✅ Tests verbose and quiet modes separately
  • ✅ Tests error conditions

🔒 Security Considerations

✅ No security concerns identified

  • The code only reads configuration, does not execute arbitrary commands
  • String matching is safe (no eval or command injection risk)
  • Error handling prevents information leakage

⚡ Performance Considerations

✅ Performance impact is positive

  • Primary benefit: Eliminates duplicate pack generation (saves significant time)
  • Check overhead: Minimal - just reads config once per invocation
  • No caching needed since this runs once per rake/dev process

📋 Recommendations

High Priority: None

The PR is ready to merge as-is.

Medium Priority:

  1. Improve pattern matching precision - Use word boundary regex instead of simple string inclusion to avoid false positives

  2. Add debug logging - Log when the check method catches an exception to aid future debugging

Low Priority:

  1. Consider caching the result - If this method is called multiple times in the same process, consider memoizing the result

  2. Documentation - Consider adding a note to the main docs about this feature when shakapacker hooks are officially released


✅ Checklist Compliance (per CLAUDE.md)

  • ✅ RuboCop compliance: Mentioned in test plan
  • ✅ Trailing newlines: All files properly terminated
  • ✅ Tests added and passing
  • ✅ Following existing code patterns
  • ✅ No manual formatting issues

🎯 Final Verdict

LGTM with minor suggestions

This PR is well-crafted and ready for merge. The suggested improvements are minor refinements that could be addressed in a follow-up if desired, but they do not block merging.

Estimated Risk: Low - The changes are defensive (only skip when hook detected), well-tested, and have clear fallback behavior.

Great work! 🚀

Copy link

claude bot commented Oct 13, 2025

Code Review for PR #1861: Skip generate_packs when shakapacker precompile hook configured

Overall Assessment

This is a well-implemented PR that solves a real problem (duplicate pack generation) with a clean, defensive approach. The code quality is high, test coverage is comprehensive, and the implementation follows Ruby best practices.


Strengths

  1. Excellent Test Coverage: The test suite is thorough and covers:

    • Hook detection with single and array configurations
    • Both verbose and quiet modes
    • Error handling with graceful fallback
    • Edge cases (nil configs, exceptions)
  2. Defensive Programming: The rescue StandardError fallback to false ensures the system continues to work even if hook detection fails

  3. Clear User Feedback: The verbose mode provides helpful messages about why pack generation is being skipped

  4. Backward Compatibility: Falls back gracefully when Shakapacker is not defined or hooks are not configured

  5. Proper RuboCop Compliance: Code follows project style guidelines


Code Quality Observations

Strong Points

lib/react_on_rails/packer_utils.rb:168-178

  • Good use of early returns for clarity
  • Proper null safety with dig and nil checks
  • Comprehensive error handling

spec/react_on_rails/packer_utils_spec.rb

  • Excellent test organization with clear contexts
  • Good use of RSpec doubles/mocking
  • Tests verify behavior, not implementation

Minor Suggestions

1. Consider Logging in Silent Failure Mode

In packer_utils.rb:177, when an exception occurs, it silently returns false. While this is the right behavior, consider logging the error for debugging.

2. DRY Opportunity in Tests

The pack_generator_spec.rb tests could extract the shared command strings to reduce duplication.

3. Missing Edge Case Test

Consider adding a test for when config_data is nil (not just when hooks are missing).


Potential Issues

None identified - The implementation handles edge cases well.


Performance Considerations

Caching Opportunity: The shakapacker_precompile_hook_configured? method reads the config file on every call. Consider memoizing the result.

Impact: Low - This method is called infrequently (only during asset precompile and bin/dev startup), so the performance gain would be minimal. However, it would prevent redundant file reads.


Security Considerations

No security concerns identified. The code:

  • Only reads configuration, doesn't execute arbitrary commands
  • Doesn't expose sensitive data
  • Has proper error handling to prevent information leakage

Documentation

The PR description is excellent and clearly explains:

  • What the change does
  • Why it matters
  • How it works
  • Test coverage

Suggestion: Consider adding inline comments in configuration.rb:250-253 to explain the conditional logic for future maintainers.


Checklist Verification

Based on CLAUDE.md requirements:

  • RuboCop compliance mentioned in PR description
  • Comprehensive test coverage
  • Files end with newlines (verified in diff)
  • Follows project conventions

Conclusion

Recommendation: APPROVE

This is a clean, well-tested implementation that solves a real problem without breaking existing functionality. The minor suggestions above are optional improvements, not blockers.

Great work on the defensive programming approach and comprehensive test coverage!

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant