/
style_check.rb
87 lines (72 loc) · 2.38 KB
/
style_check.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
require 'set'
require 'cane/file'
require 'cane/task_runner'
module Cane
# Creates violations for files that do not meet style conventions. Only
# highly obvious, probable, and non-controversial checks are performed here.
# It is not the goal of the tool to provide an extensive style report, but
# only to prevent stupid mistakes.
class StyleCheck < Struct.new(:opts)
def self.key; :style; end
def self.name; "style checking"; end
def self.options
{
style_glob: ['Glob to run style checks over',
default: '{app,lib,spec}/**/*.rb',
variable: 'GLOB',
clobber: :no_style],
style_measure: ['Max line length',
default: 80,
cast: :to_i,
clobber: :no_style],
style_exclude: ['Exclude file from style checking',
variable: 'FILE',
type: Array,
default: [],
clobber: :no_style],
no_style: ['Disable style checking', cast: ->(x) { !x }]
}
end
def violations
return [] if opts[:no_style]
worker.map(file_list) do |file_path|
map_lines(file_path) do |line, line_number|
violations_for_line(line.chomp).map {|message| {
file: file_path,
line: line_number + 1,
label: message,
description: "Lines violated style requirements"
}}
end
end.flatten
end
protected
def violations_for_line(line)
result = []
if line.length > measure
result << "Line is >%i characters (%i)" % [measure, line.length]
end
result << "Line contains trailing whitespace" if line =~ /\s$/
result << "Line contains hard tabs" if line =~ /\t/
result
end
def file_list
Dir[opts.fetch(:style_glob)].reject {|f| excluded?(f) }
end
def measure
opts.fetch(:style_measure)
end
def map_lines(file_path, &block)
Cane::File.iterator(file_path).map.with_index(&block)
end
def exclusions
@exclusions ||= opts.fetch(:style_exclude, []).flatten.to_set
end
def excluded?(file)
exclusions.include?(file)
end
def worker
Cane.task_runner(opts)
end
end
end