Skip to content

Instantly share code, notes, and snippets.

@bigfive
Last active August 29, 2015 14:03
Show Gist options
  • Save bigfive/17654b10ebfe0030c471 to your computer and use it in GitHub Desktop.
Save bigfive/17654b10ebfe0030c471 to your computer and use it in GitHub Desktop.
Genreate report on possible duplicate and missing scss color vars
require 'scss_lint'
module SassExtractor
mattr_accessor :color_var_nodes
mattr_accessor :color_nodes
self.color_var_nodes = []
self.color_nodes = []
module Vistors
class VariableGatherer < SCSSLint::Linter
def visit_variable(node)
if node.expr.is_a?(Sass::Script::Tree::Literal) && node.expr.value.is_a?(Sass::Script::Value::Color)
SassExtractor.color_var_nodes << node
end
end
end
class ColorGatherer < SCSSLint::Linter
def visit_script_color(node)
unless node.to_s == 'transparent' || debug_line(node) =~ /\$(.*?):(.*?);/
SassExtractor.color_nodes << [node, node.to_s, debug_line(node)]
end
end
def visit_script_string(node)
return unless node.type == :identifier
value = remove_quoted_strings(node.value)
# Hexs
value.scan(/#(?:[0-9a-f]{3}){1,2}/i) do |color|
SassExtractor.color_nodes << [node, color, debug_line(node)]
end
# Named colors
value.scan(/(^|\s)([a-z]+)(?=\s|$)/i) do |_, color|
SassExtractor.color_nodes << [node, color, debug_line(node)] if Sass::Script::Value::Color::COLOR_NAMES[color] && color != 'transparent'
end
end
protected
def debug_line(node)
"#{engine.filename}:#{node.line}: ( #{engine.lines[node.line - 1][0..-2].gsub(/\s+/, " ")} )"
end
end
end
class ColorExtractor
def self.report(glob)
gather_config = {
'linters' => {
'VariableGatherer' => { 'enabled' => true },
'ColorGatherer' => { 'enabled' => true }
}
}
runner = SCSSLint::Runner.new SCSSLint::Config.new(gather_config)
runner.run Dir.glob(glob)
report_lines = []
report_lines << "---------------------"
report_lines << "Possible duplicates:"
SassExtractor.color_nodes.each do |arr|
next unless arr.is_a? Array
duplicate_var = SassExtractor.color_var_nodes.select{|n| n.expr.value.to_s == arr[1].to_s }
if duplicate_var.present?
report_lines << "#{arr[2]} maybe should use $#{duplicate_var.map(&:name).join(' or $')}"
end
end
report_lines << ""
report_lines << "---------------------"
report_lines << "Define Vars for:"
SassExtractor.color_nodes.each_with_index do |arr, index|
next unless arr.is_a? Array
duplicate_var = SassExtractor.color_var_nodes.select{|n| n.expr.value.to_s == arr[1].to_s }
if duplicate_var.blank?
report_lines << "$var#{index}: #{arr[1].to_s}"
end
end
report_lines << "---------------------"
report_lines << "And use them here:"
SassExtractor.color_nodes.each_with_index do |arr, index|
next unless arr.is_a? Array
duplicate_var = SassExtractor.color_var_nodes.select{|n| n.expr.value.to_s == arr[1].to_s }
if duplicate_var.blank?
report_lines << "#{arr[2]} should use $var#{index}"
end
end
report_lines.join("\n")
end
end
end
module SCSSLint::LinterRegistry
def self.linters
[
SassExtractor::Vistors::VariableGatherer,
SassExtractor::Vistors::ColorGatherer
]
end
end
# Run with
# puts SassExtractor::ColorExtractor.report(Rails.root.join 'app/assets/stylesheets/**/*.css.scss')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment