maximus 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,6 @@ module Maximus
11
11
  module Helper
12
12
 
13
13
  # See if project linted is a Rails app
14
- #
15
14
  # This will usually be stored as a class variable in the inherited class
16
15
  # @return [Boolean]
17
16
  def is_rails?
@@ -19,7 +18,6 @@ module Maximus
19
18
  end
20
19
 
21
20
  # Get root directory of file being called
22
- #
23
21
  # @return [String] absolute path to root directory
24
22
  def root_dir
25
23
  is_rails? ? Rails.root.to_s : Dir.pwd.to_s
@@ -31,13 +29,9 @@ module Maximus
31
29
  # @param install_instructions [String] how to install the missing command
32
30
  # @return [void] aborts the action if command not found
33
31
  def node_module_exists(command, install_instructions = 'npm install -g')
34
- cmd = `if hash #{command} 2>/dev/null; then
35
- echo "true"
36
- else
37
- echo "false"
38
- fi`
32
+ cmd = `if hash #{command} 2>/dev/null; then echo "true"; else echo "false"; fi`
39
33
  if cmd.include? "false"
40
- command_msg = "Missing command #{command}".color(:red)
34
+ command_msg = "Missing command #{command}"
41
35
  abort "#{command_msg}: Please run `#{install_instructions} #{command}` And try again\n"
42
36
  exit 1
43
37
  end
@@ -49,11 +43,10 @@ module Maximus
49
43
  # @param file [String] filename with extension to search for
50
44
  # @return [String] path to default config file or file in user's directory
51
45
  def check_default_config_path(file)
52
- File.exist?(file) ? file : File.join(File.dirname(__FILE__), "config/#{file}")
46
+ File.exist?(file) ? file : File.join(File.dirname(__FILE__), file)
53
47
  end
54
48
 
55
49
  # Grab the absolute path of the reporter file
56
- #
57
50
  # @param filename [String]
58
51
  # @return [String] absolute path to the reporter file
59
52
  def reporter_path(filename)
@@ -82,16 +75,14 @@ module Maximus
82
75
  end
83
76
 
84
77
  # Convert string to boolean
85
- #
86
78
  # @param str [String] the string to evaluate
87
79
  # @return [Boolean] whether or not the string is true
88
- def truthy(str)
80
+ def truthy?(str)
89
81
  return true if str == true || str =~ (/^(true|t|yes|y|1)$/i)
90
82
  return false if str == false || str.blank? || str =~ (/^(false|f|no|n|0)$/i)
91
83
  end
92
84
 
93
85
  # Edit and save a YAML file
94
- #
95
86
  # @param yaml_location [String] YAML absolute file path
96
87
  # @return [void]
97
88
  def edit_yaml(yaml_location, &block)
@@ -101,7 +92,6 @@ module Maximus
101
92
  end
102
93
 
103
94
  # Request user input
104
- #
105
95
  # @param args [Array<String>] prompts to request
106
96
  # @return [String] user input to use elsewhere
107
97
  def prompt(*args)
@@ -115,17 +105,10 @@ module Maximus
115
105
  # @see Lint#relevant_lint
116
106
  #
117
107
  # @example typical output
118
- # lines_added = {'filename' => ['0..10', '11..14']}
108
+ # lines_added = {changes: ['0..10', '11..14']}
119
109
  # lines_added_to_range(lines_added)
120
110
  # # output
121
- # {
122
- # 'filename': {
123
- # {
124
- # [0,1,2,3,4,5,6,7,8,9,10],
125
- # [11,12,13,14]
126
- # }
127
- # }
128
- # }
111
+ # [0,1,2,3,4,5,6,7,8,9,10, 11,12,13,14]
129
112
  #
130
113
  # @todo I'm sure there's a better way of doing this
131
114
  # @todo figure out a better place to put this than in Helper
@@ -136,10 +119,9 @@ module Maximus
136
119
  end
137
120
 
138
121
  # Ensure path exists
139
- #
140
122
  # @param path [String, Array] path to files can be directory or glob
141
123
  # @return [Boolean]
142
- def path_exists(path = @path)
124
+ def path_exists?(path = @path)
143
125
  path = path.split(' ') if path.is_a?(String) && path.include?(' ')
144
126
  if path.is_a?(Array)
145
127
  path.each do |p|
@@ -20,7 +20,7 @@ module Maximus
20
20
  # lint_data = JSON.parse(`some-command-line-linter`)
21
21
  # @output[:files_inspected] ||= files_inspected(extension, delimiter, base_path_replacement)
22
22
  # refine data_from_output
23
- # end
23
+ # end
24
24
  #
25
25
  # Inherits settings from {Config#initialize}
26
26
  # @see Config#initialize
@@ -45,10 +45,10 @@ module Maximus
45
45
  end
46
46
 
47
47
  # Convert raw data into warnings, errors, conventions or refactors. Use this wisely.
48
- #
49
48
  # @param data [Hash] unfiltered lint data
50
49
  # @return [Hash] refined lint data and all the other bells and whistles
51
50
  def refine(data)
51
+
52
52
  # Prevent abortive empty JSON.parse error
53
53
  data = '{}' if data.blank?
54
54
  return puts "Error from #{@task}: #{data}" if data.is_a?(String) && data.include?('No such')
@@ -60,48 +60,19 @@ module Maximus
60
60
  data = @output[:relevant_lints]
61
61
  end
62
62
 
63
- lint_warnings = []
64
- lint_errors = []
65
- lint_conventions = []
66
- lint_refactors = []
67
- unless data.blank?
68
- data.each do |filename, error_list|
69
- error_list.each do |message|
70
- # so that :raw_data remains unaffected
71
- message = message.clone
72
- message.delete('length')
73
- message['filename'] = filename
74
- if message['severity'] == 'warning'
75
- message.delete('severity')
76
- lint_warnings << message
77
- elsif message['severity'] == 'error'
78
- message.delete('severity')
79
- lint_errors << message
80
- elsif message['severity'] == 'convention'
81
- message.delete('severity')
82
- lint_conventions << message
83
- elsif message['severity'] == 'refactor'
84
- message.delete('severity')
85
- lint_refactors << message
86
- end
87
- end
88
- end
89
- end
90
- @output[:lint_errors] = lint_errors
91
- @output[:lint_warnings] = lint_warnings
92
- @output[:lint_conventions] = lint_conventions
93
- @output[:lint_refactors] = lint_refactors
94
- lint_count = (lint_errors.length + lint_warnings.length + lint_conventions.length + lint_refactors.length)
63
+ evaluate_severities(data)
64
+
65
+ lint_count = (@output[:lint_errors].length + @output[:lint_warnings].length + @output[:lint_conventions].length + @output[:lint_refactors].length)
66
+
67
+ puts lint_summarize
68
+
95
69
  if @config.is_dev?
96
70
  puts lint_dev_format(data) unless data.blank?
97
- puts lint_summarize
98
71
  lint_ceiling lint_count
99
72
  else
100
- @config.log.info lint_summarize
101
73
  # Because this should be returned in the format it was received
102
74
  @output[:raw_data] = data.to_json
103
75
  end
104
- @config.destroy_temp(@task)
105
76
  @output
106
77
  end
107
78
 
@@ -109,7 +80,6 @@ module Maximus
109
80
  protected
110
81
 
111
82
  # List all files inspected
112
- #
113
83
  # @param ext [String] extension to search for
114
84
  # @param delimiter [String] comma or space separated
115
85
  # @param remove [String] remove from all file names
@@ -119,7 +89,6 @@ module Maximus
119
89
  end
120
90
 
121
91
  # Compare lint output with lines changed in commit
122
- #
123
92
  # @param lint [Hash] output lint data
124
93
  # @param files [Hash<String: String>] filename: filepath
125
94
  # @return [Array] lints that match the lines in commit
@@ -127,29 +96,25 @@ module Maximus
127
96
  all_files = {}
128
97
  files.each do |file|
129
98
 
130
- # sometimes data will be blank but this is good - it means no errors raised in the lint
131
- unless lint.blank?
132
- lint_file = lint[file[:filename].to_s]
133
-
134
- expanded = lines_added_to_range(file)
135
- revert_name = file[:filename].gsub("#{@settings[:root_dir]}/", '')
136
- unless lint_file.blank?
137
- all_files[revert_name] = []
138
-
139
- # @todo originally I tried .map and delete_if, but this works,
140
- # and the other method didn't cover all bases.
141
- # Gotta be a better way to write this though
142
- lint_file.each do |l|
143
- if expanded.include?(l['line'].to_i)
144
- all_files[revert_name] << l
145
- end
99
+ # sometimes data will be blank but this is good - it means no errors were raised in the lint
100
+ next if lint.blank?
101
+ lint_file = lint[file[:filename].to_s]
102
+
103
+ expanded = lines_added_to_range(file)
104
+ revert_name = file[:filename].gsub("#{@settings[:root_dir]}/", '')
105
+ unless lint_file.blank?
106
+ all_files[revert_name] = []
107
+
108
+ # @todo originally I tried .map and delete_if, but this works,
109
+ # and the other method didn't cover all bases.
110
+ # Gotta be a better way to write this though
111
+ lint_file.each do |l|
112
+ if expanded.include?(l['line'].to_i)
113
+ all_files[revert_name] << l
146
114
  end
147
- # If there's nothing there, then it definitely isn't a relevant lint
148
- all_files.delete(revert_name) if all_files[revert_name].blank?
149
115
  end
150
- else
151
- # Optionally store the filename with a blank array
152
- # @example all_files[file[:filename].to_s.gsub("#{@settings[:root_dir]}/", '')] = []
116
+ # If there's nothing there, then it definitely isn't a relevant lint
117
+ all_files.delete(revert_name) if all_files[revert_name].blank?
153
118
  end
154
119
  end
155
120
  @output[:files_linted] = all_files.keys
@@ -157,7 +122,6 @@ module Maximus
157
122
  end
158
123
 
159
124
  # Look for a config defined from Config#initialize
160
- #
161
125
  # @since 0.1.2
162
126
  # @param search_for [String]
163
127
  # @return [String, Boolean] path to temp file
@@ -166,58 +130,72 @@ module Maximus
166
130
  @settings[search_for.to_sym].blank? ? false : @settings[search_for.to_sym]
167
131
  end
168
132
 
133
+ # Add severities to @output
134
+ # @since 0.1.5
135
+ # @param data [Hash]
136
+ def evaluate_severities(data)
137
+ @output[:lint_warnings] = []
138
+ @output[:lint_errors] = []
139
+ @output[:lint_conventions] = []
140
+ @output[:lint_refactors] = []
141
+ return if data.blank?
142
+ data.each do |filename, error_list|
143
+ error_list.each do |message|
144
+ # so that :raw_data remains unaffected
145
+ message = message.clone
146
+ message.delete('length')
147
+ message['filename'] = filename.nil? ? '' : filename.gsub("#{@settings[:root_dir]}/", '')
148
+ severity = message['severity']
149
+ message.delete('severity')
150
+ @output["lint_#{severity}s".to_sym] << message
151
+ end
152
+ end
153
+ return @output
154
+ end
155
+
169
156
 
170
157
  private
171
158
 
172
159
  # Send abbreviated results to console or to the log
173
- #
174
160
  # @return [String] console message to display
175
161
  def lint_summarize
176
- puts "\n" if @config.is_dev?
177
-
178
- puts "#{'Warning'.color(:red)}: #{@output[:lint_errors].length} errors found in #{@task.to_s}" if @output[:lint_errors].length > 0
162
+ puts "#{'Warning'.color(:red)}: #{@output[:lint_errors].length} errors found in #{@task}" unless @output[:lint_errors].length
179
163
 
180
164
  success = @task.to_s.color(:green)
181
165
  success += ": "
182
166
  success += "[#{@output[:lint_warnings].length}]".color(:yellow)
183
- success += " " + "[#{@output[:lint_errors].length}]".color(:red)
167
+ success += " [#{@output[:lint_errors].length}]".color(:red)
184
168
  if @task == 'rubocop'
185
- success += " " + "[#{@output[:lint_conventions].length}]".color(:cyan)
186
- success += " " + "[#{@output[:lint_refactors].length}]".color(:white)
169
+ success += " [#{@output[:lint_conventions].length}]".color(:cyan)
170
+ success += " [#{@output[:lint_refactors].length}]".color(:white)
187
171
  end
188
172
 
189
173
  success
190
174
  end
191
175
 
192
176
  # If there's just too much to handle, through a warning.
193
- #
194
177
  # @param lint_length [Integer] count of how many lints
195
178
  # @return [String] console message to display
196
179
  def lint_ceiling(lint_length)
197
- if lint_length > 100
198
- lint_dev_format
199
- failed_task = "#{@task}".color(:green)
200
- errors = Rainbow("#{lint_length} failures.").red
201
- errormsg = ["You wouldn't stand a chance in Rome.\nResolve thy errors and train with #{failed_task} again.", "The gods frown upon you, mortal.\n#{failed_task}. Again.", "Do not embarrass the city. Fight another day. Use #{failed_task}.", "You are without honor. Replenish it with another #{failed_task}.", "You will never claim the throne with a performance like that.", "Pompeii has been lost.", "A wise choice. Do not be discouraged from another #{failed_task}."].sample
202
- errormsg += "\n\n"
203
-
204
- go_on = prompt "\n#{errors} Continue? (y/n) "
205
- abort errormsg unless truthy(go_on)
206
- end
180
+ return unless lint_length > 100
181
+ failed_task = @task.color(:green)
182
+ errors = "#{lint_length} failures.".color(:red)
183
+ errormsg = ["You wouldn't stand a chance in Rome.\nResolve thy errors and train with #{failed_task} again.", "The gods frown upon you, mortal.\n#{failed_task}. Again.", "Do not embarrass the city. Fight another day. Use #{failed_task}.", "You are without honor. Replenish it with another #{failed_task}.", "You will never claim the throne with a performance like that.", "Pompeii has been lost.", "A wise choice. Do not be discouraged from another #{failed_task}."].sample
184
+ errormsg += "\n\n"
185
+
186
+ go_on = prompt "\n#{errors} Continue? (y/n) "
187
+ abort errormsg unless truthy?(go_on)
207
188
  end
208
189
 
209
190
  # Dev display, executed only when called from command line
210
- #
211
191
  # @param errors [Hash] data from lint
212
192
  # @return [String] console message to display
213
193
  def lint_dev_format(errors = @output[:raw_data])
214
194
  return if errors.blank?
215
195
  pretty_output = ''
216
196
  errors.each do |filename, error_list|
217
- pretty_output += "\n"
218
197
  filename = filename.gsub("#{@settings[:root_dir]}/", '')
219
- pretty_output += filename.color(:cyan).underline
220
- pretty_output += "\n"
198
+ pretty_output += "\n#{filename.color(:cyan).underline} \n"
221
199
  error_list.each do |message|
222
200
  pretty_output += case message['severity']
223
201
  when 'warning' then 'W'.color(:yellow)
@@ -226,15 +204,13 @@ module Maximus
226
204
  when 'refactor' then 'R'.color(:white)
227
205
  else '?'.color(:blue)
228
206
  end
229
- pretty_output += ' '
230
- pretty_output += message['line'].to_s.color(:blue)
231
- pretty_output += " #{message['linter'].color(:green)}: "
232
- pretty_output += message['reason']
233
- pretty_output += "\n"
207
+ pretty_output += " #{message['line'].to_s.color(:blue)} #{message['linter'].color(:green)}: #{message['reason']} \n"
234
208
  end
235
209
  end
236
210
  pretty_output
237
211
  end
238
212
 
213
+
214
+
239
215
  end
240
216
  end
@@ -3,19 +3,13 @@ module Maximus
3
3
  class Brakeman < Maximus::Lint
4
4
 
5
5
  # Brakeman (requires Rails)
6
- #
7
6
  # @see Lint#initialize
8
7
  def result
9
8
 
10
- return unless is_rails?
11
-
12
9
  @task = 'brakeman'
13
-
14
- return unless temp_config(@task)
15
-
16
10
  @path = @settings[:root_dir] if @path.blank?
17
11
 
18
- return unless path_exists(@path)
12
+ return unless is_rails? && temp_config(@task) && path_exists?(@path)
19
13
 
20
14
  tmp = Tempfile.new('brakeman')
21
15
  quietly { `brakeman #{@path} -f json -o #{tmp.path} -q` }
@@ -55,12 +49,11 @@ module Maximus
55
49
  private
56
50
 
57
51
  # Convert to {file:README.md Maximus format}
58
- #
59
52
  # @param error [Hash] lint error
60
53
  # @return [Hash]
61
54
  def hash_for_brakeman(error, type)
62
55
  {
63
- linter: error['warning_type'],
56
+ linter: error['warning_type'].delete(' '),
64
57
  severity: type.chomp('s'),
65
58
  reason: error['message'],
66
59
  column: 0,
@@ -3,16 +3,12 @@ module Maximus
3
3
  class Jshint < Maximus::Lint
4
4
 
5
5
  # JSHint (requires node module)
6
- #
7
6
  # @see Lint#initialize
8
7
  def result
9
8
  @task = 'jshint'
10
-
11
- return unless temp_config(@task)
12
-
13
9
  @path = is_rails? ? "#{@settings[:root_dir]}/app/assets" : "#{@settings[:root_dir]}source/assets" if @path.blank?
14
10
 
15
- return unless path_exists(@path)
11
+ return unless temp_config(@task) && path_exists?(@path)
16
12
 
17
13
  node_module_exists(@task)
18
14
 
@@ -3,19 +3,13 @@ module Maximus
3
3
  class Railsbp < Maximus::Lint
4
4
 
5
5
  # rails_best_practice (requires Rails)
6
- #
7
6
  # @see Lint#initialize
8
7
  def result
9
8
 
10
- return unless is_rails?
11
-
12
9
  @task = 'railsbp'
13
-
14
- return unless temp_config(@task)
15
-
16
10
  @path = @settings[:root_dir] if @path.blank?
17
11
 
18
- return unless path_exists(@path)
12
+ return unless is_rails? && temp_config(@task) && path_exists?(@path)
19
13
 
20
14
  tmp = Tempfile.new('railsbp')
21
15
  `rails_best_practices #{@path} -f json --output-file #{tmp.path}`
@@ -27,15 +21,13 @@ module Maximus
27
21
  rbj = JSON.parse(railsbp).group_by { |s| s['filename'] }
28
22
  railsbp = {}
29
23
  rbj.each do |file, errors|
30
- if file
31
- # This crazy gsub grapbs scrubs the absolute path from the filename
32
- railsbp[file.gsub(Rails.root.to_s, '')[1..-1].to_sym] = errors.map { |o| hash_for_railsbp(o) }
33
- end
24
+ next unless file
25
+
26
+ # This crazy gsub scrubs the absolute path from the filename
27
+ filename = file.gsub(Rails.root.to_s, '')[1..-1]
28
+ railsbp[filename] = errors.map { |o| hash_for_railsbp(o) }
29
+
34
30
  end
35
- # The output of railsbp is a mix of strings and symbols
36
- # but resetting the JSON like this standardizes everything.
37
- # @todo Better way to get around this?
38
- railsbp = JSON.parse(railsbp.to_json)
39
31
  end
40
32
 
41
33
  @output[:files_inspected] ||= files_inspected('rb', ' ')
@@ -46,16 +38,15 @@ module Maximus
46
38
  private
47
39
 
48
40
  # Convert to {file:README.md Maximus format}
49
- #
50
41
  # @param error [Hash] lint error
51
42
  # @return [Hash]
52
43
  def hash_for_railsbp(error)
53
44
  {
54
- linter: error['message'].gsub(/\((.*)\)/, '').strip.parameterize('_').camelize,
55
- severity: 'warning',
56
- reason: error['message'],
57
- column: 0,
58
- line: error['line_number'].to_i
45
+ 'linter' => error['message'].gsub(/\((.*)\)/, '').strip.parameterize('_').camelize,
46
+ 'severity' => 'warning',
47
+ 'reason' => error['message'],
48
+ 'column' => 0,
49
+ 'line' => error['line_number'].to_i
59
50
  }
60
51
  end
61
52