codeclimate-fede 0.85.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/bin/check +18 -0
  3. data/bin/codeclimate +21 -0
  4. data/bin/prep-release +45 -0
  5. data/bin/publish +47 -0
  6. data/bin/release +41 -0
  7. data/bin/validate-release +18 -0
  8. data/config/engines.yml +322 -0
  9. data/lib/cc/analyzer/bridge.rb +106 -0
  10. data/lib/cc/analyzer/composite_container_listener.rb +21 -0
  11. data/lib/cc/analyzer/container/result.rb +74 -0
  12. data/lib/cc/analyzer/container.rb +208 -0
  13. data/lib/cc/analyzer/container_listener.rb +9 -0
  14. data/lib/cc/analyzer/engine.rb +125 -0
  15. data/lib/cc/analyzer/engine_output.rb +74 -0
  16. data/lib/cc/analyzer/engine_output_filter.rb +36 -0
  17. data/lib/cc/analyzer/engine_output_overrider.rb +31 -0
  18. data/lib/cc/analyzer/filesystem.rb +50 -0
  19. data/lib/cc/analyzer/formatters/formatter.rb +53 -0
  20. data/lib/cc/analyzer/formatters/html_formatter.rb +415 -0
  21. data/lib/cc/analyzer/formatters/json_formatter.rb +38 -0
  22. data/lib/cc/analyzer/formatters/plain_text_formatter.rb +101 -0
  23. data/lib/cc/analyzer/formatters/spinner.rb +35 -0
  24. data/lib/cc/analyzer/formatters.rb +21 -0
  25. data/lib/cc/analyzer/issue.rb +69 -0
  26. data/lib/cc/analyzer/issue_sorter.rb +30 -0
  27. data/lib/cc/analyzer/issue_validations/category_validation.rb +32 -0
  28. data/lib/cc/analyzer/issue_validations/check_name_presence_validation.rb +15 -0
  29. data/lib/cc/analyzer/issue_validations/content_validation.rb +21 -0
  30. data/lib/cc/analyzer/issue_validations/description_presence_validation.rb +15 -0
  31. data/lib/cc/analyzer/issue_validations/location_format_validation.rb +72 -0
  32. data/lib/cc/analyzer/issue_validations/other_locations_format_validation.rb +41 -0
  33. data/lib/cc/analyzer/issue_validations/path_existence_validation.rb +15 -0
  34. data/lib/cc/analyzer/issue_validations/path_is_file_validation.rb +15 -0
  35. data/lib/cc/analyzer/issue_validations/path_presence_validation.rb +15 -0
  36. data/lib/cc/analyzer/issue_validations/relative_path_validation.rb +32 -0
  37. data/lib/cc/analyzer/issue_validations/remediation_points_validation.rb +25 -0
  38. data/lib/cc/analyzer/issue_validations/severity_validation.rb +39 -0
  39. data/lib/cc/analyzer/issue_validations/type_validation.rb +15 -0
  40. data/lib/cc/analyzer/issue_validations/validation.rb +35 -0
  41. data/lib/cc/analyzer/issue_validations.rb +26 -0
  42. data/lib/cc/analyzer/issue_validator.rb +11 -0
  43. data/lib/cc/analyzer/location_description.rb +45 -0
  44. data/lib/cc/analyzer/logging_container_listener.rb +24 -0
  45. data/lib/cc/analyzer/measurement.rb +22 -0
  46. data/lib/cc/analyzer/measurement_validations/name_validation.rb +23 -0
  47. data/lib/cc/analyzer/measurement_validations/type_validation.rb +15 -0
  48. data/lib/cc/analyzer/measurement_validations/validation.rb +27 -0
  49. data/lib/cc/analyzer/measurement_validations/value_validation.rb +21 -0
  50. data/lib/cc/analyzer/measurement_validations.rb +16 -0
  51. data/lib/cc/analyzer/measurement_validator.rb +11 -0
  52. data/lib/cc/analyzer/mounted_path.rb +80 -0
  53. data/lib/cc/analyzer/raising_container_listener.rb +32 -0
  54. data/lib/cc/analyzer/source_buffer.rb +47 -0
  55. data/lib/cc/analyzer/source_extractor.rb +79 -0
  56. data/lib/cc/analyzer/source_fingerprint.rb +40 -0
  57. data/lib/cc/analyzer/statsd_container_listener.rb +51 -0
  58. data/lib/cc/analyzer/validator.rb +38 -0
  59. data/lib/cc/analyzer.rb +50 -0
  60. data/lib/cc/cli/analyze/engine_failure.rb +11 -0
  61. data/lib/cc/cli/analyze.rb +90 -0
  62. data/lib/cc/cli/command.rb +85 -0
  63. data/lib/cc/cli/console.rb +12 -0
  64. data/lib/cc/cli/engines/engine_command.rb +15 -0
  65. data/lib/cc/cli/engines/install.rb +35 -0
  66. data/lib/cc/cli/engines/list.rb +18 -0
  67. data/lib/cc/cli/engines.rb +5 -0
  68. data/lib/cc/cli/file_store.rb +42 -0
  69. data/lib/cc/cli/global_cache.rb +47 -0
  70. data/lib/cc/cli/global_config.rb +35 -0
  71. data/lib/cc/cli/help.rb +51 -0
  72. data/lib/cc/cli/output.rb +34 -0
  73. data/lib/cc/cli/prepare.rb +98 -0
  74. data/lib/cc/cli/runner.rb +75 -0
  75. data/lib/cc/cli/validate_config.rb +84 -0
  76. data/lib/cc/cli/version.rb +16 -0
  77. data/lib/cc/cli/version_checker.rb +107 -0
  78. data/lib/cc/cli.rb +39 -0
  79. data/lib/cc/config/checks_adapter.rb +40 -0
  80. data/lib/cc/config/default_adapter.rb +54 -0
  81. data/lib/cc/config/engine.rb +41 -0
  82. data/lib/cc/config/engine_set.rb +47 -0
  83. data/lib/cc/config/json_adapter.rb +17 -0
  84. data/lib/cc/config/prepare.rb +92 -0
  85. data/lib/cc/config/validation/check_validator.rb +34 -0
  86. data/lib/cc/config/validation/engine_validator.rb +93 -0
  87. data/lib/cc/config/validation/fetch_validator.rb +78 -0
  88. data/lib/cc/config/validation/file_validator.rb +112 -0
  89. data/lib/cc/config/validation/hash_validations.rb +52 -0
  90. data/lib/cc/config/validation/json.rb +31 -0
  91. data/lib/cc/config/validation/prepare_validator.rb +40 -0
  92. data/lib/cc/config/validation/yaml.rb +66 -0
  93. data/lib/cc/config/yaml_adapter.rb +73 -0
  94. data/lib/cc/config.rb +70 -0
  95. data/lib/cc/engine_registry.rb +74 -0
  96. data/lib/cc/resolv.rb +39 -0
  97. data/lib/cc/workspace/exclusion.rb +34 -0
  98. data/lib/cc/workspace/path_tree/dir_node.rb +67 -0
  99. data/lib/cc/workspace/path_tree/file_node.rb +31 -0
  100. data/lib/cc/workspace/path_tree.rb +49 -0
  101. data/lib/cc/workspace.rb +39 -0
  102. metadata +279 -0
@@ -0,0 +1,30 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssueSorter
4
+ def initialize(issues)
5
+ @issues = issues
6
+ end
7
+
8
+ def by_location
9
+ @issues.sort_by { |i| line_or_offset(i) }
10
+ end
11
+
12
+ private
13
+
14
+ def line_or_offset(issue)
15
+ location = issue["location"]
16
+
17
+ case
18
+ when location["lines"]
19
+ [location["lines"]["begin"].to_i]
20
+ when location["positions"] && location["positions"]["begin"]["line"]
21
+ [location["positions"]["begin"]["line"].to_i, location["positions"]["begin"]["column"].to_i]
22
+ when location["positions"] && location["positions"]["begin"]["offset"]
23
+ [1_000_000_000] # push offsets to end of list
24
+ else
25
+ [0] # whole-file issues are first
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class CategoryValidation < Validation
5
+ CATEGORIES = [
6
+ "Bug Risk".freeze,
7
+ "Clarity".freeze,
8
+ "Compatibility".freeze,
9
+ "Complexity".freeze,
10
+ "Duplication".freeze,
11
+ "Performance".freeze,
12
+ "Security".freeze,
13
+ "Style".freeze,
14
+ ].freeze
15
+
16
+ def valid?
17
+ object["categories"].present? && no_invalid_categories?
18
+ end
19
+
20
+ def message
21
+ "Category must be at least one of #{CATEGORIES.join(", ")}"
22
+ end
23
+
24
+ private
25
+
26
+ def no_invalid_categories?
27
+ (CATEGORIES | object["categories"]) == CATEGORIES
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class CheckNamePresenceValidation < Validation
5
+ def valid?
6
+ object["check_name"].present?
7
+ end
8
+
9
+ def message
10
+ "Check name must be present"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class ContentValidation < Validation
5
+ def valid?
6
+ !has_content? || (content.is_a?(Hash) && content["body"].is_a?(String))
7
+ end
8
+
9
+ def message
10
+ "Content must be a hash containing a 'body' key with string contents"
11
+ end
12
+
13
+ private
14
+
15
+ def has_content?
16
+ object.key?("content")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class DescriptionPresenceValidation < Validation
5
+ def valid?
6
+ object["description"].present?
7
+ end
8
+
9
+ def message
10
+ "Description must be present"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,72 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class LocationFormatValidation < Validation
5
+ class Validator
6
+ def initialize(location)
7
+ @location = location
8
+ check_validity
9
+ end
10
+
11
+ def valid?
12
+ error.nil?
13
+ end
14
+
15
+ def message
16
+ if error
17
+ "Location is not formatted correctly: #{error}"
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_accessor :error
24
+
25
+ attr_reader :location
26
+
27
+ def check_validity
28
+ if location["lines"]
29
+ self.error = "location.lines is not valid: #{JSON.dump(location["lines"])}" unless valid_lines?(location["lines"])
30
+ elsif location["positions"]
31
+ self.error = "location.positions is not valid: #{JSON.dump(location["positions"])}" unless valid_positions?(location["positions"])
32
+ else
33
+ self.error = "location.lines or location.positions must be present"
34
+ end
35
+ end
36
+
37
+ def valid_positions?(positions)
38
+ positions.is_a?(Hash) &&
39
+ valid_position?(positions["begin"]) &&
40
+ valid_position?(positions["end"])
41
+ end
42
+
43
+ def valid_position?(position)
44
+ position &&
45
+ (
46
+ [position["line"], position["column"]].all? { |value| value.is_a?(Integer) } ||
47
+ position["offset"].is_a?(Integer)
48
+ )
49
+ end
50
+
51
+ def valid_lines?(lines)
52
+ lines.is_a?(Hash) && [lines["begin"], lines["end"]].all? { |value| value.is_a?(Integer) }
53
+ end
54
+ end
55
+
56
+ def valid?
57
+ validation.valid?
58
+ end
59
+
60
+ def message
61
+ validation.message
62
+ end
63
+
64
+ private
65
+
66
+ def validation
67
+ @validation ||= Validator.new(object.fetch("location", {}))
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,41 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class OtherLocationsFormatValidation < Validation
5
+ CHECKS = [
6
+ LocationFormatValidation,
7
+ PathExistenceValidation,
8
+ PathPresenceValidation,
9
+ RelativePathValidation,
10
+ ].freeze
11
+
12
+ def initialize(object)
13
+ super
14
+ @other_location_valid = {}
15
+ end
16
+
17
+ def valid?
18
+ if object["other_locations"]
19
+ object["other_locations"].is_a?(Array) &&
20
+ object["other_locations"].all?(&method(:other_location_valid?))
21
+ else
22
+ true
23
+ end
24
+ end
25
+
26
+ def message
27
+ "Other locations are not formatted correctly"
28
+ end
29
+
30
+ private
31
+
32
+ def other_location_valid?(location)
33
+ path = location && location["path"]
34
+ @other_location_valid[path] ||= CHECKS.all? do |klass|
35
+ klass.new("location" => location).valid?
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class PathExistenceValidation < Validation
5
+ def valid?
6
+ path && File.exist?(path)
7
+ end
8
+
9
+ def message
10
+ "File does not exist: '#{path}'"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class PathIsFileValidation < Validation
5
+ def valid?
6
+ path && File.file?(path)
7
+ end
8
+
9
+ def message
10
+ "Path is not a file: '#{path}'"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class PathPresenceValidation < Validation
5
+ def valid?
6
+ path.present?
7
+ end
8
+
9
+ def message
10
+ "Path must be present"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ require "pathname"
2
+
3
+ module CC
4
+ module Analyzer
5
+ module IssueValidations
6
+ class RelativePathValidation < Validation
7
+ BUILDER_CODE_PATH = "/tmp/workspace/code".freeze
8
+
9
+ def valid?
10
+ path &&
11
+ !path.start_with?("/") && (
12
+ relative_to?(MountedPath.code.container_path) ||
13
+ relative_to?(BUILDER_CODE_PATH)
14
+ )
15
+ end
16
+
17
+ def message
18
+ "Path must be relative to the project directory"
19
+ end
20
+
21
+ private
22
+
23
+ def relative_to?(directory)
24
+ expanded_base = Pathname.new(directory).expand_path.to_s
25
+ expanded_path = Pathname.new(path).expand_path.to_s
26
+
27
+ expanded_path.start_with?(expanded_base)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class RemediationPointsValidation < Validation
5
+ def valid?
6
+ remediation_points.nil? || positive_integer?(remediation_points)
7
+ end
8
+
9
+ def message
10
+ "Remediation points must be a non-negative integer"
11
+ end
12
+
13
+ private
14
+
15
+ def remediation_points
16
+ @remediation_points ||= object["remediation_points"]
17
+ end
18
+
19
+ def positive_integer?(x)
20
+ x.is_a?(Integer) && x >= 0
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class SeverityValidation < Validation
5
+ INFO = "info".freeze
6
+ MINOR = "minor".freeze
7
+ MAJOR = "major".freeze
8
+ CRITICAL = "critical".freeze
9
+ BLOCKER = "blocker".freeze
10
+
11
+ DEPRECATED_SEVERITIES = [
12
+ NORMAL = "normal".freeze,
13
+ ].freeze
14
+
15
+ VALID_SEVERITIES = ([
16
+ INFO,
17
+ MINOR,
18
+ MAJOR,
19
+ CRITICAL,
20
+ BLOCKER,
21
+ ] + DEPRECATED_SEVERITIES).freeze
22
+
23
+ def valid?
24
+ severity.nil? || VALID_SEVERITIES.include?(severity)
25
+ end
26
+
27
+ def message
28
+ "Permitted severities include #{VALID_SEVERITIES.join(", ")}"
29
+ end
30
+
31
+ private
32
+
33
+ def severity
34
+ @severity ||= object["severity"]
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,15 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ class TypeValidation < Validation
5
+ def valid?
6
+ type&.casecmp("issue")&.zero?
7
+ end
8
+
9
+ def message
10
+ "Type must be 'issue' but was '#{type}'"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
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 path
22
+ object.fetch("location", {})["path"]
23
+ end
24
+
25
+ def type
26
+ object["type"]
27
+ end
28
+
29
+ def content
30
+ object["content"]
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ module CC
2
+ module Analyzer
3
+ module IssueValidations
4
+ autoload :CategoryValidation, "cc/analyzer/issue_validations/category_validation"
5
+ autoload :CheckNamePresenceValidation, "cc/analyzer/issue_validations/check_name_presence_validation"
6
+ autoload :ContentValidation, "cc/analyzer/issue_validations/content_validation"
7
+ autoload :DescriptionPresenceValidation, "cc/analyzer/issue_validations/description_presence_validation"
8
+ autoload :LocationFormatValidation, "cc/analyzer/issue_validations/location_format_validation"
9
+ autoload :OtherLocationsFormatValidation, "cc/analyzer/issue_validations/other_locations_format_validation"
10
+ autoload :PathExistenceValidation, "cc/analyzer/issue_validations/path_existence_validation"
11
+ autoload :PathIsFileValidation, "cc/analyzer/issue_validations/path_is_file_validation"
12
+ autoload :PathPresenceValidation, "cc/analyzer/issue_validations/path_presence_validation"
13
+ autoload :RelativePathValidation, "cc/analyzer/issue_validations/relative_path_validation"
14
+ autoload :RemediationPointsValidation, "cc/analyzer/issue_validations/remediation_points_validation"
15
+ autoload :SeverityValidation, "cc/analyzer/issue_validations/severity_validation"
16
+ autoload :TypeValidation, "cc/analyzer/issue_validations/type_validation"
17
+ autoload :Validation, "cc/analyzer/issue_validations/validation"
18
+
19
+ def self.validations
20
+ constants.sort.map(&method(:const_get)).select do |klass|
21
+ klass.is_a?(Class) && klass.superclass == Validation
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module CC
2
+ module Analyzer
3
+ class IssueValidator
4
+ include Validator
5
+
6
+ def self.validations
7
+ IssueValidations.validations
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,45 @@
1
+ module CC
2
+ module Analyzer
3
+ class LocationDescription
4
+ def initialize(source_buffer, location, suffix = "")
5
+ @source_buffer = source_buffer
6
+ @location = location
7
+ @suffix = suffix
8
+ end
9
+
10
+ def to_s
11
+ if location["lines"]
12
+ begin_line = location["lines"]["begin"]
13
+ end_line = location["lines"]["end"]
14
+ elsif location["positions"]
15
+ begin_line = position_to_line(location["positions"]["begin"])
16
+ end_line = position_to_line(location["positions"]["end"])
17
+ end
18
+
19
+ str = render_lines(begin_line, end_line)
20
+ str << suffix unless str.blank?
21
+ str
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :location, :suffix
27
+
28
+ def render_lines(begin_line, end_line)
29
+ if end_line == begin_line
30
+ begin_line.to_s
31
+ else
32
+ "#{begin_line}-#{end_line}"
33
+ end
34
+ end
35
+
36
+ def position_to_line(position)
37
+ if position["line"]
38
+ position["line"]
39
+ else
40
+ @source_buffer.decompose_position(position["offset"]).first
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,24 @@
1
+ module CC
2
+ module Analyzer
3
+ class LoggingContainerListener < ContainerListener
4
+ def initialize(logger)
5
+ @logger = logger
6
+ end
7
+
8
+ def started(engine, _details)
9
+ logger.info("starting engine #{engine.name}")
10
+ end
11
+
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
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :logger
22
+ end
23
+ end
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,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&.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&.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&.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,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