]> git.immae.eu Git - github/fretlink/pronto-hlint.git/blob - lib/pronto/eslint_npm.rb
add class variables to prepare setting external config
[github/fretlink/pronto-hlint.git] / lib / pronto / eslint_npm.rb
1 require 'pronto'
2 require 'shellwords'
3
4 module Pronto
5 class ESLintNpm < Runner
6 class << self
7 attr_writer :eslint_executable, :files_to_lint
8
9 def eslint_executable
10 @eslint_executable || 'eslint'.freeze
11 end
12
13 def files_to_lint
14 @files_to_lint || /(\.js|\.es6)$/
15 end
16 end
17
18 def run
19 return [] unless @patches
20
21 @patches
22 .select { |patch| patch.additions > 0 }
23 .select { |patch| js_file?(patch.new_file_full_path) }
24 .map { |patch| inspect(patch) }
25 .flatten.compact
26 end
27
28 private
29
30 def inspect(patch)
31 @_repo_path ||= @patches.first.repo.path
32
33 offences = run_eslint(patch)
34 clean_up_eslint_output(offences)
35 .map do |offence|
36 patch
37 .added_lines
38 .select { |line| line.new_lineno == offence['line'] }
39 .map { |line| new_message(offence, line) }
40 end
41 end
42
43 def new_message(offence, line)
44 path = line.patch.delta.new_file[:path]
45 level = :warning
46
47 Message.new(path, line, level, offence['message'], nil, self.class)
48 end
49
50 def js_file?(path)
51 self.class.files_to_lint =~ path.to_s
52 end
53
54 def run_eslint(patch)
55 Dir.chdir(@_repo_path) do
56 escaped_file_path = Shellwords.escape(patch.new_file_full_path.to_s)
57 JSON.parse(
58 `#{self.class.eslint_executable} #{escaped_file_path} -f json`
59 )
60 end
61 end
62
63 def clean_up_eslint_output(output)
64 # 1. Filter out offences without a warning or error
65 # 2. Get the messages for that file
66 # 3. Ignore errors without a line number for now
67 output
68 .select { |offence| offence['errorCount'] + offence['warningCount'] > 0 }
69 .map { |offence| offence['messages'] }
70 .flatten.select { |offence| offence['line'] }
71 end
72 end
73 end