Skip to content

Instantly share code, notes, and snippets.

@jworley
Last active December 15, 2015 00:39
Show Gist options
  • Save jworley/5174653 to your computer and use it in GitHub Desktop.
Save jworley/5174653 to your computer and use it in GitHub Desktop.
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