codeclimate 0.69.0 → 0.70.0

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/bin/prep-release +1 -1
  3. data/config/engines.yml +32 -323
  4. data/lib/cc/analyzer.rb +5 -4
  5. data/lib/cc/analyzer/bridge.rb +106 -0
  6. data/lib/cc/analyzer/composite_container_listener.rb +4 -8
  7. data/lib/cc/analyzer/container.rb +44 -41
  8. data/lib/cc/analyzer/container/result.rb +74 -0
  9. data/lib/cc/analyzer/container_listener.rb +2 -7
  10. data/lib/cc/analyzer/engine.rb +53 -45
  11. data/lib/cc/analyzer/engine_output.rb +40 -10
  12. data/lib/cc/analyzer/formatters/formatter.rb +2 -0
  13. data/lib/cc/analyzer/formatters/html_formatter.rb +4 -0
  14. data/lib/cc/analyzer/formatters/json_formatter.rb +1 -0
  15. data/lib/cc/analyzer/formatters/plain_text_formatter.rb +8 -1
  16. data/lib/cc/analyzer/issue.rb +4 -2
  17. data/lib/cc/analyzer/issue_validations/relative_path_validation.rb +6 -2
  18. data/lib/cc/analyzer/issue_validator.rb +3 -32
  19. data/lib/cc/analyzer/logging_container_listener.rb +9 -7
  20. data/lib/cc/analyzer/measurement.rb +22 -0
  21. data/lib/cc/analyzer/measurement_validations.rb +16 -0
  22. data/lib/cc/analyzer/measurement_validations/name_validation.rb +23 -0
  23. data/lib/cc/analyzer/measurement_validations/type_validation.rb +15 -0
  24. data/lib/cc/analyzer/measurement_validations/validation.rb +27 -0
  25. data/lib/cc/analyzer/measurement_validations/value_validation.rb +21 -0
  26. data/lib/cc/analyzer/measurement_validator.rb +11 -0
  27. data/lib/cc/analyzer/raising_container_listener.rb +18 -18
  28. data/lib/cc/analyzer/statsd_container_listener.rb +22 -22
  29. data/lib/cc/analyzer/validator.rb +38 -0
  30. data/lib/cc/cli.rb +12 -12
  31. data/lib/cc/cli/analyze.rb +42 -60
  32. data/lib/cc/cli/analyze/engine_failure.rb +11 -0
  33. data/lib/cc/cli/command.rb +0 -10
  34. data/lib/cc/cli/engines.rb +0 -3
  35. data/lib/cc/cli/engines/engine_command.rb +2 -34
  36. data/lib/cc/cli/engines/install.rb +11 -17
  37. data/lib/cc/cli/engines/list.rb +5 -3
  38. data/lib/cc/cli/prepare.rb +5 -11
  39. data/lib/cc/cli/runner.rb +1 -2
  40. data/lib/cc/cli/test.rb +0 -1
  41. data/lib/cc/cli/validate_config.rb +49 -63
  42. data/lib/cc/cli/version_checker.rb +3 -3
  43. data/lib/cc/config.rb +70 -0
  44. data/lib/cc/config/checks_adapter.rb +40 -0
  45. data/lib/cc/config/default_adapter.rb +52 -0
  46. data/lib/cc/config/engine.rb +41 -0
  47. data/lib/cc/config/engine_set.rb +47 -0
  48. data/lib/cc/config/json_adapter.rb +17 -0
  49. data/lib/cc/config/prepare.rb +92 -0
  50. data/lib/cc/config/validation/check_validator.rb +34 -0
  51. data/lib/cc/config/validation/engine_validator.rb +89 -0
  52. data/lib/cc/config/validation/fetch_validator.rb +78 -0
  53. data/lib/cc/config/validation/file_validator.rb +112 -0
  54. data/lib/cc/config/validation/hash_validations.rb +52 -0
  55. data/lib/cc/config/validation/json.rb +31 -0
  56. data/lib/cc/config/validation/prepare_validator.rb +40 -0
  57. data/lib/cc/config/validation/yaml.rb +66 -0
  58. data/lib/cc/config/yaml_adapter.rb +73 -0
  59. data/lib/cc/engine_registry.rb +74 -0
  60. data/lib/cc/workspace/path_tree/dir_node.rb +1 -1
  61. metadata +36 -55
  62. data/bin/codeclimate-init +0 -6
  63. data/config/coffeelint/coffeelint.json +0 -129
  64. data/config/csslint/.csslintrc +0 -2
  65. data/config/eslint/.eslintignore +0 -1
  66. data/config/eslint/.eslintrc.yml +0 -277
  67. data/config/rubocop/.rubocop.yml +0 -1156
  68. data/lib/cc/analyzer/config.rb +0 -86
  69. data/lib/cc/analyzer/engine_registry.rb +0 -36
  70. data/lib/cc/analyzer/engines_config_builder.rb +0 -97
  71. data/lib/cc/analyzer/engines_runner.rb +0 -64
  72. data/lib/cc/cli/config.rb +0 -44
  73. data/lib/cc/cli/config_generator.rb +0 -108
  74. data/lib/cc/cli/engines/disable.rb +0 -38
  75. data/lib/cc/cli/engines/enable.rb +0 -41
  76. data/lib/cc/cli/engines/remove.rb +0 -35
  77. data/lib/cc/cli/init.rb +0 -117
  78. data/lib/cc/cli/prepare/quality.rb +0 -64
  79. data/lib/cc/cli/upgrade_config_generator.rb +0 -42
@@ -2,33 +2,59 @@ module CC
2
2
  module Analyzer
3
3
  class EngineOutput
4
4
  delegate :blank?, to: :raw_output
5
- delegate :to_json, to: :as_issue
6
5
 
7
- def initialize(raw_output)
6
+ def initialize(name, raw_output)
7
+ @name = name
8
8
  @raw_output = raw_output
9
9
  end
10
10
 
11
11
  def issue?
12
- parsed_output &&
13
- parsed_output["type"].present? &&
14
- parsed_output["type"].downcase == "issue"
12
+ valid_with_type?("issue")
13
+ end
14
+
15
+ def measurement?
16
+ valid_with_type?("measurement")
15
17
  end
16
18
 
17
19
  def as_issue
18
- Issue.new(raw_output)
20
+ Issue.new(name, raw_output)
21
+ end
22
+
23
+ def to_json
24
+ if issue?
25
+ as_issue.to_json
26
+ elsif measurement?
27
+ Measurement.new(name, raw_output).to_json
28
+ end
19
29
  end
20
30
 
21
31
  def valid?
22
- validator.valid?
32
+ valid_json? && validator && validator.valid?
23
33
  end
24
34
 
25
35
  def error
26
- validator.error
36
+ if !valid_json?
37
+ { message: "Invalid JSON", output: raw_output }
38
+ elsif !validator.present?
39
+ { message: "Unsupported document type", output: raw_output }
40
+ else
41
+ validator.error
42
+ end
27
43
  end
28
44
 
29
45
  private
30
46
 
31
- attr_accessor :raw_output
47
+ attr_accessor :name, :raw_output
48
+
49
+ def valid_json?
50
+ parsed_output.present?
51
+ end
52
+
53
+ def valid_with_type?(type)
54
+ parsed_output &&
55
+ parsed_output["type"].present? &&
56
+ parsed_output["type"].downcase == type
57
+ end
32
58
 
33
59
  def parsed_output
34
60
  @parsed_output ||= JSON.parse(raw_output)
@@ -37,7 +63,11 @@ module CC
37
63
  end
38
64
 
39
65
  def validator
40
- IssueValidator.new(parsed_output)
66
+ if issue?
67
+ IssueValidator.new(parsed_output)
68
+ elsif measurement?
69
+ MeasurementValidator.new(parsed_output)
70
+ end
41
71
  end
42
72
  end
43
73
  end
@@ -16,6 +16,8 @@ module CC
16
16
  issues << json
17
17
  when "warning"
18
18
  warnings << json
19
+ when "measurement"
20
+ measurements << json
19
21
  else
20
22
  raise "Invalid type found: #{json["type"]}"
21
23
  end
@@ -405,6 +405,10 @@ module CC
405
405
  def warnings
406
406
  @warnings ||= []
407
407
  end
408
+
409
+ def measurements
410
+ @measurements ||= []
411
+ end
408
412
  end
409
413
  end
410
414
  end
@@ -17,6 +17,7 @@ module CC
17
17
 
18
18
  def write(data)
19
19
  document = JSON.parse(data)
20
+ return unless document["type"] == "issue"
20
21
  document["engine_name"] = current_engine.name
21
22
 
22
23
  if @has_begun
@@ -38,7 +38,10 @@ module CC
38
38
 
39
39
  def engine_running(engine, &block)
40
40
  super(engine) do
41
- with_spinner("Running #{current_engine.name}: ", &block)
41
+ result = with_spinner("Running #{current_engine.name}: ", &block)
42
+ if result.skipped?
43
+ puts(colorize("Skipped #{current_engine.name}: #{result.stderr}", :yellow))
44
+ end
42
45
  end
43
46
  end
44
47
 
@@ -85,6 +88,10 @@ module CC
85
88
  @warnings ||= []
86
89
  end
87
90
 
91
+ def measurements
92
+ @measurements ||= []
93
+ end
94
+
88
95
  def pluralize(number, noun)
89
96
  "#{ActiveSupport::NumberHelper.number_to_delimited(number)} #{noun.pluralize(number)}"
90
97
  end
@@ -16,12 +16,14 @@ module CC
16
16
  type
17
17
  ]
18
18
 
19
- def initialize(output)
19
+ def initialize(engine_name, output)
20
+ @engine_name = engine_name
20
21
  @output = output
21
22
  end
22
23
 
23
24
  def as_json(*)
24
25
  parsed_output.reverse_merge!(
26
+ "engine_name" => engine_name,
25
27
  "fingerprint" => fingerprint,
26
28
  ).merge!("severity" => severity)
27
29
  end
@@ -43,7 +45,7 @@ module CC
43
45
 
44
46
  private
45
47
 
46
- attr_reader :output
48
+ attr_reader :engine_name, :output
47
49
 
48
50
  def default_fingerprint
49
51
  SourceFingerprint.new(self).compute
@@ -4,10 +4,14 @@ module CC
4
4
  module Analyzer
5
5
  module IssueValidations
6
6
  class RelativePathValidation < Validation
7
+ BUILDER_CODE_PATH = "/tmp/workspace/code".freeze
8
+
7
9
  def valid?
8
10
  path &&
9
- !path.start_with?("/") &&
10
- relative_to?(MountedPath.code.container_path)
11
+ !path.start_with?("/") && (
12
+ relative_to?(MountedPath.code.container_path) ||
13
+ relative_to?(BUILDER_CODE_PATH)
14
+ )
11
15
  end
12
16
 
13
17
  def message
@@ -1,39 +1,10 @@
1
1
  module CC
2
2
  module Analyzer
3
3
  class IssueValidator
4
- CHECKS = IssueValidations.validations.freeze
4
+ include Validator
5
5
 
6
- attr_reader :error
7
-
8
- def initialize(issue)
9
- @issue = issue
10
- validate
11
- end
12
-
13
- def validate
14
- return @valid unless @valid.nil?
15
-
16
- if issue && invalid_messages.any?
17
- @error = {
18
- message: "#{invalid_messages.join("; ")}: `#{issue}`.",
19
- issue: issue,
20
- }
21
- @valid = false
22
- else
23
- @valid = true
24
- end
25
- end
26
- alias valid? validate
27
-
28
- private
29
-
30
- attr_reader :issue
31
-
32
- def invalid_messages
33
- @invalid_messages ||= CHECKS.each_with_object([]) do |check, result|
34
- validator = check.new(issue)
35
- result << validator.message unless validator.valid?
36
- end
6
+ def self.validations
7
+ IssueValidations.validations
37
8
  end
38
9
  end
39
10
  end
@@ -1,22 +1,24 @@
1
1
  module CC
2
2
  module Analyzer
3
3
  class LoggingContainerListener < ContainerListener
4
- def initialize(engine_name, logger)
5
- @engine_name = engine_name
4
+ def initialize(logger)
6
5
  @logger = logger
7
6
  end
8
7
 
9
- def started(_data)
10
- logger.info("starting engine #{engine_name}")
8
+ def started(engine, _details)
9
+ logger.info("starting engine #{engine.name}")
11
10
  end
12
11
 
13
- def finished(_data)
14
- logger.info("finished engine #{engine_name}")
12
+ def finished(engine, _details, result)
13
+ logger.info("finished engine #{engine.name}")
14
+ if result.skipped?
15
+ logger.warn("skipped engine #{engine.name}: #{result.stderr}")
16
+ end
15
17
  end
16
18
 
17
19
  private
18
20
 
19
- attr_reader :engine_name, :logger
21
+ attr_reader :logger
20
22
  end
21
23
  end
22
24
  end
@@ -0,0 +1,22 @@
1
+ module CC
2
+ module Analyzer
3
+ class Measurement
4
+ def initialize(engine_name, output)
5
+ @engine_name = engine_name
6
+ @output = output
7
+ end
8
+
9
+ def as_json(*)
10
+ parsed_output.merge("engine_name" => engine_name)
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :engine_name, :output
16
+
17
+ def parsed_output
18
+ @parsed_output ||= JSON.parse(output)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ module CC
2
+ module Analyzer
3
+ module MeasurementValidations
4
+ autoload :NameValidation, "cc/analyzer/measurement_validations/name_validation"
5
+ autoload :TypeValidation, "cc/analyzer/measurement_validations/type_validation"
6
+ autoload :ValueValidation, "cc/analyzer/measurement_validations/value_validation"
7
+ autoload :Validation, "cc/analyzer/measurement_validations/validation"
8
+
9
+ def self.validations
10
+ constants.sort.map(&method(:const_get)).select do |klass|
11
+ klass.is_a?(Class) && klass.superclass == Validation
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module CC
2
+ module Analyzer
3
+ module MeasurementValidations
4
+ class NameValidation < Validation
5
+ REGEX = /^[A-Za-z0-9_\.\-]+$/
6
+
7
+ def valid?
8
+ name && name.is_a?(String) && REGEX.match?(name)
9
+ end
10
+
11
+ def message
12
+ "Name must be present and contain only letters, numbers, periods, hyphens, and underscores"
13
+ end
14
+
15
+ private
16
+
17
+ def name
18
+ object["name"]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ module CC
2
+ module Analyzer
3
+ module MeasurementValidations
4
+ class TypeValidation < Validation
5
+ def valid?
6
+ type && type.casecmp("measurement").zero?
7
+ end
8
+
9
+ def message
10
+ "Type must be 'measurement' but was '#{type}'"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ module CC
2
+ module Analyzer
3
+ module MeasurementValidations
4
+ class Validation
5
+ def initialize(object)
6
+ @object = object
7
+ end
8
+
9
+ def valid?
10
+ raise NotImplementedError
11
+ end
12
+
13
+ def message
14
+ raise NotImplementedError
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :object
20
+
21
+ def type
22
+ object["type"]
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ module CC
2
+ module Analyzer
3
+ module MeasurementValidations
4
+ class ValueValidation < Validation
5
+ def valid?
6
+ value && value.is_a?(Numeric)
7
+ end
8
+
9
+ def message
10
+ "Value must be present and numeric"
11
+ end
12
+
13
+ private
14
+
15
+ def value
16
+ object["value"]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ module CC
2
+ module Analyzer
3
+ class MeasurementValidator
4
+ include Validator
5
+
6
+ def self.validations
7
+ MeasurementValidations.validations
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,32 +1,32 @@
1
1
  module CC
2
2
  module Analyzer
3
3
  class RaisingContainerListener < ContainerListener
4
- def initialize(engine_name, failure_ex, timeout_ex)
5
- @engine_name = engine_name
4
+ def initialize(failure_ex, timeout_ex = nil, maximum_output_ex = nil)
6
5
  @failure_ex = failure_ex
7
- @timeout_ex = timeout_ex
6
+ @timeout_ex = timeout_ex || failure_ex
7
+ @maximum_output_ex = maximum_output_ex || failure_ex
8
8
  end
9
9
 
10
- def timed_out(data)
11
- message = "engine #{engine_name} ran for #{data.duration / 1000} seconds"
12
- message << " and was killed"
13
-
14
- raise timeout_ex, message
15
- end
16
-
17
- def finished(data)
18
- unless data.status.success?
19
- message = "engine #{engine_name} failed"
20
- message << " with status #{data.status.exitstatus}"
21
- message << " and stderr \n#{data.stderr}"
22
-
23
- raise failure_ex, message
10
+ def finished(engine, _details, result)
11
+ if result.timed_out?
12
+ message = "engine #{engine.name} ran for #{result.duration / 1000}"
13
+ message << " seconds and was killed"
14
+ raise timeout_ex.new(message, engine.name)
15
+ elsif result.maximum_output_exceeded?
16
+ message = "engine #{engine.name} produced too much output"
17
+ message << " (#{result.output_byte_count} bytes)"
18
+ raise maximum_output_ex.new(message, engine.name)
19
+ elsif result.exit_status.nonzero?
20
+ message = "engine #{engine.name} failed"
21
+ message << " with status #{result.exit_status}"
22
+ message << " and stderr \n#{result.stderr}"
23
+ raise failure_ex.new(message, engine.name)
24
24
  end
25
25
  end
26
26
 
27
27
  private
28
28
 
29
- attr_reader :engine_name, :failure_ex, :timeout_ex
29
+ attr_reader :failure_ex, :timeout_ex, :maximum_output_ex
30
30
  end
31
31
  end
32
32
  end