aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/pronto
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pronto')
-rw-r--r--lib/pronto/eslint_npm.rb104
-rw-r--r--lib/pronto/eslint_npm/version.rb7
-rw-r--r--lib/pronto/hlint.rb8
-rw-r--r--lib/pronto/hlint/runner.rb120
-rw-r--r--lib/pronto/hlint/version.rb7
5 files changed, 135 insertions, 111 deletions
diff --git a/lib/pronto/eslint_npm.rb b/lib/pronto/eslint_npm.rb
deleted file mode 100644
index 6a9c00c..0000000
--- a/lib/pronto/eslint_npm.rb
+++ /dev/null
@@ -1,104 +0,0 @@
1# frozen_string_literal: true
2
3require 'pronto'
4require 'shellwords'
5
6module Pronto
7 class ESLintNpm < Runner
8 CONFIG_FILE = '.pronto_eslint_npm.yml'.freeze
9 CONFIG_KEYS = %w[eslint_executable files_to_lint cmd_line_opts].freeze
10
11 attr_writer :eslint_executable, :cmd_line_opts
12
13 def eslint_executable
14 @eslint_executable || 'eslint'
15 end
16
17 def files_to_lint
18 @files_to_lint || /(\.js|\.es6)$/
19 end
20
21 def cmd_line_opts
22 @cmd_line_opts || ''
23 end
24
25 def files_to_lint=(regexp)
26 @files_to_lint = regexp.is_a?(Regexp) && regexp || Regexp.new(regexp)
27 end
28
29 def config_options
30 @config_options ||=
31 begin
32 config_file = File.join(repo_path, CONFIG_FILE)
33 File.exist?(config_file) && YAML.load_file(config_file) || {}
34 end
35 end
36
37 def read_config
38 config_options.each do |key, val|
39 next unless CONFIG_KEYS.include?(key.to_s)
40 send("#{key}=", val)
41 end
42 end
43
44 def run
45 return [] if !@patches || @patches.count.zero?
46
47 read_config
48
49 @patches
50 .select { |patch| patch.additions > 0 }
51 .select { |patch| js_file?(patch.new_file_full_path) }
52 .map { |patch| inspect(patch) }
53 .flatten.compact
54 end
55
56 private
57
58 def repo_path
59 @repo_path ||= @patches.first.repo.path
60 end
61
62 def inspect(patch)
63 offences = run_eslint(patch)
64 clean_up_eslint_output(offences)
65 .map do |offence|
66 patch
67 .added_lines
68 .select { |line| line.new_lineno == offence['line'] }
69 .map { |line| new_message(offence, line) }
70 end
71 end
72
73 def new_message(offence, line)
74 path = line.patch.delta.new_file[:path]
75 level = :warning
76
77 Message.new(path, line, level, offence['message'], nil, self.class)
78 end
79
80 def js_file?(path)
81 files_to_lint =~ path.to_s
82 end
83
84 def run_eslint(patch)
85 Dir.chdir(repo_path) do
86 JSON.parse `#{eslint_command_line(patch.new_file_full_path.to_s)}`
87 end
88 end
89
90 def eslint_command_line(path)
91 "#{eslint_executable} #{cmd_line_opts} #{Shellwords.escape(path)} -f json"
92 end
93
94 def clean_up_eslint_output(output)
95 # 1. Filter out offences without a warning or error
96 # 2. Get the messages for that file
97 # 3. Ignore errors without a line number for now
98 output
99 .select { |offence| offence['errorCount'] + offence['warningCount'] > 0 }
100 .map { |offence| offence['messages'] }
101 .flatten.select { |offence| offence['line'] }
102 end
103 end
104end
diff --git a/lib/pronto/eslint_npm/version.rb b/lib/pronto/eslint_npm/version.rb
deleted file mode 100644
index e3683f4..0000000
--- a/lib/pronto/eslint_npm/version.rb
+++ /dev/null
@@ -1,7 +0,0 @@
1# frozen_string_literal: true
2
3module Pronto
4 module ESLintNpmVersion
5 VERSION = '0.10.0'.freeze
6 end
7end
diff --git a/lib/pronto/hlint.rb b/lib/pronto/hlint.rb
new file mode 100644
index 0000000..daf1029
--- /dev/null
+++ b/lib/pronto/hlint.rb
@@ -0,0 +1,8 @@
1# frozen_string_literal: true
2
3require 'pronto/hlint/runner'
4
5module Pronto
6 module Hlint
7 end
8end
diff --git a/lib/pronto/hlint/runner.rb b/lib/pronto/hlint/runner.rb
new file mode 100644
index 0000000..e334860
--- /dev/null
+++ b/lib/pronto/hlint/runner.rb
@@ -0,0 +1,120 @@
1# frozen_string_literal: true
2
3require 'pronto'
4require 'shellwords'
5
6module Pronto
7 module Hlint
8 class Runner < Pronto::Runner
9 CONFIG_FILE = '.pronto_hlint.yml'.freeze
10 CONFIG_KEYS = %w[hlint_executable files_to_lint cmd_line_opts].freeze
11
12 attr_writer :hlint_executable, :cmd_line_opts
13
14 def hlint_executable
15 @hlint_executable || 'hlint'
16 end
17
18 def files_to_lint
19 @files_to_lint || /(\.hs)$/
20 end
21
22 def cmd_line_opts
23 @cmd_line_opts || ''
24 end
25
26 def files_to_lint=(regexp)
27 @files_to_lint = regexp.is_a?(Regexp) && regexp || Regexp.new(regexp)
28 end
29
30 def config_options
31 @config_options ||=
32 begin
33 config_file = File.join(repo_path, CONFIG_FILE)
34 File.exist?(config_file) && YAML.load_file(config_file) || {}
35 end
36 end
37
38 def read_config
39 config_options.each do |key, val|
40 next unless CONFIG_KEYS.include?(key.to_s)
41 send("#{key}=", val)
42 end
43 end
44
45 def run
46 return [] if !@patches || @patches.count.zero?
47
48 read_config
49
50 @patches
51 .select { |patch| patch.additions > 0 }
52 .select { |patch| hs_file?(patch.new_file_full_path) }
53 .map { |patch| inspect(patch) }
54 .flatten.compact
55 end
56
57 private
58
59 def repo_path
60 @repo_path ||= @patches.first.repo.path
61 end
62
63 def inspect(patch)
64 offences = run_hlint(patch)
65 offences
66 .map do |offence|
67 patch
68 .added_lines
69 .select { |line| (offence['startLine']..offence['endLine']).include?(line.new_lineno) }
70 .map { |line| new_message(offence, line) }
71 end
72 end
73
74 def new_message(offence, line)
75 path = line.patch.delta.new_file[:path]
76 level = hlint_severity_to_pronto_level(offence['severity']) || :warning
77
78 text = <<~EOF
79 #{offence['severity']} offence detected by Hlint. Hint is: `#{offence['hint']}`.
80
81 Consider changing the code from
82 ```
83 #{offence['from']}
84 ```
85 to
86 ```
87 #{offence['to']}
88 ```
89 EOF
90
91 Message.new(path, line, level, text, nil, self.class)
92 end
93
94 def hlint_severity_to_pronto_level(severity)
95 case severity
96 when "Error"
97 :error
98 when "Warning"
99 :warning
100 when "Suggestion"
101 :info
102 end
103 end
104
105 def hs_file?(path)
106 files_to_lint =~ path.to_s
107 end
108
109 def run_hlint(patch)
110 Dir.chdir(repo_path) do
111 JSON.parse `#{hlint_command_line(patch.new_file_full_path.to_s)}`
112 end
113 end
114
115 def hlint_command_line(path)
116 "#{hlint_executable} #{cmd_line_opts} #{Shellwords.escape(path)} --json"
117 end
118 end
119 end
120end
diff --git a/lib/pronto/hlint/version.rb b/lib/pronto/hlint/version.rb
new file mode 100644
index 0000000..0b9bd5a
--- /dev/null
+++ b/lib/pronto/hlint/version.rb
@@ -0,0 +1,7 @@
1# frozen_string_literal: true
2
3module Pronto
4 module Hlint
5 VERSION = '0.1.0'.freeze
6 end
7end