codeclimate 0.69.0 → 0.70.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/prep-release +1 -1
- data/config/engines.yml +32 -323
- data/lib/cc/analyzer.rb +5 -4
- data/lib/cc/analyzer/bridge.rb +106 -0
- data/lib/cc/analyzer/composite_container_listener.rb +4 -8
- data/lib/cc/analyzer/container.rb +44 -41
- data/lib/cc/analyzer/container/result.rb +74 -0
- data/lib/cc/analyzer/container_listener.rb +2 -7
- data/lib/cc/analyzer/engine.rb +53 -45
- data/lib/cc/analyzer/engine_output.rb +40 -10
- data/lib/cc/analyzer/formatters/formatter.rb +2 -0
- data/lib/cc/analyzer/formatters/html_formatter.rb +4 -0
- data/lib/cc/analyzer/formatters/json_formatter.rb +1 -0
- data/lib/cc/analyzer/formatters/plain_text_formatter.rb +8 -1
- data/lib/cc/analyzer/issue.rb +4 -2
- data/lib/cc/analyzer/issue_validations/relative_path_validation.rb +6 -2
- data/lib/cc/analyzer/issue_validator.rb +3 -32
- data/lib/cc/analyzer/logging_container_listener.rb +9 -7
- data/lib/cc/analyzer/measurement.rb +22 -0
- data/lib/cc/analyzer/measurement_validations.rb +16 -0
- data/lib/cc/analyzer/measurement_validations/name_validation.rb +23 -0
- data/lib/cc/analyzer/measurement_validations/type_validation.rb +15 -0
- data/lib/cc/analyzer/measurement_validations/validation.rb +27 -0
- data/lib/cc/analyzer/measurement_validations/value_validation.rb +21 -0
- data/lib/cc/analyzer/measurement_validator.rb +11 -0
- data/lib/cc/analyzer/raising_container_listener.rb +18 -18
- data/lib/cc/analyzer/statsd_container_listener.rb +22 -22
- data/lib/cc/analyzer/validator.rb +38 -0
- data/lib/cc/cli.rb +12 -12
- data/lib/cc/cli/analyze.rb +42 -60
- data/lib/cc/cli/analyze/engine_failure.rb +11 -0
- data/lib/cc/cli/command.rb +0 -10
- data/lib/cc/cli/engines.rb +0 -3
- data/lib/cc/cli/engines/engine_command.rb +2 -34
- data/lib/cc/cli/engines/install.rb +11 -17
- data/lib/cc/cli/engines/list.rb +5 -3
- data/lib/cc/cli/prepare.rb +5 -11
- data/lib/cc/cli/runner.rb +1 -2
- data/lib/cc/cli/test.rb +0 -1
- data/lib/cc/cli/validate_config.rb +49 -63
- data/lib/cc/cli/version_checker.rb +3 -3
- data/lib/cc/config.rb +70 -0
- data/lib/cc/config/checks_adapter.rb +40 -0
- data/lib/cc/config/default_adapter.rb +52 -0
- data/lib/cc/config/engine.rb +41 -0
- data/lib/cc/config/engine_set.rb +47 -0
- data/lib/cc/config/json_adapter.rb +17 -0
- data/lib/cc/config/prepare.rb +92 -0
- data/lib/cc/config/validation/check_validator.rb +34 -0
- data/lib/cc/config/validation/engine_validator.rb +89 -0
- data/lib/cc/config/validation/fetch_validator.rb +78 -0
- data/lib/cc/config/validation/file_validator.rb +112 -0
- data/lib/cc/config/validation/hash_validations.rb +52 -0
- data/lib/cc/config/validation/json.rb +31 -0
- data/lib/cc/config/validation/prepare_validator.rb +40 -0
- data/lib/cc/config/validation/yaml.rb +66 -0
- data/lib/cc/config/yaml_adapter.rb +73 -0
- data/lib/cc/engine_registry.rb +74 -0
- data/lib/cc/workspace/path_tree/dir_node.rb +1 -1
- metadata +36 -55
- data/bin/codeclimate-init +0 -6
- data/config/coffeelint/coffeelint.json +0 -129
- data/config/csslint/.csslintrc +0 -2
- data/config/eslint/.eslintignore +0 -1
- data/config/eslint/.eslintrc.yml +0 -277
- data/config/rubocop/.rubocop.yml +0 -1156
- data/lib/cc/analyzer/config.rb +0 -86
- data/lib/cc/analyzer/engine_registry.rb +0 -36
- data/lib/cc/analyzer/engines_config_builder.rb +0 -97
- data/lib/cc/analyzer/engines_runner.rb +0 -64
- data/lib/cc/cli/config.rb +0 -44
- data/lib/cc/cli/config_generator.rb +0 -108
- data/lib/cc/cli/engines/disable.rb +0 -38
- data/lib/cc/cli/engines/enable.rb +0 -41
- data/lib/cc/cli/engines/remove.rb +0 -35
- data/lib/cc/cli/init.rb +0 -117
- data/lib/cc/cli/prepare/quality.rb +0 -64
- 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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
data/lib/cc/analyzer/issue.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
4
|
+
include Validator
|
5
5
|
|
6
|
-
|
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(
|
5
|
-
@engine_name = engine_name
|
4
|
+
def initialize(logger)
|
6
5
|
@logger = logger
|
7
6
|
end
|
8
7
|
|
9
|
-
def started(
|
10
|
-
logger.info("starting engine #{
|
8
|
+
def started(engine, _details)
|
9
|
+
logger.info("starting engine #{engine.name}")
|
11
10
|
end
|
12
11
|
|
13
|
-
def finished(
|
14
|
-
logger.info("finished engine #{
|
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 :
|
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
|
@@ -1,32 +1,32 @@
|
|
1
1
|
module CC
|
2
2
|
module Analyzer
|
3
3
|
class RaisingContainerListener < ContainerListener
|
4
|
-
def initialize(
|
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
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
message
|
21
|
-
message << "
|
22
|
-
|
23
|
-
raise failure_ex,
|
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 :
|
29
|
+
attr_reader :failure_ex, :timeout_ex, :maximum_output_ex
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|