Skip to content

Instantly share code, notes, and snippets.

@h-lame
Created June 30, 2017 12:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save h-lame/6bacdd299545af092ed79ced9bbb47d3 to your computer and use it in GitHub Desktop.
Save h-lame/6bacdd299545af092ed79ced9bbb47d3 to your computer and use it in GitHub Desktop.
Rake task to hook into assets:precompile in a rails app and remove any BOMs that are inserted by sprockets/sass in CSS files (and their gzipped siblings)
namespace :assets do
task :remove_bom => :environment do
require 'sprockets/utils/gzip'
# object that has enough of the Sprockets::Asset API to be
# used in the Sprockets::Utils::Gzip class without us needing
# to use the real class which needs more data
class DeBOMedCSSAsset < Struct.new(:file_name)
def content_type
'text/css'
end
def charset
source.encoding.to_s
end
def source
@source ||= File.read(file_name)
end
end
if Dir.exists?(Rails.application.assets_manifest.directory)
Dir.chdir(Rails.application.assets_manifest.directory) do
debomed = []
# find all css files and remove BOM from any that have it
Dir[File.join('**', '*.css')].each do |css_file|
# use binread / binwrite to preserve any encoding
file_contents = File.binread(css_file)
if file_contents.bytes[0..2] == [0xEF, 0xBB, 0xBF]
Rails.logger.info "Removing BOM from #{css_file}"
File.binwrite(css_file, file_contents[3..-1])
debomed << css_file
end
end
debomed.each do |debomed|
# re-write the gziped version using sprockets own gzipper
if File.exists?("#{debomed}.gz")
Rails.logger.info "Removing BOM from #{debomed}.gz"
# TODO: this might be a private API we're using so there's danger
# this'll go away
Sprockets::Utils::Gzip.new(DeBOMedCSSAsset.new(debomed)).compress(debomed)
end
end
end
end
end
end
Rake::Task['assets:precompile'].enhance do
Rake::Task['assets:remove_bom'].invoke
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment