Skip to content

Commit 6d2011e

Browse files
committed
Use csv formatter for coffeelint
This allows us to remove the dependency on the 'json' library and simplify the message parsing logic. It also makes it easier to parse concatenated results of multiple calls when splitting argument lists.
1 parent 627a8c0 commit 6d2011e

File tree

3 files changed

+30
-66
lines changed

3 files changed

+30
-66
lines changed

config/default.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ PreCommit:
176176
enabled: false
177177
description: 'Analyzing with coffeelint'
178178
required_executable: 'coffeelint'
179-
required_library: 'json'
180-
flags: ['--reporter=raw']
179+
flags: ['--reporter=csv']
181180
install_command: 'npm install -g coffeelint'
182181
include: '**/*.coffee'
183182

lib/overcommit/hook/pre_commit/coffee_lint.rb

+18-26
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,30 @@ module Overcommit::Hook::PreCommit
33
#
44
# @see http://www.coffeelint.org/
55
class CoffeeLint < Base
6+
MESSAGE_REGEX = /
7+
^(?<file>.+)
8+
,(?<line>\d*),\d*
9+
,(?<type>\w+)
10+
,(?<msg>.+)$
11+
/x
12+
13+
MESSAGE_TYPE_CATEGORIZER = lambda do |type|
14+
type.include?('w') ? :warning : :error
15+
end
16+
617
def run
718
result = execute(command + applicable_files)
8-
9-
begin
10-
parse_json_messages(result.stdout)
11-
rescue JSON::ParserError => e
12-
[:fail, "Error parsing coffeelint output: #{e.message}"]
13-
end
19+
parse_messages(result.stdout)
1420
end
1521

1622
private
1723

18-
def parse_json_messages(output)
19-
JSON.parse(output).collect do |file, messages|
20-
messages.collect { |msg| extract_message(file, msg) }
21-
end.flatten
22-
end
23-
24-
def extract_message(file, message_hash)
25-
type = message_hash['level'].include?('w') ? :warning : :error
26-
line = message_hash['lineNumber']
27-
rule = message_hash['rule']
28-
msg = message_hash['message']
29-
text =
30-
if rule == 'coffeescript_error'
31-
# Syntax errors are output in different format.
32-
# Splice in the file name and grab the first line.
33-
msg.sub('[stdin]', file).split("\n")[0]
34-
else
35-
"#{file}:#{line}: #{msg} (#{rule})"
36-
end
37-
Overcommit::Hook::Message.new(type, file, line, text)
24+
def parse_messages(output)
25+
output.scan(MESSAGE_REGEX).map do |file, line, type, msg|
26+
type = MESSAGE_TYPE_CATEGORIZER.call(type)
27+
text = "#{file}:#{line}:#{type} #{msg}"
28+
Overcommit::Hook::Message.new(type, file, line, text)
29+
end
3830
end
3931
end
4032
end

spec/overcommit/hook/pre_commit/coffee_lint_spec.rb

+11-38
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,20 @@
1919

2020
context 'with no warnings' do
2121
before do
22-
result.stub(:stdout).and_return('{
23-
"file1.coffee": []
24-
}')
22+
result.stub(:stdout).and_return(normalize_indent(<<-OUT))
23+
path,lineNumber,lineNumberEnd,level,message
24+
OUT
2525
end
2626

2727
it { should pass }
2828
end
2929

3030
context 'and it reports a warning' do
3131
before do
32-
result.stub(:stdout).and_return('{
33-
"file1.coffee": [
34-
{
35-
"name": "ensure_comprehensions",
36-
"level": "warn",
37-
"message": "Comprehensions must have parentheses around them",
38-
"description": "This rule makes sure that parentheses are around comprehensions.",
39-
"context": "",
40-
"lineNumber": 31,
41-
"line": "cubes = math.cube num for num in list",
42-
"rule": "ensure_comprehensions"
43-
}
44-
]
45-
}')
32+
result.stub(:stdout).and_return(normalize_indent(<<-OUT))
33+
path,lineNumber,lineNumberEnd,level,message
34+
file1.coffee,31,,warn,Comprehensions must have parentheses around them
35+
OUT
4636
end
4737

4838
it { should warn }
@@ -59,27 +49,10 @@
5949

6050
context 'and it reports an error' do
6151
before do
62-
result.stub(:stdout).and_return('{
63-
"file1.coffee": [
64-
{
65-
"name": "duplicate_key",
66-
"level": "error",
67-
"message": "Duplicate key defined in object or class",
68-
"description": "Prevents defining duplicate keys in object literals and classes",
69-
"lineNumber": 17,
70-
"line": " root: foo",
71-
"rule": "duplicate_key"
72-
}
73-
]
74-
}')
75-
end
76-
77-
it { should fail_hook }
78-
end
79-
80-
context 'and its output is not valid JSON' do
81-
before do
82-
result.stub(:stdout).and_return('foo')
52+
result.stub(:stdout).and_return(normalize_indent(<<-OUT))
53+
path,lineNumber,lineNumberEnd,level,message
54+
file1.coffee,17,,error,Duplicate key defined in object or class
55+
OUT
8356
end
8457

8558
it { should fail_hook }

0 commit comments

Comments
 (0)