rubycritic 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/lib/rubycritic/analysers/attributes.rb +21 -0
- data/lib/rubycritic/analysers/churn.rb +5 -5
- data/lib/rubycritic/analysers/complexity.rb +6 -6
- data/lib/rubycritic/analysers/helpers/ast_node.rb +73 -0
- data/lib/rubycritic/analysers/{adapters → helpers}/config.reek +0 -0
- data/lib/rubycritic/analysers/{adapters → helpers}/flay.rb +0 -0
- data/lib/rubycritic/analysers/{adapters → helpers}/flog.rb +0 -0
- data/lib/rubycritic/analysers/helpers/methods_counter.rb +28 -0
- data/lib/rubycritic/analysers/helpers/modules_locator.rb +46 -0
- data/lib/rubycritic/analysers/{adapters → helpers}/reek.rb +0 -0
- data/lib/rubycritic/analysers/smells/flay.rb +9 -9
- data/lib/rubycritic/analysers/smells/flog.rb +8 -8
- data/lib/rubycritic/analysers/smells/reek.rb +8 -8
- data/lib/rubycritic/analysers_runner.rb +6 -6
- data/lib/rubycritic/cli.rb +2 -2
- data/lib/rubycritic/core/{analysed_file.rb → analysed_module.rb} +4 -7
- data/lib/rubycritic/modules_initializer.rb +14 -0
- data/lib/rubycritic/orchestrator.rb +5 -5
- data/lib/rubycritic/report_generators/code_file.rb +4 -4
- data/lib/rubycritic/report_generators/code_index.rb +2 -2
- data/lib/rubycritic/report_generators/overview.rb +2 -2
- data/lib/rubycritic/report_generators/smells_index.rb +13 -2
- data/lib/rubycritic/report_generators/templates/code_file.html.erb +10 -10
- data/lib/rubycritic/report_generators/templates/code_index.html.erb +7 -7
- data/lib/rubycritic/report_generators/templates/smells_index.html.erb +1 -1
- data/lib/rubycritic/report_generators/turbulence.rb +5 -5
- data/lib/rubycritic/report_generators/view_helpers.rb +4 -4
- data/lib/rubycritic/reporters/main.rb +7 -8
- data/lib/rubycritic/reporters/mini.rb +3 -3
- data/lib/rubycritic/revision_comparator.rb +12 -10
- data/lib/rubycritic/source_locator.rb +1 -1
- data/lib/rubycritic/version.rb +1 -1
- data/rubycritic.gemspec +3 -4
- data/test/analysers_test_helper.rb +1 -1
- data/test/lib/rubycritic/analysers/churn_test.rb +9 -9
- data/test/lib/rubycritic/analysers/complexity_test.rb +5 -5
- data/test/lib/rubycritic/analysers/helpers/methods_counter_test.rb +29 -0
- data/test/lib/rubycritic/analysers/helpers/modules_locator_test.rb +53 -0
- data/test/lib/rubycritic/analysers/smells/flay_test.rb +10 -12
- data/test/lib/rubycritic/analysers/smells/flog_test.rb +7 -7
- data/test/lib/rubycritic/analysers/smells/reek_test.rb +10 -10
- data/test/lib/rubycritic/core/analysed_module_test.rb +88 -0
- data/test/lib/rubycritic/report_generators/turbulence_test.rb +4 -4
- data/test/lib/rubycritic/report_generators/view_helpers_test.rb +10 -23
- data/test/lib/rubycritic/smells_status_setter_test.rb +1 -1
- data/test/lib/rubycritic/source_locator_test.rb +6 -6
- data/test/samples/{stats/empty_example.rb → empty.rb} +0 -0
- data/test/samples/{stats/example.rb → methods_count.rb} +0 -0
- data/test/samples/module_names.rb +18 -0
- data/test/samples/unparsable.rb +1 -0
- metadata +30 -23
- data/lib/rubycritic/analysers/adapters/ast_node.rb +0 -35
- data/lib/rubycritic/analysers/stats.rb +0 -34
- data/lib/rubycritic/files_initializer.rb +0 -15
- data/test/lib/rubycritic/analysers/stats_test.rb +0 -30
- data/test/lib/rubycritic/core/analysed_file_test.rb +0 -86
- data/test/samples/stats/unparsable_example.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e19fa08f433cdb1ef0d4f49096ffa2de1e8a7132
|
4
|
+
data.tar.gz: 0eb7f2ce702010efc38a3d14d5044ba9dcccfe70
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae8600a942a9c784bb4c7c4c3caba9d649430c9f346ce5e8576c92fef8e5a0e933ee3200b96f44deee10f9bef3b9cca99094949ea7c5f36a21baba36d839c0c3
|
7
|
+
data.tar.gz: 285e582072b09076129b9519349aa4e2d941cee174c31688b730674ac689f030d5f2df5ee232185b3f9456b96aee2a481f25676d4ced89c669f5f0e4b651f17c
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# 1.1.0 / 2014-07-27
|
2
|
+
|
3
|
+
* [FEATURE] Display name of the first module found in a file instead of the file's name
|
4
|
+
|
5
|
+
# 1.0.2 / 2014-07-23
|
6
|
+
|
7
|
+
* [BUGFIX] Fix issue #8 - Solve a dependency error by requiring at least ruby2ruby 2.1.1
|
8
|
+
|
9
|
+
# 1.0.1 / 2014-07-22
|
10
|
+
|
11
|
+
* [BUGFIX] Fix issue #6 - Rescue `Parser::SyntaxError` when a file is unparsable
|
12
|
+
|
13
|
+
# 1.0.0 / 2014-07-13
|
14
|
+
|
15
|
+
* Official Release
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rubycritic/analysers/helpers/methods_counter"
|
2
|
+
require "rubycritic/analysers/helpers/modules_locator"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
module Analyser
|
6
|
+
|
7
|
+
class Attributes
|
8
|
+
def initialize(analysed_modules)
|
9
|
+
@analysed_modules = analysed_modules
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
@analysed_modules.each do |analysed_module|
|
14
|
+
analysed_module.methods_count = MethodsCounter.new(analysed_module).count
|
15
|
+
analysed_module.name = ModulesLocator.new(analysed_module).first_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -2,15 +2,15 @@ module Rubycritic
|
|
2
2
|
module Analyser
|
3
3
|
|
4
4
|
class Churn
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(analysed_modules, source_control_system)
|
6
|
+
@analysed_modules = analysed_modules
|
7
7
|
@source_control_system = source_control_system
|
8
8
|
end
|
9
9
|
|
10
10
|
def run
|
11
|
-
@
|
12
|
-
|
13
|
-
|
11
|
+
@analysed_modules.each do |analysed_module|
|
12
|
+
analysed_module.churn = @source_control_system.revisions_count(analysed_module.path)
|
13
|
+
analysed_module.committed_at = @source_control_system.date_of_last_commit(analysed_module.path)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -1,19 +1,19 @@
|
|
1
|
-
require "rubycritic/analysers/
|
1
|
+
require "rubycritic/analysers/helpers/flog"
|
2
2
|
|
3
3
|
module Rubycritic
|
4
4
|
module Analyser
|
5
5
|
|
6
6
|
class Complexity
|
7
|
-
def initialize(
|
7
|
+
def initialize(analysed_modules)
|
8
8
|
@flog = Flog.new
|
9
|
-
@
|
9
|
+
@analysed_modules = analysed_modules
|
10
10
|
end
|
11
11
|
|
12
12
|
def run
|
13
|
-
@
|
13
|
+
@analysed_modules.each do |analysed_module|
|
14
14
|
@flog.reset
|
15
|
-
@flog.flog(
|
16
|
-
|
15
|
+
@flog.flog(analysed_module.path)
|
16
|
+
analysed_module.complexity = @flog.total_score.round
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Parser
|
2
|
+
module AST
|
3
|
+
|
4
|
+
class Node
|
5
|
+
MODULE_TYPES = [:module, :class]
|
6
|
+
|
7
|
+
def count_nodes_of_type(*types)
|
8
|
+
count = 0
|
9
|
+
recursive_children do |child|
|
10
|
+
count += 1 if types.include?(child.type)
|
11
|
+
end
|
12
|
+
count
|
13
|
+
end
|
14
|
+
|
15
|
+
def recursive_children
|
16
|
+
children.each do |child|
|
17
|
+
next unless child.is_a?(Parser::AST::Node)
|
18
|
+
yield child
|
19
|
+
child.recursive_children { |grand_child| yield grand_child }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_module_names
|
24
|
+
children_modules = children
|
25
|
+
.select { |child| child.is_a?(Parser::AST::Node) }
|
26
|
+
.flat_map { |child| child.get_module_names }
|
27
|
+
|
28
|
+
if MODULE_TYPES.include?(self.type)
|
29
|
+
if children_modules.empty?
|
30
|
+
[module_name]
|
31
|
+
else
|
32
|
+
children_modules.map do |children_module|
|
33
|
+
"#{module_name}::#{children_module}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
elsif children_modules.empty?
|
37
|
+
[]
|
38
|
+
else
|
39
|
+
children_modules
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def module_name
|
46
|
+
name_segments = []
|
47
|
+
current_node = children[0]
|
48
|
+
while(current_node) do
|
49
|
+
name_segments.unshift(current_node.children[1])
|
50
|
+
current_node = current_node.children[0]
|
51
|
+
end
|
52
|
+
name_segments.join("::")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module Rubycritic
|
60
|
+
module AST
|
61
|
+
|
62
|
+
class EmptyNode
|
63
|
+
def count_nodes_of_type(*types)
|
64
|
+
0
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_module_names
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "parser/current"
|
2
|
+
require "rubycritic/analysers/helpers/ast_node"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
|
6
|
+
class MethodsCounter
|
7
|
+
def initialize(analysed_module)
|
8
|
+
@analysed_module = analysed_module
|
9
|
+
end
|
10
|
+
|
11
|
+
def count
|
12
|
+
node.count_nodes_of_type(:def, :defs)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def node
|
18
|
+
Parser::CurrentRuby.parse(content) || AST::EmptyNode.new
|
19
|
+
rescue Parser::SyntaxError => error
|
20
|
+
AST::EmptyNode.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def content
|
24
|
+
File.read(@analysed_module.path)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "parser/current"
|
2
|
+
require "rubycritic/analysers/helpers/ast_node"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
|
6
|
+
class ModulesLocator
|
7
|
+
def initialize(analysed_module)
|
8
|
+
@analysed_module = analysed_module
|
9
|
+
end
|
10
|
+
|
11
|
+
def first_name
|
12
|
+
names.first
|
13
|
+
end
|
14
|
+
|
15
|
+
def names
|
16
|
+
return name_from_path if @analysed_module.methods_count == 0
|
17
|
+
names = node.get_module_names
|
18
|
+
if names.empty?
|
19
|
+
name_from_path
|
20
|
+
else
|
21
|
+
names
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def node
|
28
|
+
Parser::CurrentRuby.parse(content) || AST::EmptyNode.new
|
29
|
+
rescue Parser::SyntaxError => error
|
30
|
+
AST::EmptyNode.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def content
|
34
|
+
File.read(@analysed_module.path)
|
35
|
+
end
|
36
|
+
|
37
|
+
def name_from_path
|
38
|
+
[file_name.split("_").map(&:capitalize).join]
|
39
|
+
end
|
40
|
+
|
41
|
+
def file_name
|
42
|
+
@analysed_module.pathname.basename.sub_ext("").to_s
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
File without changes
|
@@ -1,34 +1,34 @@
|
|
1
|
-
require "rubycritic/analysers/
|
1
|
+
require "rubycritic/analysers/helpers/flay"
|
2
2
|
require "rubycritic/core/smell"
|
3
3
|
|
4
4
|
module Rubycritic
|
5
5
|
module Analyser
|
6
6
|
|
7
7
|
class FlaySmells
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
-
@flay = Flay.new(@
|
8
|
+
def initialize(analysed_modules)
|
9
|
+
@analysed_modules = paths_to_analysed_modules(analysed_modules)
|
10
|
+
@flay = Flay.new(@analysed_modules.keys)
|
11
11
|
end
|
12
12
|
|
13
13
|
def run
|
14
14
|
@flay.hashes.each do |structural_hash, nodes|
|
15
15
|
smell = create_smell(structural_hash, nodes)
|
16
16
|
nodes.map(&:file).uniq.each do |file|
|
17
|
-
@
|
17
|
+
@analysed_modules[file].smells << smell
|
18
18
|
end
|
19
19
|
|
20
20
|
nodes.each do |node|
|
21
|
-
@
|
21
|
+
@analysed_modules[node.file].duplication += node.mass
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
def
|
28
|
+
def paths_to_analysed_modules(analysed_modules)
|
29
29
|
paths = {}
|
30
|
-
|
31
|
-
paths[
|
30
|
+
analysed_modules.each do |analysed_module|
|
31
|
+
paths[analysed_module.path] = analysed_module
|
32
32
|
end
|
33
33
|
paths
|
34
34
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require "rubycritic/analysers/
|
1
|
+
require "rubycritic/analysers/helpers/flog"
|
2
2
|
require "rubycritic/core/smell"
|
3
3
|
|
4
4
|
module Rubycritic
|
@@ -8,26 +8,26 @@ module Rubycritic
|
|
8
8
|
HIGH_COMPLEXITY_SCORE_THRESHOLD = 25
|
9
9
|
VERY_HIGH_COMPLEXITY_SCORE_THRESHOLD = 60
|
10
10
|
|
11
|
-
def initialize(
|
11
|
+
def initialize(analysed_modules)
|
12
12
|
@flog = Flog.new
|
13
|
-
@
|
13
|
+
@analysed_modules = analysed_modules
|
14
14
|
end
|
15
15
|
|
16
16
|
def run
|
17
|
-
@
|
18
|
-
add_smells_to(
|
17
|
+
@analysed_modules.each do |analysed_module|
|
18
|
+
add_smells_to(analysed_module)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
-
def add_smells_to(
|
24
|
+
def add_smells_to(analysed_module)
|
25
25
|
@flog.reset
|
26
|
-
@flog.flog(
|
26
|
+
@flog.flog(analysed_module.path)
|
27
27
|
@flog.each_by_score do |class_method, original_score|
|
28
28
|
score = original_score.round
|
29
29
|
if score >= HIGH_COMPLEXITY_SCORE_THRESHOLD
|
30
|
-
|
30
|
+
analysed_module.smells << create_smell(class_method, score)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -1,25 +1,25 @@
|
|
1
|
-
require "rubycritic/analysers/
|
1
|
+
require "rubycritic/analysers/helpers/reek"
|
2
2
|
require "rubycritic/core/smell"
|
3
3
|
|
4
4
|
module Rubycritic
|
5
5
|
module Analyser
|
6
6
|
|
7
7
|
class ReekSmells
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(analysed_modules)
|
9
|
+
@analysed_modules = analysed_modules
|
10
10
|
end
|
11
11
|
|
12
12
|
def run
|
13
|
-
@
|
14
|
-
add_smells_to(
|
13
|
+
@analysed_modules.each do |analysed_module|
|
14
|
+
add_smells_to(analysed_module)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
def add_smells_to(
|
21
|
-
Reek.new(
|
22
|
-
|
20
|
+
def add_smells_to(analysed_module)
|
21
|
+
Reek.new(analysed_module.path).smells.each do |smell|
|
22
|
+
analysed_module.smells << create_smell(smell)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -3,7 +3,7 @@ require "rubycritic/analysers/smells/flog"
|
|
3
3
|
require "rubycritic/analysers/smells/reek"
|
4
4
|
require "rubycritic/analysers/complexity"
|
5
5
|
require "rubycritic/analysers/churn"
|
6
|
-
require "rubycritic/analysers/
|
6
|
+
require "rubycritic/analysers/attributes"
|
7
7
|
|
8
8
|
module Rubycritic
|
9
9
|
|
@@ -13,19 +13,19 @@ module Rubycritic
|
|
13
13
|
Analyser::FlogSmells,
|
14
14
|
Analyser::ReekSmells,
|
15
15
|
Analyser::Complexity,
|
16
|
-
Analyser::
|
16
|
+
Analyser::Attributes
|
17
17
|
]
|
18
18
|
|
19
|
-
def initialize(
|
20
|
-
@
|
19
|
+
def initialize(analysed_modules, source_control_system)
|
20
|
+
@analysed_modules = analysed_modules
|
21
21
|
@source_control_system = source_control_system
|
22
22
|
end
|
23
23
|
|
24
24
|
def run
|
25
25
|
ANALYSERS.each do |analyser|
|
26
|
-
analyser.new(@
|
26
|
+
analyser.new(@analysed_modules).run
|
27
27
|
end
|
28
|
-
Analyser::Churn.new(@
|
28
|
+
Analyser::Churn.new(@analysed_modules, @source_control_system).run
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
data/lib/rubycritic/cli.rb
CHANGED
@@ -34,8 +34,8 @@ module Rubycritic
|
|
34
34
|
end.parse!(@argv)
|
35
35
|
|
36
36
|
if @main_command
|
37
|
-
|
38
|
-
report_location = Reporter::Main.new(
|
37
|
+
analysed_modules = Orchestrator.new.critique(@argv)
|
38
|
+
report_location = Reporter::Main.new(analysed_modules).generate_report
|
39
39
|
puts "New critique at #{report_location}"
|
40
40
|
end
|
41
41
|
|
@@ -3,21 +3,18 @@ require "rubycritic/core/rating"
|
|
3
3
|
|
4
4
|
module Rubycritic
|
5
5
|
|
6
|
-
class
|
6
|
+
class AnalysedModule
|
7
7
|
include Virtus.model
|
8
8
|
|
9
|
+
attribute :name
|
9
10
|
attribute :pathname
|
10
|
-
attribute :smells
|
11
|
+
attribute :smells, Array, :default => []
|
11
12
|
attribute :churn
|
12
13
|
attribute :committed_at
|
13
14
|
attribute :complexity
|
14
|
-
attribute :duplication
|
15
|
+
attribute :duplication, Integer, :default => 0
|
15
16
|
attribute :methods_count
|
16
17
|
|
17
|
-
def name
|
18
|
-
@name ||= pathname.basename.sub_ext("").to_s
|
19
|
-
end
|
20
|
-
|
21
18
|
def path
|
22
19
|
@path ||= pathname.to_s
|
23
20
|
end
|