Skip to content

Copy compressor option hashes before applying defaults or retaining them - #851

Closed
OskarEichler wants to merge 1 commit into
rails:mainfrom
OskarEichler:codex/compressor-options
Closed

Copy compressor option hashes before applying defaults or retaining them#851
OskarEichler wants to merge 1 commit into
rails:mainfrom
OskarEichler:codex/compressor-options

Conversation

@OskarEichler

Copy link
Copy Markdown

Summary

Uglifier, Closure and YUI compressors copy the top-level options hash at initialization. Uglifier accepts a frozen options hash without adding defaults to the caller hash. Nested option values remain shared.

Copy the top-level hashes before applying Uglifier defaults or retaining Closure/YUI options. Real compilation confirms that changing the caller hash no longer changes output while leaving the initialized cache key unchanged. Nested option values remain shared; this is deliberately not a deep-copy guarantee. Existing default semantics, including comments:false normalization, remain unchanged.

Reproduction

With require "sprockets"; require "tmpdir":

options = {}.freeze
Sprockets::UglifierCompressor.new(options) # Previously FrozenError.
p options # {}, no default inserted into caller-owned hash.

options = {mangle: false, compress: false}
compressor = Sprockets::UglifierCompressor.new(options)
options[:mangle] = true
# The compressor now retains mangle:false, matching its initial cache key.
# Closure and YUI likewise retain their initial top-level option values.

Verification

  • Isolated patch: unchanged bundle exec rake test and bundle exec rake test_isolated each pass 913 tests / 4,109 assertions / zero failures/errors / four skips, on Ruby 3.2.11 and 4.0.6 with Rack 3.2.7.
  • 25 focused external checks pass on each Ruby. Baseline reproduces the defect. All Ruby commands used rbenv.
  • Full RuboCop: 133 files, zero offenses. Changed Ruby files pass syntax checks on both Rubies; git diff --check passes.
  • Gem build and content comparison preserve all 84 package paths, version 4.4.1, Ruby >=2.5 and dependency metadata. Only README, CHANGELOG and the relevant runtime files differ.

Compatibility and limitations

Breaking changes: no intended change to valid supported behavior; the incorrect behavior described above changes. No new dependencies or version upgrades. Nested configuration ownership, unrelated cache invalidation and HTTP behavior are outside this focused patch.

Based on installed release/current upstream main 49d9f20c00ac7d9a7ee57db058961edcccd86699. This is an upstream-only contribution; no personal fork is being adopted in the application. Older Ruby/Linux/JRuby verification is left to upstream CI, not claimed locally. No checked-in tests were added or edited under the requesting repository's no-test-edit policy; focused reproductions ran externally. Prepared with AI assistance. This does not claim exhaustive Sprockets coverage.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants