codeclimate 0.24.3 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|