Example custom metric for Square's Cane gem. Checks source code for `puts` and `print` left behind by developers.
require 'cane/file' | |
require 'cane/task_runner' | |
class PutsCheck < Struct.new(:opts) | |
DESCRIPTION = | |
"Lines output to console using `puts` or `print`" | |
PUTS_REGEX = /^\s*p(uts|rint)?[\s\(]+(.+?)\s*[\)\s]*$/ | |
PUTS_GLOB = '{app,lib}/**/*.rb' | |
def self.key; :puts; end | |
def self.name; "puts output checking"; end | |
def self.options | |
{ | |
puts_glob: ['Glob to run puts checks over', | |
default: PUTS_GLOB, | |
variable: 'GLOB', | |
clobber: :no_puts], | |
puts_exclude: ['Exclude file or glob from puts checking', | |
variable: 'GLOB', | |
type: Array, | |
default: [], | |
clobber: :no_puts], | |
no_puts: ['Disable puts checking', cast: ->(x) { !x }] | |
} | |
end | |
def violations | |
return [] if opts[:no_puts] | |
worker.map(file_names) do |file_name| | |
find_violations(file_name) | |
end.flatten | |
end | |
def find_violations(file_name) | |
Cane::File.iterator(file_name).map.with_index do |line, number| | |
puts_match = line.match(PUTS_REGEX) | |
result = if !!puts_match | |
{ | |
file: file_name, | |
line: number + 1, | |
label: "Line outputs '#{puts_match[2]}'", | |
description: DESCRIPTION | |
} | |
end | |
end.compact | |
end | |
def file_names | |
Dir[opts.fetch(:puts_glob, PUTS_GLOB)].reject { |file| excluded?(file) } | |
end | |
def exclusions | |
@exclusions ||= opts.fetch(:puts_exclude, []).flatten.map do |i| | |
Dir[i] | |
end.flatten.to_set | |
end | |
def excluded?(file) | |
exclusions.include?(file) | |
end | |
def worker | |
Cane.task_runner(opts) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment