Skip to content

Instantly share code, notes, and snippets.

@edward
Created January 22, 2015 02:07
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 edward/c8dc5365735c51b5379a to your computer and use it in GitHub Desktop.
Save edward/c8dc5365735c51b5379a to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'bundler/setup'
require 'css_parser'
class String
CSS_CLASS_REGEX = /\.[\w-]+/ix
CSS_ID_REGEX = /\#[\w-]+/ix
def css_classes
scan(CSS_CLASS_REGEX)
end
def css_identifiers
scan(CSS_ID_REGEX)
end
def css_classes_and_identifiers
scan(Regexp.union(CSS_CLASS_REGEX, CSS_ID_REGEX))
end
end
class UnusedCssFinder
PROJECT_PATH = '/home/vagrant/shopify'
attr_accessor :classes, :identifiers
def initialize
@parser = CssParser::Parser.new
end
def load_css_from_uri(address)
@parser.load_uri!(address)
selectors = []
@parser.each_selector { |s| selectors << s }
# weirdo_selectors = selectors.map do |s|
# s if s.css_classes_and_identifiers.empty?
# end.compact
@identifiers = selectors.map(&:css_identifiers).flatten.uniq
@classes = selectors.map(&:css_classes).flatten.uniq
end
def find_in_project(css_thing, path)
css_thing = css_thing[1..-1] # Remove prevailing . or # to just have the class name
cmd = `ack-grep --match "[ \\"\\']#{css_thing}[ \\"\\']" --type-set=coffeescript=.coffee --coffee --ruby --js --coffeescript #{path}/app/ #{path}/vendor/`
if cmd.empty?
css_thing
else
nil
end
end
def report
puts "These are suspected unused CSS classes/identifiers:"
@suspected_unused_css_things = []
[@classes + @identifiers].flatten.each do |css_thing|
if find_in_project(css_thing, PROJECT_PATH)
@suspected_unused_css_things << css_thing
puts css_thing
end
end
end
def git_into_it
git_logs_path = "unused_css_git_logs"
`mkdir #{git_logs_path}`
puts "Ok, I’m generating git log things on all of this business and putting them in #{git_logs_path}"
puts "Please note that this is going to take like #{@suspected_unused_css_things} minutes to run."
@suspected_unused_css_things.each do |css_thing|
`git log -S#{css_thing} --patch --max-count=5 -- . ':(exclude)*.css' ':(exclude)*.scss' > #{PROJECT_PATH}/#{git_logs_path}/#{css_thing}.diff`
end
puts "Ok! Done. Look in #{git_logs_path} for diffs to help you investigate."
end
end
unused_css_finder = UnusedCssFinder.new
puts "Ok! Looking for unused CSS in #{UnusedCssFinder::PROJECT_PATH}"
css_uri = 'http://cdn.myshopify.io/s/assets/admin/style-e0b8e5ba14d67e7e2135f5450301ef3c.css'
begin
unused_css_finder.load_css_from_uri(css_uri)
rescue CssParser::RemoteFileError
puts "It looks like #{css_uri} isn’t loading. Exiting."
exit
end
puts "Loaded #{css_uri}"
puts "Identifiers: #{unused_css_finder.identifiers.size}"
puts "Classes: #{unused_css_finder.classes.size}"
puts
unused_css_finder.report
# Don’t use this for now since it takes forever
# Just use it on css things that aren’t obviously used by generated code or not
# unused_css_finder.git_into_it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment