Skip to content

Instantly share code, notes, and snippets.

@jawspeak
Created September 27, 2011 15:45
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 jawspeak/1245432 to your computer and use it in GitHub Desktop.
Save jawspeak/1245432 to your computer and use it in GitHub Desktop.
Before and after refactoring of an asset checker - that looks at all assets in a rails project, and finds the ones that appear to be unreferenced.
require 'rubygems'
require 'find'
require 'pp'
class UnusedImagesFinder
def find_unused_assets
puts "Lists unused files based upon explicit programatic checks. Requires manual confirmation before deletion."
puts "------------------ Building css from sass ------------------"
system 'rake build_static:stylesheets'
puts "------------------ Finding assets and references ------------------"
all_assets = find_all_asset_files
used_assets = find_all_asset_references
delta = all_assets.values.flatten - used_assets.keys
puts "----------------- #{delta.size} Files that might not be used -----------------------"
pp delta
delta = used_assets.keys - all_assets.values.flatten
puts "------------ #{delta.size} Files referenced but not at computed location ---------------"
pp delta
end
def find_all_asset_files
ignored_dirpaths = %w(./public/system ./public/fonts ./public/javascripts)
ignored_extensions = %w(html htm txt css) << ''
asset_files = {}
Find.find('./public') do |f|
extension = extension(f)
next if File.directory?(f) || ignored_extensions.member?(extension) || ignored_dirpaths.any?{|prefix| File.dirname(f).start_with?(prefix)}
(asset_files[extension] || asset_files[extension] = []) << f
end
asset_files
end
def find_all_asset_references
checkers = {'erb' => :add_image_matches, 'css' => :add_css_matches}
refs = {}
messages = []
%w(./app/views public/stylesheets).each do |base|
Find.find(base) do |file|
next if File.directory?(file)
lines = File.readlines(file)
lines.each_with_index do |line, line_number|
checker = checkers[extension(file)]
send(checker, file, refs, line, line_number) if checker
end
end
end
refs
end
private
def add_image_matches(file, refs, line, line_number)
add_matches(/img.*src=['"]([^'"]+)['"]/, file, refs, line, line_number) {|match| "./public/images/#{match[1]}"}
add_matches(/<%=[ ]*image_tag[ ]+["']([^'"]+)['"]/, file, refs, line, line_number) {|match| "./public/images/#{match[1]}"}
end
def add_css_matches(file, refs, line, line_number)
add_matches(/url\([\s]*["']?([^\s'"\)]+)['"]?[\s]*\)/, file, refs, line, line_number) {|match| match[1].gsub('../images', './public/images')}
end
def add_matches(regex, file, refs, line, line_number)
match = line.match(regex)
if match
image = yield match
puts "#{file}:#{line_number+1} #{image}\t\t#{line}"
(refs[image] || refs[image] = []) << file
end
end
def extension(file)
File.extname(file).gsub('.', '')
end
end
#UnusedImagesFinder.new.find_all_asset_files
#UnusedImagesFinder.new.find_all_asset_references
UnusedImagesFinder.new.find_unused_assets
require 'rubygems'
require 'find'
require 'pp'
class UnusedImagesFinder
def find_unused_assets
puts "Lists unused files based upon explicit programatic checks. Requires manual confirmation before deletion."
puts "------------------ Build css from sass ------------------"
system 'rake build_static:stylesheets'
all_assets = find_all_asset_files
used_assets = find_all_asset_references
delta = all_assets.values.flatten - used_assets.keys
puts "----------------- #{delta.size} Files that might not be used -----------------------"
pp delta
delta = used_assets.keys - all_assets.values.flatten
puts "------------ #{delta.size} Files referenced but not at computed location ---------------"
pp delta
end
def find_all_asset_files
ignored_dirpaths = %w(./public/system ./public/fonts ./public/javascripts)
ignored_extensions = %w(html htm txt css) << ''
asset_files = {}
Find.find('./public') do |f|
extension = extension(f)
next if File.directory?(f) || ignored_extensions.member?(extension) || ignored_dirpaths.any?{|prefix| File.dirname(f).start_with?(prefix)}
(asset_files[extension] || asset_files[extension] = []) << f
end
asset_files
end
def find_all_asset_references
refs = {}
messages = []
%w(./app/views public/stylesheets).each do |base|
Find.find(base) do |f|
next if File.directory?(f)
lines = File.readlines(f)
extension = extension(f)
lines.each_with_index do |line, line_number|
add_image_matches(f, refs, line, line_number, messages) if extension == 'erb'
add_css_matches(f, refs, line, line_number, messages) if extension == 'css'
end
end
end
refs
end
private
def add_image_matches(file, refs, line, line_number, messages)
matched_img = line.match(/img.*src=['"]([^'"]+)['"]/)
if matched_img
image = "./public/images/#{matched_img[1]}"
messages << "#{file}:#{line_number+1} #{image}\t#{line}"
(refs[image] || refs[image] = []) << file
end
matched_image_tag = line.match(/<%=[ ]*image_tag[ ]+["']([^'"]+)['"]/)
if matched_image_tag
image = "./public/images/#{matched_image_tag[1]}"
messages << "#{file}:#{line_number+1} #{image}\t#{line}"
(refs[image] || refs[image] = []) << file
end
end
def add_css_matches(file, refs, line, line_number, messages)
matched_url = line.match(/url\([\s]*["']?([^\s'"\)]+)['"]?[\s]*\)/)
if matched_url
image = matched_url[1].gsub('../images', './public/images')
messages << "#{file}:#{line_number+1} #{image}\t#{line}"
(refs[image] || refs[image] = []) << file
end
end
def extension(file)
File.extname(file).gsub('.', '')
end
end
#UnusedImagesFinder.new.find_all_asset_files
#UnusedImagesFinder.new.find_all_asset_references
UnusedImagesFinder.new.find_unused_assets
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment