codeclimate-fede 0.85.23
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.
- checksums.yaml +7 -0
- data/bin/check +18 -0
- data/bin/codeclimate +21 -0
- data/bin/prep-release +45 -0
- data/bin/release +41 -0
- data/bin/validate-release +18 -0
- data/config/engines.yml +322 -0
- data/lib/cc/analyzer.rb +50 -0
- data/lib/cc/analyzer/bridge.rb +106 -0
- data/lib/cc/analyzer/composite_container_listener.rb +21 -0
- data/lib/cc/analyzer/container.rb +208 -0
- data/lib/cc/analyzer/container/result.rb +74 -0
- data/lib/cc/analyzer/container_listener.rb +9 -0
- data/lib/cc/analyzer/engine.rb +125 -0
- data/lib/cc/analyzer/engine_output.rb +74 -0
- data/lib/cc/analyzer/engine_output_filter.rb +36 -0
- data/lib/cc/analyzer/engine_output_overrider.rb +31 -0
- data/lib/cc/analyzer/filesystem.rb +50 -0
- data/lib/cc/analyzer/formatters.rb +21 -0
- data/lib/cc/analyzer/formatters/formatter.rb +53 -0
- data/lib/cc/analyzer/formatters/html_formatter.rb +415 -0
- data/lib/cc/analyzer/formatters/json_formatter.rb +38 -0
- data/lib/cc/analyzer/formatters/plain_text_formatter.rb +101 -0
- data/lib/cc/analyzer/formatters/spinner.rb +35 -0
- data/lib/cc/analyzer/issue.rb +69 -0
- data/lib/cc/analyzer/issue_sorter.rb +30 -0
- data/lib/cc/analyzer/issue_validations.rb +26 -0
- data/lib/cc/analyzer/issue_validations/category_validation.rb +32 -0
- data/lib/cc/analyzer/issue_validations/check_name_presence_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/content_validation.rb +21 -0
- data/lib/cc/analyzer/issue_validations/description_presence_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/location_format_validation.rb +72 -0
- data/lib/cc/analyzer/issue_validations/other_locations_format_validation.rb +41 -0
- data/lib/cc/analyzer/issue_validations/path_existence_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/path_is_file_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/path_presence_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/relative_path_validation.rb +32 -0
- data/lib/cc/analyzer/issue_validations/remediation_points_validation.rb +25 -0
- data/lib/cc/analyzer/issue_validations/severity_validation.rb +39 -0
- data/lib/cc/analyzer/issue_validations/type_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/validation.rb +35 -0
- data/lib/cc/analyzer/issue_validator.rb +11 -0
- data/lib/cc/analyzer/location_description.rb +45 -0
- data/lib/cc/analyzer/logging_container_listener.rb +24 -0
- 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/mounted_path.rb +80 -0
- data/lib/cc/analyzer/raising_container_listener.rb +32 -0
- data/lib/cc/analyzer/source_buffer.rb +47 -0
- data/lib/cc/analyzer/source_extractor.rb +79 -0
- data/lib/cc/analyzer/source_fingerprint.rb +40 -0
- data/lib/cc/analyzer/statsd_container_listener.rb +51 -0
- data/lib/cc/analyzer/validator.rb +38 -0
- data/lib/cc/cli.rb +39 -0
- data/lib/cc/cli/analyze.rb +90 -0
- data/lib/cc/cli/analyze/engine_failure.rb +11 -0
- data/lib/cc/cli/command.rb +85 -0
- data/lib/cc/cli/console.rb +12 -0
- data/lib/cc/cli/engines.rb +5 -0
- data/lib/cc/cli/engines/engine_command.rb +15 -0
- data/lib/cc/cli/engines/install.rb +35 -0
- data/lib/cc/cli/engines/list.rb +18 -0
- data/lib/cc/cli/file_store.rb +42 -0
- data/lib/cc/cli/global_cache.rb +47 -0
- data/lib/cc/cli/global_config.rb +35 -0
- data/lib/cc/cli/help.rb +51 -0
- data/lib/cc/cli/output.rb +34 -0
- data/lib/cc/cli/prepare.rb +98 -0
- data/lib/cc/cli/runner.rb +75 -0
- data/lib/cc/cli/validate_config.rb +84 -0
- data/lib/cc/cli/version.rb +16 -0
- data/lib/cc/cli/version_checker.rb +107 -0
- data/lib/cc/config.rb +70 -0
- data/lib/cc/config/checks_adapter.rb +40 -0
- data/lib/cc/config/default_adapter.rb +54 -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 +93 -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/resolv.rb +39 -0
- data/lib/cc/workspace.rb +39 -0
- data/lib/cc/workspace/exclusion.rb +34 -0
- data/lib/cc/workspace/path_tree.rb +49 -0
- data/lib/cc/workspace/path_tree/dir_node.rb +67 -0
- data/lib/cc/workspace/path_tree/file_node.rb +31 -0
- metadata +277 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
module CC
|
|
2
|
+
class Config
|
|
3
|
+
module Validation
|
|
4
|
+
class FileValidator
|
|
5
|
+
include HashValidations
|
|
6
|
+
|
|
7
|
+
attr_reader :errors, :path, :warnings
|
|
8
|
+
|
|
9
|
+
def initialize(path, registry)
|
|
10
|
+
@path = path
|
|
11
|
+
@registry = registry
|
|
12
|
+
|
|
13
|
+
@errors = []
|
|
14
|
+
@warnings = []
|
|
15
|
+
|
|
16
|
+
validate
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def valid?
|
|
20
|
+
errors.none?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
attr_reader :data, :registry
|
|
26
|
+
|
|
27
|
+
def validate
|
|
28
|
+
raise NotImplementedError, "use a subclass"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def denormalize_subvalidator(validator, prefix)
|
|
32
|
+
validator.errors.each do |msg|
|
|
33
|
+
errors << "#{prefix}: #{msg}"
|
|
34
|
+
end
|
|
35
|
+
validator.warnings.each do |msg|
|
|
36
|
+
warnings << "#{prefix}: #{msg}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def validate_prepare
|
|
41
|
+
return unless validate_key_type("prepare", Hash)
|
|
42
|
+
|
|
43
|
+
validator = PrepareValidator.new(data.fetch("prepare", {}))
|
|
44
|
+
denormalize_subvalidator(validator, "prepare section")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def validate_engines(key, legacy: false)
|
|
48
|
+
return unless validate_key_type(key, Hash)
|
|
49
|
+
|
|
50
|
+
data.fetch(key, {}).each do |engine_name, engine_data|
|
|
51
|
+
engine_validator = EngineValidator.new(engine_data, legacy: legacy)
|
|
52
|
+
denormalize_subvalidator(engine_validator, "engine #{engine_name}")
|
|
53
|
+
|
|
54
|
+
if engine_validator.valid?
|
|
55
|
+
validate_engine_existence(engine_name, engine_data)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def validate_engine_existence(engine_name, engine_data)
|
|
61
|
+
if [true, false].include?(engine_data)
|
|
62
|
+
engine_data = {
|
|
63
|
+
"enabled" => true,
|
|
64
|
+
"channel" => Engine::DEFAULT_CHANNEL,
|
|
65
|
+
}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
engine = Engine.new(
|
|
69
|
+
engine_name,
|
|
70
|
+
enabled: engine_data.fetch("enabled", true),
|
|
71
|
+
channel: engine_data["channel"],
|
|
72
|
+
config: engine_data["config"],
|
|
73
|
+
)
|
|
74
|
+
unless engine_exists?(engine)
|
|
75
|
+
warnings << "unknown engine or channel <#{engine.name}:#{engine.channel}>"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def engine_exists?(engine)
|
|
80
|
+
!registry.fetch_engine_details(engine).nil?
|
|
81
|
+
rescue CC::EngineRegistry::EngineDetailsNotFoundError
|
|
82
|
+
false
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def validate_checks
|
|
86
|
+
return unless validate_key_type("checks", Hash)
|
|
87
|
+
|
|
88
|
+
data.fetch("checks", {}).each do |check_name, check_data|
|
|
89
|
+
validator = CheckValidator.new(check_data)
|
|
90
|
+
denormalize_subvalidator(validator, "check #{check_name}")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def validate_exclude_pattern(key, legacy: false)
|
|
95
|
+
types =
|
|
96
|
+
if legacy
|
|
97
|
+
[Array, String]
|
|
98
|
+
else
|
|
99
|
+
Array
|
|
100
|
+
end
|
|
101
|
+
return unless validate_key_type(key, types)
|
|
102
|
+
|
|
103
|
+
Array(data.fetch(key, [])).each do |pattern|
|
|
104
|
+
unless pattern.is_a?(String)
|
|
105
|
+
errors << "each exclude pattern should be a string, but '#{pattern.inspect}' is a #{pattern.class.to_s.downcase}"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module CC
|
|
2
|
+
class Config
|
|
3
|
+
module Validation
|
|
4
|
+
module HashValidations
|
|
5
|
+
def validate_hash_data
|
|
6
|
+
unless data.is_a?(Hash)
|
|
7
|
+
errors << "Config file should contain a hash, not a #{data.class.to_s.downcase}"
|
|
8
|
+
return false
|
|
9
|
+
end
|
|
10
|
+
true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def validate_key_type(key, types)
|
|
14
|
+
if types.is_a?(Class)
|
|
15
|
+
return validate_key_type(key, [types])
|
|
16
|
+
elsif data.key?(key)
|
|
17
|
+
unless types.include?(data[key].class)
|
|
18
|
+
errors << key_type_error_message(key, types)
|
|
19
|
+
return false
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def key_type_error_message(key, types)
|
|
26
|
+
if types.one?
|
|
27
|
+
klass_name = types[0].to_s.downcase
|
|
28
|
+
article =
|
|
29
|
+
if klass_name[0] == "a"
|
|
30
|
+
"an"
|
|
31
|
+
else
|
|
32
|
+
"a"
|
|
33
|
+
end
|
|
34
|
+
"'#{key}' must be #{article} #{klass_name}"
|
|
35
|
+
elsif types == [TrueClass, FalseClass]
|
|
36
|
+
"'#{key}' must be a boolean"
|
|
37
|
+
else
|
|
38
|
+
type_names = types.map(&:to_s).map(&:downcase)
|
|
39
|
+
"'#{key}' must be one of #{type_names.join(", ")}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def warn_unrecognized_keys(recognized_keys)
|
|
44
|
+
unknown_keys = data.keys.reject { |k| recognized_keys.include?(k) }
|
|
45
|
+
unknown_keys.each do |key|
|
|
46
|
+
warnings << "unrecognized key '#{key}'"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module CC
|
|
2
|
+
class Config
|
|
3
|
+
module Validation
|
|
4
|
+
class JSON < FileValidator
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def validate
|
|
8
|
+
@data = ::JSON.parse(File.read(path))
|
|
9
|
+
|
|
10
|
+
return unless validate_hash_data
|
|
11
|
+
|
|
12
|
+
validate_version
|
|
13
|
+
validate_prepare
|
|
14
|
+
validate_engines("plugins")
|
|
15
|
+
validate_checks
|
|
16
|
+
validate_exclude_pattern("exclude_patterns")
|
|
17
|
+
|
|
18
|
+
warn_unrecognized_keys(%w[checks prepare plugins exclude_patterns version])
|
|
19
|
+
rescue ::JSON::ParserError => ex
|
|
20
|
+
errors << "Unable to parse: #{ex.message}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def validate_version
|
|
24
|
+
unless data.key?("version")
|
|
25
|
+
warnings << %(missing 'version' key. Please add `"version": "2"`)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module CC
|
|
2
|
+
class Config
|
|
3
|
+
module Validation
|
|
4
|
+
class PrepareValidator
|
|
5
|
+
include HashValidations
|
|
6
|
+
|
|
7
|
+
attr_reader :errors, :warnings
|
|
8
|
+
|
|
9
|
+
def initialize(data)
|
|
10
|
+
@data = data
|
|
11
|
+
|
|
12
|
+
@errors = []
|
|
13
|
+
@warnings = []
|
|
14
|
+
|
|
15
|
+
validate
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_reader :data
|
|
21
|
+
|
|
22
|
+
def validate
|
|
23
|
+
return unless validate_key_type("fetch", Array)
|
|
24
|
+
|
|
25
|
+
data.fetch("fetch", []).each do |fetch_data|
|
|
26
|
+
validator = FetchValidator.new(fetch_data)
|
|
27
|
+
validator.errors.each do |msg|
|
|
28
|
+
errors << msg
|
|
29
|
+
end
|
|
30
|
+
validator.warnings.each do |msg|
|
|
31
|
+
warnings << msg
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
warn_unrecognized_keys(%w[fetch])
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module CC
|
|
2
|
+
class Config
|
|
3
|
+
module Validation
|
|
4
|
+
class YAML < FileValidator
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def validate
|
|
8
|
+
@data = ::YAML.safe_load(File.read(path))
|
|
9
|
+
|
|
10
|
+
return unless validate_hash_data
|
|
11
|
+
|
|
12
|
+
validate_version
|
|
13
|
+
validate_prepare
|
|
14
|
+
|
|
15
|
+
validate_one_of(%w[engines plugins])
|
|
16
|
+
validate_one_of(%w[exclude_paths exclude_patterns])
|
|
17
|
+
|
|
18
|
+
validate_engines("engines", legacy: true)
|
|
19
|
+
validate_engines("plugins")
|
|
20
|
+
|
|
21
|
+
validate_checks
|
|
22
|
+
|
|
23
|
+
validate_exclude_pattern("exclude_patterns")
|
|
24
|
+
validate_exclude_pattern("exclude_paths", legacy: true)
|
|
25
|
+
|
|
26
|
+
deprecated_key_warnings
|
|
27
|
+
warn_unrecognized_keys(%w[checks prepare engines plugins ratings languages exclude_paths exclude_patterns version])
|
|
28
|
+
rescue Psych::SyntaxError => ex
|
|
29
|
+
errors << "Unable to parse: #{ex.message}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def validate_version
|
|
33
|
+
if !data.key?("version") && (data.key?("plugins") || data.key?("exclude_patterns"))
|
|
34
|
+
warnings << %(missing 'version' key. Please add `version: "2"`)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def validate_one_of(keys)
|
|
39
|
+
num = keys.map { |k| data.key?(k) }.select(&:present?).count
|
|
40
|
+
if num > 1
|
|
41
|
+
wrapped_keys = keys.map { |k| "'#{k}'" }
|
|
42
|
+
errors << "only use one of #{wrapped_keys.join(", ")}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def deprecated_key_warnings
|
|
47
|
+
deprecate_key("engines", "plugins")
|
|
48
|
+
deprecate_key("exclude_paths", "exclude_patterns")
|
|
49
|
+
deprecate_key("languages")
|
|
50
|
+
deprecate_key("ratings")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def deprecate_key(key, new_key = nil)
|
|
54
|
+
if data.key?(key)
|
|
55
|
+
warnings <<
|
|
56
|
+
if new_key.nil?
|
|
57
|
+
"'#{key}' has been deprecated, and will not be used"
|
|
58
|
+
else
|
|
59
|
+
"'#{key}' has been deprecated, please use '#{new_key}' instead"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module CC
|
|
2
|
+
class Config
|
|
3
|
+
class YAMLAdapter
|
|
4
|
+
DEFAULT_PATH = ".codeclimate.yml".freeze
|
|
5
|
+
|
|
6
|
+
attr_reader :config
|
|
7
|
+
|
|
8
|
+
def self.load(path = DEFAULT_PATH)
|
|
9
|
+
new(::YAML.safe_load(File.read(path)))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(yaml = {})
|
|
13
|
+
@config = yaml || {}
|
|
14
|
+
|
|
15
|
+
upconvert_legacy_yaml!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def coerce_engine(data)
|
|
21
|
+
if [true, false].include?(data)
|
|
22
|
+
{ "enabled" => data }
|
|
23
|
+
elsif data.is_a?(Hash)
|
|
24
|
+
data
|
|
25
|
+
else
|
|
26
|
+
{}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Many of our plugins still expect:
|
|
31
|
+
#
|
|
32
|
+
# { config: PATH }
|
|
33
|
+
#
|
|
34
|
+
# But we document, and hope to eventually move to:
|
|
35
|
+
#
|
|
36
|
+
# { config: { file: PATH } }
|
|
37
|
+
#
|
|
38
|
+
# We need to munge from the latter to the former when/if we encounter it
|
|
39
|
+
def convert_to_legacy_file_config(config)
|
|
40
|
+
if config.is_a?(Hash) && config.keys.one? && config.key?("file")
|
|
41
|
+
config["file"]
|
|
42
|
+
else
|
|
43
|
+
config
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def upconvert_legacy_yaml!
|
|
48
|
+
config.delete("ratings")
|
|
49
|
+
|
|
50
|
+
if config.key?("engines")
|
|
51
|
+
config["plugins"] ||= config.delete("engines")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
plugins = config.fetch("plugins", {})
|
|
55
|
+
plugins.each do |engine, data|
|
|
56
|
+
plugins[engine] = coerce_engine(data)
|
|
57
|
+
if plugins.fetch(engine)["exclude_paths"]
|
|
58
|
+
plugins.fetch(engine)["exclude_patterns"] ||= Array(plugins.fetch(engine).delete("exclude_paths"))
|
|
59
|
+
end
|
|
60
|
+
if plugins.fetch(engine)["config"]
|
|
61
|
+
plugins.fetch(engine)["config"] = convert_to_legacy_file_config(
|
|
62
|
+
plugins.fetch(engine).fetch("config"),
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if config.key?("exclude_paths")
|
|
68
|
+
config["exclude_patterns"] ||= Array(config.delete("exclude_paths"))
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module CC
|
|
2
|
+
class EngineRegistry
|
|
3
|
+
include Enumerable
|
|
4
|
+
|
|
5
|
+
DEFAULT_MEMORY_LIMIT = 1_024_000_000
|
|
6
|
+
DEFAULT_COMMAND = nil
|
|
7
|
+
DEFAULT_MANIFEST_PATH = File.expand_path("../../../config/engines.yml", __FILE__)
|
|
8
|
+
|
|
9
|
+
EngineDetails = Struct.new(:image, :command, :description, :memory)
|
|
10
|
+
EngineDetailsNotFoundError = Class.new(StandardError)
|
|
11
|
+
|
|
12
|
+
def initialize(path = DEFAULT_MANIFEST_PATH, prefix = nil)
|
|
13
|
+
@yaml = YAML.safe_load(File.read(path))
|
|
14
|
+
@prefix = prefix || ENV["CODECLIMATE_PREFIX"] || ""
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def each
|
|
18
|
+
yaml.each do |name, metadata|
|
|
19
|
+
engine = Config::Engine.new(
|
|
20
|
+
name,
|
|
21
|
+
channel: metadata.fetch("channels").keys.first,
|
|
22
|
+
)
|
|
23
|
+
engine_details = fetch_engine_details(engine)
|
|
24
|
+
|
|
25
|
+
yield(engine, engine_details)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def fetch_engine_details(engine, development: false)
|
|
30
|
+
if development
|
|
31
|
+
EngineDetails.new("codeclimate/codeclimate-#{engine.name}", nil, "")
|
|
32
|
+
else
|
|
33
|
+
metadata = yaml.fetch(engine.name)
|
|
34
|
+
channels = metadata.fetch("channels")
|
|
35
|
+
|
|
36
|
+
EngineDetails.new(
|
|
37
|
+
[prefix, channels.fetch(engine.channel)].join,
|
|
38
|
+
metadata.fetch("command", DEFAULT_COMMAND),
|
|
39
|
+
metadata.fetch("description", "(No description available)"),
|
|
40
|
+
memory_limit(metadata["minimum_memory_limit"]),
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
rescue KeyError
|
|
44
|
+
raise EngineDetailsNotFoundError, not_found_message(engine, channels)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
attr_reader :yaml, :prefix
|
|
50
|
+
|
|
51
|
+
def memory_limit(minimum_memory_limit)
|
|
52
|
+
[
|
|
53
|
+
minimum_memory_limit.to_i,
|
|
54
|
+
default_memory_limit.to_i,
|
|
55
|
+
].max
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def default_memory_limit
|
|
59
|
+
ENV["ENGINE_MEMORY_LIMIT_BYTES"] || DEFAULT_MEMORY_LIMIT
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def not_found_message(engine, available_channels)
|
|
63
|
+
if available_channels
|
|
64
|
+
# Known engine, unknown channel
|
|
65
|
+
"Channel #{engine.channel} not found" \
|
|
66
|
+
" for #{engine.name}," \
|
|
67
|
+
" available channels: #{available_channels.keys.inspect}"
|
|
68
|
+
else
|
|
69
|
+
# Unknown engine
|
|
70
|
+
"No engine named #{engine.name} found"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|