codeclimate 0.24.3 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d5ba7e27f0c2fcc953c2f14dc15ca0055ddf4d25
4
- data.tar.gz: 919f9784e1f9c9f22eb82168d6bdb8213082e8b3
3
+ metadata.gz: c732584b6855ac426cc7e0a19b4fb55375f7fcf5
4
+ data.tar.gz: 1678f0e4a32a532a7e871412e681ddaf7cc0f59a
5
5
  SHA512:
6
- metadata.gz: 9069df8ef0b536687fbac616f775b8e6723820dfc36f424eb49ef31e2ffef19b34bf8ecf172bc7947344b1328a116da992feecf20ef42ca9f6b8872083051676
7
- data.tar.gz: 87096921939b8b13fc5b00278cfc11d73dc74479878524712d5e955667a42ee05e3d18d9184cf99f4faa3a62d4d2900a6784277ee3c7c8dfa71f75a86c99a45c
6
+ metadata.gz: b091b7d2457a3aa89666baba5b3c789f1284854edc95c25a96a96571202aa3b2a35462568f8c93e924f1bced4cf90825864685d24e14988fed77a7d0a0e54afa
7
+ data.tar.gz: 4c2cc51abd7534ac166daffb627ce7a099118d18beb6816222d8b87060d2ed020d6a0d9283813aca5d7a556903206f9cc706dbe30fc806f79fa0c8066c700b94
data/lib/cc/analyzer.rb CHANGED
@@ -15,13 +15,22 @@ module CC
15
15
  autoload :Filesystem, "cc/analyzer/filesystem"
16
16
  autoload :Formatters, "cc/analyzer/formatters"
17
17
  autoload :Issue, "cc/analyzer/issue"
18
+ autoload :IssueCategoryValidation, "cc/analyzer/issue_category_validation"
19
+ autoload :IssueCheckNamePresenceValidation, "cc/analyzer/issue_check_name_presence_validation"
20
+ autoload :IssueDescriptionPresenceValidation, "cc/analyzer/issue_description_presence_validation"
21
+ autoload :IssuePathExistenceValidation, "cc/analyzer/issue_path_existence_validation"
22
+ autoload :IssuePathPresenceValidation, "cc/analyzer/issue_path_presence_validation"
23
+ autoload :IssueRelativePathValidation, "cc/analyzer/issue_relative_path_validation"
18
24
  autoload :IssueSorter, "cc/analyzer/issue_sorter"
25
+ autoload :IssueTypeValidation, "cc/analyzer/issue_type_validation"
26
+ autoload :IssueValidator, "cc/analyzer/issue_validator"
19
27
  autoload :LocationDescription, "cc/analyzer/location_description"
20
28
  autoload :LoggingContainerListener, "cc/analyzer/logging_container_listener"
21
29
  autoload :MountedPath, "cc/analyzer/mounted_path"
22
30
  autoload :RaisingContainerListener, "cc/analyzer/raising_container_listener"
23
31
  autoload :SourceBuffer, "cc/analyzer/source_buffer"
24
32
  autoload :StatsdContainerListener, "cc/analyzer/statsd_container_listener"
33
+ autoload :Validation, "cc/analyzer/validation"
25
34
 
26
35
  class DummyStatsd
27
36
  def method_missing(*)
@@ -5,11 +5,11 @@ module CC
5
5
  module Analyzer
6
6
  class Container
7
7
  ContainerData = Struct.new(
8
- :image, # image used to create the container
9
- :name, # name given to the container when created
10
- :duration, # duration, for a finished event
11
- :status, # status, for a finished event
12
- :stderr, # stderr, for a finished event
8
+ :image, # image used to create the container
9
+ :name, # name given to the container when created
10
+ :duration, # duration, for a finished event
11
+ :status, # status, for a finished event
12
+ :stderr, # stderr, for a finished event
13
13
  )
14
14
  ImageRequired = Class.new(StandardError)
15
15
  Result = Struct.new(
@@ -37,6 +37,11 @@ module CC
37
37
  CLI.debug("#{name} engine output: #{raw_output.strip}")
38
38
  output = EngineOutput.new(raw_output)
39
39
 
40
+ unless output.valid?
41
+ stdout_io.failed("#{name} produced invalid output: #{output.error[:message]}")
42
+ container.stop
43
+ end
44
+
40
45
  unless output_filter.filter?(output)
41
46
  stdout_io.write(output.to_json) || container.stop
42
47
  end
@@ -18,15 +18,27 @@ module CC
18
18
  Issue.new(raw_output)
19
19
  end
20
20
 
21
+ def valid?
22
+ validator.valid?
23
+ end
24
+
25
+ def error
26
+ validator.error
27
+ end
28
+
21
29
  private
22
30
 
23
31
  attr_accessor :raw_output
24
32
 
25
33
  def parsed_output
26
- JSON.parse(raw_output)
34
+ @parsed_output ||= JSON.parse(raw_output)
27
35
  rescue JSON::ParserError
28
36
  nil
29
37
  end
38
+
39
+ def validator
40
+ IssueValidator.new(parsed_output)
41
+ end
30
42
  end
31
43
  end
32
44
  end
@@ -12,7 +12,7 @@ module CC
12
12
  }.freeze
13
13
 
14
14
  def self.resolve(name)
15
- FORMATTERS[name.to_sym] or raise Formatter::InvalidFormatterError, "'#{name}' is not a valid formatter. Valid options are: #{FORMATTERS.keys.join(', ')}"
15
+ FORMATTERS[name.to_sym] or raise Formatter::InvalidFormatterError, "'#{name}' is not a valid formatter. Valid options are: #{FORMATTERS.keys.join(", ")}"
16
16
  end
17
17
  end
18
18
  end
@@ -20,7 +20,7 @@ module CC
20
20
  when "warning"
21
21
  warnings << json
22
22
  else
23
- raise "Invalid type found: #{json['type']}"
23
+ raise "Invalid type found: #{json["type"]}"
24
24
  end
25
25
  end
26
26
 
@@ -28,7 +28,7 @@ module CC
28
28
  puts
29
29
 
30
30
  issues_by_path.each do |path, file_issues|
31
- puts colorize("== #{path} (#{pluralize(file_issues.size, 'issue')}) ==", :yellow)
31
+ puts colorize("== #{path} (#{pluralize(file_issues.size, "issue")}) ==", :yellow)
32
32
 
33
33
  IssueSorter.new(file_issues).by_location.each do |issue|
34
34
  if (location = issue["location"])
@@ -37,15 +37,15 @@ module CC
37
37
  end
38
38
 
39
39
  print(issue["description"])
40
- print(colorize(" [#{issue['engine_name']}]", "#333333"))
40
+ print(colorize(" [#{issue["engine_name"]}]", "#333333"))
41
41
  puts
42
42
  end
43
43
  puts
44
44
  end
45
45
 
46
- print(colorize("Analysis complete! Found #{pluralize(issues.size, 'issue')}", :green))
46
+ print(colorize("Analysis complete! Found #{pluralize(issues.size, "issue")}", :green))
47
47
  if warnings.size > 0
48
- print(colorize(" and #{pluralize(warnings.size, 'warning')}", :green))
48
+ print(colorize(" and #{pluralize(warnings.size, "warning")}", :green))
49
49
  end
50
50
  puts(colorize(".", :green))
51
51
  end
@@ -0,0 +1,30 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssueCategoryValidation < Validation
4
+ CATEGORIES = [
5
+ "Bug Risk".freeze,
6
+ "Clarity".freeze,
7
+ "Compatibility".freeze,
8
+ "Complexity".freeze,
9
+ "Duplication".freeze,
10
+ "Performance".freeze,
11
+ "Security".freeze,
12
+ "Style".freeze,
13
+ ].freeze
14
+
15
+ def valid?
16
+ object["categories"].present? && no_invalid_categories?
17
+ end
18
+
19
+ def message
20
+ "Category must be at least one of #{CATEGORIES.join(", ")}"
21
+ end
22
+
23
+ private
24
+
25
+ def no_invalid_categories?
26
+ (CATEGORIES | object["categories"]) == CATEGORIES
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssueCheckNamePresenceValidation < Validation
4
+ def valid?
5
+ object["check_name"].present?
6
+ end
7
+
8
+ def message
9
+ "Check name must be present"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssueDescriptionPresenceValidation < Validation
4
+ def valid?
5
+ object["description"].present?
6
+ end
7
+
8
+ def message
9
+ "Description must be present"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssuePathExistenceValidation < Validation
4
+ def valid?
5
+ File.exist?(path)
6
+ end
7
+
8
+ def message
9
+ "File does not exist: '#{path}'"
10
+ end
11
+
12
+ private
13
+
14
+ def path
15
+ object.fetch("location", {}).fetch("path", "")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssuePathPresenceValidation < Validation
4
+ def valid?
5
+ path.present?
6
+ end
7
+
8
+ def message
9
+ "Path must be present"
10
+ end
11
+
12
+ private
13
+
14
+ def path
15
+ object.fetch("location", {})["path"]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssueRelativePathValidation < Validation
4
+ def valid?
5
+ path && !path.start_with?("/")
6
+ end
7
+
8
+ def message
9
+ "Path must be relative"
10
+ end
11
+
12
+ private
13
+
14
+ def path
15
+ object.fetch("location", {})["path"]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssueTypeValidation < Validation
4
+ def valid?
5
+ type && type.casecmp("issue").zero?
6
+ end
7
+
8
+ def message
9
+ "Type must be 'issue' but was '#{type}'"
10
+ end
11
+
12
+ private
13
+
14
+ def type
15
+ object["type"]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssueValidator
4
+ CHECKS = [
5
+ IssueCategoryValidation,
6
+ IssueCheckNamePresenceValidation,
7
+ IssueDescriptionPresenceValidation,
8
+ IssuePathExistenceValidation,
9
+ IssuePathPresenceValidation,
10
+ IssueRelativePathValidation,
11
+ IssueTypeValidation,
12
+ ].freeze
13
+
14
+ attr_reader :error
15
+
16
+ def initialize(issue)
17
+ @issue = issue
18
+ end
19
+
20
+ def valid?
21
+ return @valid unless @valid.nil?
22
+
23
+ if issue && invalid_messages.any?
24
+ @error = {
25
+ message: "#{invalid_messages.join("; ")}: `#{issue}`.",
26
+ issue: issue,
27
+ }
28
+ @valid = false
29
+ else
30
+ @valid = true
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :issue
37
+
38
+ def invalid_messages
39
+ @invalid_messages ||= CHECKS.each_with_object([]) do |check, result|
40
+ validator = check.new(issue)
41
+ result << validator.message unless validator.valid?
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ module CC
2
+ module Analyzer
3
+ class Validation
4
+ def initialize(object)
5
+ @object = object
6
+ end
7
+
8
+ def valid?
9
+ raise NotImplementedError
10
+ end
11
+
12
+ def message
13
+ raise NotImplementedError
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :object
19
+ end
20
+ end
21
+ end
@@ -13,7 +13,7 @@ module CC
13
13
  end
14
14
 
15
15
  def run
16
- $stderr.puts "unknown command #{self.class.name.split('::').last.underscore}"
16
+ $stderr.puts "unknown command #{self.class.name.split("::").last.underscore}"
17
17
  end
18
18
 
19
19
  def self.command_name
@@ -59,7 +59,7 @@ module CC
59
59
 
60
60
  def filesystem
61
61
  @filesystem ||= CC::Analyzer::Filesystem.new(
62
- CC::Analyzer::MountedPath.code.container_path
62
+ CC::Analyzer::MountedPath.code.container_path,
63
63
  )
64
64
  end
65
65
 
@@ -5,7 +5,7 @@ module CC
5
5
  def run
6
6
  say "Available engines:"
7
7
  engine_registry_list.sort_by { |name, _| name }.each do |name, attributes|
8
- say "- #{name}: #{attributes['description']}"
8
+ say "- #{name}: #{attributes["description"]}"
9
9
  end
10
10
  end
11
11
  end
data/lib/cc/cli/help.rb CHANGED
@@ -16,11 +16,11 @@ module CC
16
16
  [
17
17
  "analyze [-f format] [-e engine] <path>",
18
18
  "console",
19
- "engines:disable #{underline('engine_name')}",
20
- "engines:enable #{underline('engine_name')}",
19
+ "engines:disable #{underline("engine_name")}",
20
+ "engines:enable #{underline("engine_name")}",
21
21
  "engines:install",
22
22
  "engines:list",
23
- "engines:remove #{underline('engine_name')}",
23
+ "engines:remove #{underline("engine_name")}",
24
24
  "help",
25
25
  "init",
26
26
  "validate-config",
data/lib/cc/cli/runner.rb CHANGED
@@ -39,7 +39,7 @@ module CC
39
39
  def command_name
40
40
  case command
41
41
  when nil, "-h", "-?", "--help" then "Help"
42
- when "-v", "--version" then "Version"
42
+ when "-v", "--version" then "Version"
43
43
  else command.sub(":", "::").underscore.camelize
44
44
  end
45
45
  end
data/lib/cc/cli/test.rb CHANGED
@@ -72,7 +72,7 @@ module CC
72
72
  @engine_name = @args.first
73
73
 
74
74
  if @engine_name.blank?
75
- fatal "Usage: codeclimate test #{rainbow.wrap('engine_name').underline}"
75
+ fatal "Usage: codeclimate test #{rainbow.wrap("engine_name").underline}"
76
76
  end
77
77
 
78
78
  test_engine
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codeclimate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.3
4
+ version: 0.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code Climate
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-10 00:00:00.000000000 Z
11
+ date: 2016-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -168,13 +168,22 @@ files:
168
168
  - lib/cc/analyzer/formatters/plain_text_formatter.rb
169
169
  - lib/cc/analyzer/formatters/spinner.rb
170
170
  - lib/cc/analyzer/issue.rb
171
+ - lib/cc/analyzer/issue_category_validation.rb
172
+ - lib/cc/analyzer/issue_check_name_presence_validation.rb
173
+ - lib/cc/analyzer/issue_description_presence_validation.rb
174
+ - lib/cc/analyzer/issue_path_existence_validation.rb
175
+ - lib/cc/analyzer/issue_path_presence_validation.rb
176
+ - lib/cc/analyzer/issue_relative_path_validation.rb
171
177
  - lib/cc/analyzer/issue_sorter.rb
178
+ - lib/cc/analyzer/issue_type_validation.rb
179
+ - lib/cc/analyzer/issue_validator.rb
172
180
  - lib/cc/analyzer/location_description.rb
173
181
  - lib/cc/analyzer/logging_container_listener.rb
174
182
  - lib/cc/analyzer/mounted_path.rb
175
183
  - lib/cc/analyzer/raising_container_listener.rb
176
184
  - lib/cc/analyzer/source_buffer.rb
177
185
  - lib/cc/analyzer/statsd_container_listener.rb
186
+ - lib/cc/analyzer/validation.rb
178
187
  - lib/cc/cli.rb
179
188
  - lib/cc/cli/analyze.rb
180
189
  - lib/cc/cli/command.rb