codeclimate 0.24.3 → 0.25.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.
- checksums.yaml +4 -4
- data/lib/cc/analyzer.rb +9 -0
- data/lib/cc/analyzer/container.rb +5 -5
- data/lib/cc/analyzer/engine.rb +5 -0
- data/lib/cc/analyzer/engine_output.rb +13 -1
- data/lib/cc/analyzer/formatters.rb +1 -1
- data/lib/cc/analyzer/formatters/plain_text_formatter.rb +5 -5
- data/lib/cc/analyzer/issue_category_validation.rb +30 -0
- data/lib/cc/analyzer/issue_check_name_presence_validation.rb +13 -0
- data/lib/cc/analyzer/issue_description_presence_validation.rb +13 -0
- data/lib/cc/analyzer/issue_path_existence_validation.rb +19 -0
- data/lib/cc/analyzer/issue_path_presence_validation.rb +19 -0
- data/lib/cc/analyzer/issue_relative_path_validation.rb +19 -0
- data/lib/cc/analyzer/issue_type_validation.rb +19 -0
- data/lib/cc/analyzer/issue_validator.rb +46 -0
- data/lib/cc/analyzer/validation.rb +21 -0
- data/lib/cc/cli/command.rb +2 -2
- data/lib/cc/cli/engines/list.rb +1 -1
- data/lib/cc/cli/help.rb +3 -3
- data/lib/cc/cli/runner.rb +1 -1
- data/lib/cc/cli/test.rb +1 -1
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c732584b6855ac426cc7e0a19b4fb55375f7fcf5
|
4
|
+
data.tar.gz: 1678f0e4a32a532a7e871412e681ddaf7cc0f59a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
9
|
-
:name,
|
10
|
-
:duration,
|
11
|
-
:status,
|
12
|
-
:stderr,
|
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(
|
data/lib/cc/analyzer/engine.rb
CHANGED
@@ -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[
|
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,
|
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[
|
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,
|
46
|
+
print(colorize("Analysis complete! Found #{pluralize(issues.size, "issue")}", :green))
|
47
47
|
if warnings.size > 0
|
48
|
-
print(colorize(" and #{pluralize(warnings.size,
|
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,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
|
data/lib/cc/cli/command.rb
CHANGED
@@ -13,7 +13,7 @@ module CC
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def run
|
16
|
-
$stderr.puts "unknown command #{self.class.name.split(
|
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
|
|
data/lib/cc/cli/engines/list.rb
CHANGED
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(
|
20
|
-
"engines:enable #{underline(
|
19
|
+
"engines:disable #{underline("engine_name")}",
|
20
|
+
"engines:enable #{underline("engine_name")}",
|
21
21
|
"engines:install",
|
22
22
|
"engines:list",
|
23
|
-
"engines:remove #{underline(
|
23
|
+
"engines:remove #{underline("engine_name")}",
|
24
24
|
"help",
|
25
25
|
"init",
|
26
26
|
"validate-config",
|
data/lib/cc/cli/runner.rb
CHANGED
data/lib/cc/cli/test.rb
CHANGED
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.
|
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-
|
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
|