diff --git a/CHANGELOG.md b/CHANGELOG.md index 41433eab9..2ec6ca810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Get upgrade notes from Sprockets 3.x to 4.x at https://github.com/rails/sprocket ## Master +- Do not fingerprint files that already contain a valid digest in their name - Remove remaining support for Ruby < 2.4.[#672](https://github.com/rails/sprockets/pull/672) ## 4.0.2 diff --git a/lib/sprockets/asset.rb b/lib/sprockets/asset.rb index 32f86aca1..ef7e17a4f 100644 --- a/lib/sprockets/asset.rb +++ b/lib/sprockets/asset.rb @@ -64,7 +64,11 @@ def to_hash # # Returns String. def digest_path - logical_path.sub(/\.(\w+)$/) { |ext| "-#{etag}#{ext}" } + if DigestUtils.already_digested?(@name) + logical_path + else + logical_path.sub(/\.(\w+)$/) { |ext| "-#{etag}#{ext}" } + end end # Public: Return load path + logical path with digest spliced in. diff --git a/lib/sprockets/digest_utils.rb b/lib/sprockets/digest_utils.rb index b66703a7a..a1c704e18 100644 --- a/lib/sprockets/digest_utils.rb +++ b/lib/sprockets/digest_utils.rb @@ -179,6 +179,19 @@ def hexdigest_integrity_uri(hexdigest) integrity_uri(unpack_hexdigest(hexdigest)) end + # Internal: Checks an asset name for a valid digest + # + # name - The name of the asset + # + # Returns true if the name contains a digest recognized by one of the valid digest classes + def already_digested?(name) + return if name.nil? + + if hexdigest = name.scan(/[a-fA-F0-9]+\z/).last + detect_digest_class(unpack_hexdigest(hexdigest)) + end + end + private def build_digest(obj) digest = digest_class.new diff --git a/test/test_asset.rb b/test/test_asset.rb index 6ca369da8..13bd89751 100644 --- a/test/test_asset.rb +++ b/test/test_asset.rb @@ -1124,6 +1124,32 @@ def read(logical_path) end end +class PreDigestedAssetTest < Sprockets::TestCase + def setup + @env = Sprockets::Environment.new + @env.append_path(fixture_path('asset')) + @env.cache = {} + + @pipeline = nil + end + + test "digest path" do + path = File.expand_path("test/fixtures/asset/application") + original = "#{path}.js" + digested = "#{path}-d41d8cd98f00b204e9800998ecf8427e.js" + FileUtils.cp(original, digested) + + assert_equal "application-d41d8cd98f00b204e9800998ecf8427e.js", + asset("application-d41d8cd98f00b204e9800998ecf8427e.js").digest_path + ensure + FileUtils.rm(digested) if File.exists?(digested) + end + + def asset(logical_path, options = {}) + @env.find_asset(logical_path, **{pipeline: @pipeline}.merge(options)) + end +end + class DebugAssetTest < Sprockets::TestCase def setup diff --git a/test/test_digest_utils.rb b/test/test_digest_utils.rb index aee488488..1d451882a 100644 --- a/test/test_digest_utils.rb +++ b/test/test_digest_utils.rb @@ -94,4 +94,17 @@ def test_hexdigest_integrity_uri assert_equal "sha512-+uuYUxxe7oWIShQrWEmMn/fixz/rxDP4qcAZddXLDM3nN8/tpk1ZC2jXQk6N+mXE65jwfzNVUJL/qjA3y9KbuQ==", hexdigest_integrity_uri(sha512) end + + def test_already_digested + refute already_digested?(nil) + refute already_digested?("application-d41d8cd98f00b204e9800998ecf8427z") + refute already_digested?("application-d41d8cd98f00b204e9800998ecf8427ef") + refute already_digested?("application-d41d8cd98f00b204e9800998ecf8427e-") + + assert already_digested?("application-" + Digest::MD5.new.hexdigest) + assert already_digested?("application-" + Digest::SHA1.new.hexdigest) + assert already_digested?("application-" + Digest::SHA256.new.hexdigest) + assert already_digested?("application-" + Digest::SHA384.new.hexdigest) + assert already_digested?("application-" + Digest::SHA512.new.hexdigest) + end end