rubycritic 0.0.5 → 1.4.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/.rubocop.yml +593 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +45 -0
- data/CONTRIBUTING.md +67 -15
- data/README.md +105 -14
- data/Rakefile +9 -6
- data/bin/rubycritic +3 -1
- data/lib/rubycritic/analysers/attributes.rb +21 -0
- data/lib/rubycritic/analysers/churn.rb +21 -0
- data/lib/rubycritic/analysers/complexity.rb +22 -0
- data/lib/rubycritic/analysers/helpers/ast_node.rb +69 -0
- data/lib/rubycritic/analysers/{config.reek → helpers/config.reek} +8 -0
- data/lib/rubycritic/analysers/helpers/flay.rb +13 -0
- data/lib/rubycritic/analysers/helpers/flog.rb +17 -0
- data/lib/rubycritic/analysers/helpers/methods_counter.rb +25 -0
- data/lib/rubycritic/analysers/helpers/modules_locator.rb +43 -0
- data/lib/rubycritic/analysers/helpers/parser.rb +12 -0
- data/lib/rubycritic/analysers/helpers/reek.rb +17 -0
- data/lib/rubycritic/analysers/smells/flay.rb +68 -0
- data/lib/rubycritic/analysers/smells/flog.rb +62 -0
- data/lib/rubycritic/analysers/smells/reek.rb +44 -0
- data/lib/rubycritic/analysers_runner.rb +21 -10
- data/lib/rubycritic/cli/application.rb +24 -0
- data/lib/rubycritic/cli/options.rb +79 -0
- data/lib/rubycritic/commands/ci.rb +26 -0
- data/lib/rubycritic/commands/default.rb +28 -0
- data/lib/rubycritic/commands/help.rb +13 -0
- data/lib/rubycritic/commands/version.rb +11 -0
- data/lib/rubycritic/configuration.rb +33 -0
- data/lib/rubycritic/core/analysed_module.rb +66 -0
- data/lib/rubycritic/{location.rb → core/location.rb} +17 -2
- data/lib/rubycritic/core/rating.rb +30 -0
- data/lib/rubycritic/{smell.rb → core/smell.rb} +22 -13
- data/lib/rubycritic/generators/html/assets/javascripts/application.js +104 -0
- data/lib/rubycritic/generators/html/assets/javascripts/highcharts.src-4.0.1.js +17672 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.floatThead-v1.2.7.js +754 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.scrollTo-1.4.11.js +186 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.tablesorter.js +2089 -0
- data/lib/rubycritic/generators/html/assets/javascripts/jquery.timeago-v1.4.1.js +214 -0
- data/lib/rubycritic/generators/html/assets/stylesheets/application.css +303 -0
- data/lib/rubycritic/{report_generators → generators/html}/assets/stylesheets/prettify.custom_theme.css +1 -4
- data/lib/rubycritic/generators/html/base.rb +52 -0
- data/lib/rubycritic/generators/html/code_file.rb +40 -0
- data/lib/rubycritic/generators/html/code_index.rb +26 -0
- data/lib/rubycritic/generators/html/line.rb +37 -0
- data/lib/rubycritic/generators/html/overview.rb +27 -0
- data/lib/rubycritic/generators/html/smells_index.rb +38 -0
- data/lib/rubycritic/generators/html/templates/code_file.html.erb +38 -0
- data/lib/rubycritic/generators/html/templates/code_index.html.erb +30 -0
- data/lib/rubycritic/generators/html/templates/layouts/application.html.erb +34 -0
- data/lib/rubycritic/generators/html/templates/overview.html.erb +5 -0
- data/lib/rubycritic/generators/html/templates/smells_index.html.erb +26 -0
- data/lib/rubycritic/{report_generators → generators/html}/templates/smelly_line.html.erb +1 -1
- data/lib/rubycritic/generators/html/turbulence.rb +17 -0
- data/lib/rubycritic/generators/html/view_helpers.rb +43 -0
- data/lib/rubycritic/generators/html_report.rb +66 -0
- data/lib/rubycritic/generators/json/simple.rb +30 -0
- data/lib/rubycritic/generators/json_report.rb +23 -0
- data/lib/rubycritic/reporter.rb +20 -0
- data/lib/rubycritic/revision_comparator.rb +27 -29
- data/lib/rubycritic/serializer.rb +32 -0
- data/lib/rubycritic/smells_status_setter.rb +7 -16
- data/lib/rubycritic/source_control_systems/base.rb +37 -0
- data/lib/rubycritic/source_control_systems/double.rb +18 -0
- data/lib/rubycritic/source_control_systems/git.rb +41 -37
- data/lib/rubycritic/source_control_systems/mercurial.rb +29 -0
- data/lib/rubycritic/source_locator.rb +25 -13
- data/lib/rubycritic/version.rb +1 -1
- data/lib/rubycritic.rb +17 -22
- data/rubycritic.gemspec +10 -7
- data/test/analysers_test_helper.rb +3 -0
- data/test/lib/rubycritic/analysers/churn_test.rb +33 -0
- data/test/lib/rubycritic/analysers/complexity_test.rb +16 -0
- 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 +39 -0
- data/test/lib/rubycritic/analysers/smells/flog_test.rb +26 -0
- data/test/lib/rubycritic/analysers/smells/reek_test.rb +33 -0
- data/test/lib/rubycritic/configuration_test.rb +29 -0
- data/test/lib/rubycritic/core/analysed_module_test.rb +88 -0
- data/test/lib/rubycritic/{location_test.rb → core/location_test.rb} +8 -4
- data/test/lib/rubycritic/core/smell_test.rb +72 -0
- data/test/lib/rubycritic/{smells_array_test.rb → core/smells_array_test.rb} +1 -1
- data/test/lib/rubycritic/report_generators/turbulence_test.rb +17 -0
- data/test/lib/rubycritic/report_generators/view_helpers_test.rb +83 -0
- data/test/lib/rubycritic/smells_status_setter_test.rb +5 -5
- data/test/lib/rubycritic/source_control_systems/base_test.rb +29 -0
- data/test/lib/rubycritic/source_control_systems/double_test.rb +11 -0
- data/test/lib/rubycritic/source_control_systems/git_test.rb +13 -0
- data/test/lib/rubycritic/source_control_systems/interfaces/basic.rb +7 -0
- data/test/lib/rubycritic/source_control_systems/interfaces/time_travel.rb +7 -0
- data/test/lib/rubycritic/source_control_systems/mercurial_test.rb +11 -0
- data/test/lib/rubycritic/source_locator_test.rb +42 -18
- data/test/lib/rubycritic/version_test.rb +1 -0
- data/test/samples/empty.rb +0 -0
- data/test/samples/flay/smelly.rb +8 -0
- data/test/samples/flay/smelly2.rb +8 -0
- data/test/samples/flog/complex.rb +11 -0
- data/test/samples/flog/smelly.rb +7 -2
- data/test/samples/location/file0_symlink.rb +0 -0
- data/test/samples/methods_count.rb +7 -0
- data/test/samples/module_names.rb +18 -0
- data/test/samples/reek/not_smelly.rb +31 -3
- data/test/samples/unparsable.rb +1 -0
- data/test/test_helper.rb +39 -0
- metadata +178 -53
- data/SPEC.md +0 -58
- data/lib/rubycritic/analysers/flog.rb +0 -20
- data/lib/rubycritic/analysers/reek.rb +0 -15
- data/lib/rubycritic/cli.rb +0 -25
- data/lib/rubycritic/report_generators/assets/javascripts/application.js +0 -25
- data/lib/rubycritic/report_generators/assets/stylesheets/application.css +0 -26
- data/lib/rubycritic/report_generators/base_generator.rb +0 -42
- data/lib/rubycritic/report_generators/file_generator.rb +0 -42
- data/lib/rubycritic/report_generators/index_generator.rb +0 -28
- data/lib/rubycritic/report_generators/line_generator.rb +0 -27
- data/lib/rubycritic/report_generators/reporter.rb +0 -45
- data/lib/rubycritic/report_generators/templates/file.html.erb +0 -3
- data/lib/rubycritic/report_generators/templates/index.html.erb +0 -14
- data/lib/rubycritic/report_generators/templates/layouts/application.html.erb +0 -19
- data/lib/rubycritic/report_generators/view_helpers.rb +0 -26
- data/lib/rubycritic/smell_adapters/flog.rb +0 -41
- data/lib/rubycritic/smell_adapters/reek.rb +0 -35
- data/lib/rubycritic/smells_aggregator.rb +0 -29
- data/lib/rubycritic/smelly_pathnames_serializer.rb +0 -34
- data/lib/rubycritic/source_control_systems/source_control_system.rb +0 -42
- data/test/lib/rubycritic/metric_adapters/flog_adapter_test.rb +0 -25
- data/test/lib/rubycritic/metric_adapters/reek_adapter_test.rb +0 -34
- data/test/lib/rubycritic/smell_test.rb +0 -71
- data/test/lib/rubycritic/smells_aggregator_test.rb +0 -47
- data/test/lib/rubycritic/source_control_systems/source_control_system_test.rb +0 -26
- /data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/jquery-2.1.0.js +0 -0
- /data/lib/rubycritic/{report_generators/assets/javascripts/prettify.js → generators/html/assets/javascripts/prettify-4-Mar-2013.js} +0 -0
- /data/lib/rubycritic/{report_generators → generators/html}/templates/line.html.erb +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require "rubycritic/generators/html/base"
|
|
2
|
+
|
|
3
|
+
module Rubycritic
|
|
4
|
+
module Generator
|
|
5
|
+
module Html
|
|
6
|
+
|
|
7
|
+
class SmellsIndex < Base
|
|
8
|
+
TEMPLATE = erb_template("smells_index.html.erb")
|
|
9
|
+
|
|
10
|
+
def initialize(analysed_modules)
|
|
11
|
+
@smells = analysed_modules.flat_map(&:smells).uniq
|
|
12
|
+
@analysed_module_names = analysed_module_names(analysed_modules)
|
|
13
|
+
@show_status = (Config.mode == :default)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def file_name
|
|
17
|
+
"smells_index.html"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def render
|
|
21
|
+
index_body = TEMPLATE.result(get_binding)
|
|
22
|
+
LAYOUT_TEMPLATE.result(get_binding { index_body })
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def analysed_module_names(analysed_modules)
|
|
28
|
+
names = {}
|
|
29
|
+
analysed_modules.each do |analysed_module|
|
|
30
|
+
names[analysed_module.pathname] = analysed_module.name
|
|
31
|
+
end
|
|
32
|
+
names
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<div class="file-header group <%= Config.suppress_ratings ? 'unrated' : 'rated' %>">
|
|
2
|
+
<span class="rating rating-<%= @analysed_module.rating.to_s.downcase %> circled-text circle">
|
|
3
|
+
<%= @analysed_module.rating %>
|
|
4
|
+
</span>
|
|
5
|
+
<h2 class="file-name"><%= @analysed_module.name %></h2>
|
|
6
|
+
|
|
7
|
+
<span class="file-committed-at">
|
|
8
|
+
<% if @analysed_module.committed_at %>
|
|
9
|
+
Updated <%= timeago_tag(@analysed_module.committed_at) %>
|
|
10
|
+
<% else %>
|
|
11
|
+
Never committed
|
|
12
|
+
<% end %>
|
|
13
|
+
</span>
|
|
14
|
+
|
|
15
|
+
<div class="file-stats group">
|
|
16
|
+
<div class="file-stat">
|
|
17
|
+
<%= @analysed_module.complexity %> complexity
|
|
18
|
+
</div>
|
|
19
|
+
<div class="file-stat">
|
|
20
|
+
<%= @analysed_module.complexity_per_method %> complexity per method
|
|
21
|
+
</div>
|
|
22
|
+
<div class="file-stat">
|
|
23
|
+
<%= @analysed_module.churn %> churn
|
|
24
|
+
</div>
|
|
25
|
+
<div class="file-stat">
|
|
26
|
+
<%= @analysed_module.methods_count %> methods
|
|
27
|
+
</div>
|
|
28
|
+
<div class="file-stat">
|
|
29
|
+
<%= @analysed_module.duplication %> duplication
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<% if @analysed_module.smells? %>
|
|
34
|
+
<button id="js-toggle-smells" class="smells-toggle-button button">Toggle Smells</button>
|
|
35
|
+
<% end %>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<code class="prettyprint linenums lang-ruby file-code js-file-code"><%= yield %></code>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<table id="js-index-table" class="index-table sortable-table">
|
|
2
|
+
<thead>
|
|
3
|
+
<tr>
|
|
4
|
+
<th>Name</th>
|
|
5
|
+
<th class="numeric-cell" title="Number of times a file has changed">Churn</th>
|
|
6
|
+
<th class="numeric-cell" title="Overall amount of code in a file">Complexity</th>
|
|
7
|
+
<th class="numeric-cell" title="Amount of code that is similar to other code">Duplication</th>
|
|
8
|
+
<th class="numeric-cell">Smells</th>
|
|
9
|
+
<% unless Config.suppress_ratings %>
|
|
10
|
+
<th class="centered-cell">Rating</th>
|
|
11
|
+
<% end %>
|
|
12
|
+
</tr>
|
|
13
|
+
</thead>
|
|
14
|
+
<tbody>
|
|
15
|
+
<% @analysed_modules.each do |analysed_module| %>
|
|
16
|
+
<tr>
|
|
17
|
+
<td>
|
|
18
|
+
<a href="<%= file_path(analysed_module.pathname.sub_ext('.html')) %>"><%= analysed_module.name %></a>
|
|
19
|
+
</td>
|
|
20
|
+
<td class="numeric-cell"><%= analysed_module.churn %></td>
|
|
21
|
+
<td class="numeric-cell"><%= analysed_module.complexity %></td>
|
|
22
|
+
<td class="numeric-cell"><%= analysed_module.duplication %></td>
|
|
23
|
+
<td class="numeric-cell"><%= analysed_module.smells.length %></td>
|
|
24
|
+
<% unless Config.suppress_ratings %>
|
|
25
|
+
<td class="centered-cell"><span class="rating-<%= analysed_module.rating.to_s.downcase %> circled-text circle"><%= analysed_module.rating %></span></td>
|
|
26
|
+
<% end %>
|
|
27
|
+
</tr>
|
|
28
|
+
<% end %>
|
|
29
|
+
</tbody>
|
|
30
|
+
</table>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<title>RubyCritic</title>
|
|
7
|
+
<link href="<%= stylesheet_path(:application) %>" media="screen, projection, print" rel="stylesheet" type="text/css">
|
|
8
|
+
<link href="<%= stylesheet_path(:'prettify.custom_theme') %>" media="screen, projection, print" rel="stylesheet" type="text/css">
|
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<header class="project-header group">
|
|
13
|
+
<div class="container">
|
|
14
|
+
<h1 class="logo"><a href="<%= file_path('overview.html') %>" class="logo-link">RubyCritic</a></h1>
|
|
15
|
+
<nav class="project-nav">
|
|
16
|
+
<a href="<%= file_path('overview.html') %>" class="project-nav-item">Overview</a>
|
|
17
|
+
<a href="<%= file_path('code_index.html') %>" class="project-nav-item">Code</a>
|
|
18
|
+
<a href="<%= file_path('smells_index.html') %>" class="project-nav-item">Smells</a>
|
|
19
|
+
</nav>
|
|
20
|
+
</div>
|
|
21
|
+
</header>
|
|
22
|
+
<div class="container">
|
|
23
|
+
<%= yield %>
|
|
24
|
+
</div>
|
|
25
|
+
<%= javascript_tag(:'jquery-2.1.0') %>
|
|
26
|
+
<%= javascript_tag(:'jquery.tablesorter') %>
|
|
27
|
+
<%= javascript_tag(:'jquery.floatThead-v1.2.7') %>
|
|
28
|
+
<%= javascript_tag(:'jquery.timeago-v1.4.1') %>
|
|
29
|
+
<%= javascript_tag(:'highcharts.src-4.0.1') %>
|
|
30
|
+
<%= javascript_tag(:'jquery.scrollTo-1.4.11') %>
|
|
31
|
+
<%= javascript_tag(:'prettify-4-Mar-2013') %>
|
|
32
|
+
<%= javascript_tag(:application) %>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<table id="js-index-table" class="smells-index-table index-table sortable-table">
|
|
2
|
+
<thead>
|
|
3
|
+
<tr>
|
|
4
|
+
<th>Smell</th>
|
|
5
|
+
<th>Locations</th>
|
|
6
|
+
<% if @show_status %>
|
|
7
|
+
<th class="centered-cell" title="Code smells introduced recently are marked as new. There's still time before they are committed!">Status</th>
|
|
8
|
+
<% end %>
|
|
9
|
+
</tr>
|
|
10
|
+
</thead>
|
|
11
|
+
<tbody>
|
|
12
|
+
<% @smells.each do |smell| %>
|
|
13
|
+
<tr>
|
|
14
|
+
<td><%= smell.type %></td>
|
|
15
|
+
<td>
|
|
16
|
+
<% smell.locations.each do |location| %>
|
|
17
|
+
<a href="<%= smell_location_path(location) %>"><%= @analysed_module_names[location.pathname] %></a>
|
|
18
|
+
<% end %>
|
|
19
|
+
</td>
|
|
20
|
+
<% if @show_status %>
|
|
21
|
+
<td class="centered-cell"><span class="status-<%= smell.status %> circled-text circle"><%= smell.status %></span></td>
|
|
22
|
+
<% end %>
|
|
23
|
+
</tr>
|
|
24
|
+
<% end %>
|
|
25
|
+
</tbody>
|
|
26
|
+
</table>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<% @smells.each do |smell| %>
|
|
5
5
|
<li class="smell <%= smell.status %>">
|
|
6
6
|
<span class="description"><%= smell %>
|
|
7
|
-
<% if smell.
|
|
7
|
+
<% if smell.multiple_locations? %>
|
|
8
8
|
<% smell.locations.each_with_index do |location, index| %>
|
|
9
9
|
<a href="<%= smell_location_path(location) %>" class="js-smell-location"><%= index %></a>
|
|
10
10
|
<% end %>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module Rubycritic
|
|
4
|
+
|
|
5
|
+
module Turbulence
|
|
6
|
+
def self.data(analysed_modules)
|
|
7
|
+
analysed_modules.map do |analysed_module|
|
|
8
|
+
{
|
|
9
|
+
:name => analysed_module.name,
|
|
10
|
+
:x => analysed_module.churn,
|
|
11
|
+
:y => analysed_module.complexity
|
|
12
|
+
}
|
|
13
|
+
end.to_json
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Rubycritic
|
|
2
|
+
|
|
3
|
+
module ViewHelpers
|
|
4
|
+
def timeago_tag(time)
|
|
5
|
+
"<time class='js-timeago' datetime='#{time}'>#{time}</time>"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def javascript_tag(file)
|
|
9
|
+
"<script src='" + asset_path("javascripts/#{file}.js").to_s + "'></script>"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def stylesheet_path(file)
|
|
13
|
+
asset_path("stylesheets/#{file}.css")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def asset_path(file)
|
|
17
|
+
relative_path("assets/#{file}")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def file_path(file)
|
|
21
|
+
relative_path(file)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def smell_location_path(location)
|
|
25
|
+
file_path("#{location.pathname.sub_ext('.html')}#L#{location.line}")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def relative_path(file)
|
|
31
|
+
(root_directory + file).relative_path_from(file_directory)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def file_directory
|
|
35
|
+
raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def root_directory
|
|
39
|
+
raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "rubycritic/generators/html/overview"
|
|
3
|
+
require "rubycritic/generators/html/smells_index"
|
|
4
|
+
require "rubycritic/generators/html/code_index"
|
|
5
|
+
require "rubycritic/generators/html/code_file"
|
|
6
|
+
|
|
7
|
+
module Rubycritic
|
|
8
|
+
module Generator
|
|
9
|
+
|
|
10
|
+
class HtmlReport
|
|
11
|
+
ASSETS_DIR = File.expand_path("../html/assets", __FILE__)
|
|
12
|
+
|
|
13
|
+
def initialize(analysed_modules)
|
|
14
|
+
@analysed_modules = analysed_modules
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def generate_report
|
|
18
|
+
create_directories_and_files
|
|
19
|
+
copy_assets_to_report_directory
|
|
20
|
+
puts "New critique at #{report_location}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def create_directories_and_files
|
|
26
|
+
Array(generators).each do |generator|
|
|
27
|
+
FileUtils.mkdir_p(generator.file_directory)
|
|
28
|
+
File.open(generator.file_pathname, "w+") do |file|
|
|
29
|
+
file.write(generator.render)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def generators
|
|
35
|
+
[overview_generator, code_index_generator, smells_index_generator] + file_generators
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def overview_generator
|
|
39
|
+
@overview_generator ||= Html::Overview.new(@analysed_modules)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def code_index_generator
|
|
43
|
+
Html::CodeIndex.new(@analysed_modules)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def smells_index_generator
|
|
47
|
+
Html::SmellsIndex.new(@analysed_modules)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def file_generators
|
|
51
|
+
@analysed_modules.map do |analysed_module|
|
|
52
|
+
Html::CodeFile.new(analysed_module)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def copy_assets_to_report_directory
|
|
57
|
+
FileUtils.cp_r(ASSETS_DIR, Config.root)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def report_location
|
|
61
|
+
overview_generator.file_href
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module Rubycritic
|
|
4
|
+
module Generator
|
|
5
|
+
module Json
|
|
6
|
+
|
|
7
|
+
class Simple
|
|
8
|
+
def initialize(analysed_modules)
|
|
9
|
+
@analysed_modules = analysed_modules
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def render
|
|
13
|
+
JSON.dump(data)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def data
|
|
17
|
+
{
|
|
18
|
+
:metadata => {
|
|
19
|
+
:rubycritic => {
|
|
20
|
+
:version => Rubycritic::VERSION
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
:analysed_modules => @analysed_modules
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require "rubycritic/generators/json/simple"
|
|
2
|
+
|
|
3
|
+
module Rubycritic
|
|
4
|
+
module Generator
|
|
5
|
+
|
|
6
|
+
class JsonReport
|
|
7
|
+
def initialize(analysed_modules)
|
|
8
|
+
@analysed_modules = analysed_modules
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def generate_report
|
|
12
|
+
print generator.render
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def generator
|
|
18
|
+
Json::Simple.new(@analysed_modules)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Rubycritic
|
|
2
|
+
|
|
3
|
+
module Reporter
|
|
4
|
+
def self.generate_report(analysed_modules)
|
|
5
|
+
report_generator_class.new(analysed_modules).generate_report
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.report_generator_class
|
|
9
|
+
case Config.format
|
|
10
|
+
when :json
|
|
11
|
+
require "rubycritic/generators/json_report"
|
|
12
|
+
Generator::JsonReport
|
|
13
|
+
else
|
|
14
|
+
require "rubycritic/generators/html_report"
|
|
15
|
+
Generator::HtmlReport
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -1,54 +1,52 @@
|
|
|
1
|
-
require "rubycritic/
|
|
2
|
-
require "rubycritic/source_locator"
|
|
1
|
+
require "rubycritic/serializer"
|
|
3
2
|
require "rubycritic/analysers_runner"
|
|
4
|
-
require "rubycritic/smells_aggregator"
|
|
5
3
|
require "rubycritic/smells_status_setter"
|
|
4
|
+
require "rubycritic/version"
|
|
5
|
+
require "digest/md5"
|
|
6
6
|
|
|
7
7
|
module Rubycritic
|
|
8
8
|
|
|
9
9
|
class RevisionComparator
|
|
10
|
-
|
|
10
|
+
SNAPSHOTS_DIR_NAME = "snapshots"
|
|
11
11
|
|
|
12
|
-
def initialize(paths
|
|
12
|
+
def initialize(paths)
|
|
13
13
|
@paths = paths
|
|
14
|
-
@source_control_system = source_control_system
|
|
15
14
|
end
|
|
16
15
|
|
|
17
|
-
def
|
|
18
|
-
|
|
16
|
+
def set_statuses(analysed_modules_now)
|
|
17
|
+
if Config.source_control_system.revision?
|
|
18
|
+
SmellsStatusSetter.set(
|
|
19
|
+
analysed_modules_before.flat_map(&:smells),
|
|
20
|
+
analysed_modules_now.flat_map(&:smells)
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
analysed_modules_now
|
|
19
24
|
end
|
|
20
25
|
|
|
21
26
|
private
|
|
22
27
|
|
|
23
|
-
def
|
|
24
|
-
serializer =
|
|
28
|
+
def analysed_modules_before
|
|
29
|
+
serializer = Serializer.new(revision_file)
|
|
25
30
|
if File.file?(revision_file)
|
|
26
31
|
serializer.load
|
|
27
32
|
else
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
analysed_modules = nil
|
|
34
|
+
Config.source_control_system.travel_to_head do
|
|
35
|
+
analysed_modules = AnalysersRunner.new(@paths).run
|
|
31
36
|
end
|
|
32
|
-
serializer.dump(
|
|
33
|
-
|
|
37
|
+
serializer.dump(analysed_modules)
|
|
38
|
+
analysed_modules
|
|
34
39
|
end
|
|
35
40
|
end
|
|
36
41
|
|
|
37
|
-
def smelly_pathnames_now
|
|
38
|
-
smelly_pathnames(@paths)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def smelly_pathnames(paths)
|
|
42
|
-
smell_adapters = AnalysersRunner.new(paths).run
|
|
43
|
-
SmellsAggregator.new(smell_adapters).smelly_pathnames
|
|
44
|
-
end
|
|
45
|
-
|
|
46
42
|
def revision_file
|
|
47
|
-
@revision_file ||= File.join(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
@revision_file ||= File.join(
|
|
44
|
+
Config.root,
|
|
45
|
+
SNAPSHOTS_DIR_NAME,
|
|
46
|
+
VERSION,
|
|
47
|
+
Digest::MD5.hexdigest(Marshal.dump(@paths)),
|
|
48
|
+
Config.source_control_system.head_reference
|
|
49
|
+
)
|
|
52
50
|
end
|
|
53
51
|
end
|
|
54
52
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
|
|
3
|
+
module Rubycritic
|
|
4
|
+
|
|
5
|
+
class Serializer
|
|
6
|
+
def initialize(file)
|
|
7
|
+
@file = file
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def load
|
|
11
|
+
Marshal.load(File.binread(@file))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def dump(content)
|
|
15
|
+
create_file_directory
|
|
16
|
+
File.open(@file, "w+") do |file|
|
|
17
|
+
Marshal.dump(content, file)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def create_file_directory
|
|
24
|
+
FileUtils.mkdir_p(file_directory)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def file_directory
|
|
28
|
+
File.dirname(@file)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
module Rubycritic
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
def
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def smelly_pathnames
|
|
10
|
-
@smelly_pathnames_now.each do |pathname, smells_now|
|
|
11
|
-
smells_before = @smelly_pathnames_before[pathname] || []
|
|
12
|
-
old_smells = smells_now & smells_before
|
|
13
|
-
set_status(old_smells, :old)
|
|
14
|
-
new_smells = smells_now - smells_before
|
|
15
|
-
set_status(new_smells, :new)
|
|
16
|
-
end
|
|
17
|
-
@smelly_pathnames_now
|
|
3
|
+
module SmellsStatusSetter
|
|
4
|
+
def self.set(smells_before, smells_now)
|
|
5
|
+
old_smells = smells_now & smells_before
|
|
6
|
+
set_status(old_smells, :old)
|
|
7
|
+
new_smells = smells_now - smells_before
|
|
8
|
+
set_status(new_smells, :new)
|
|
18
9
|
end
|
|
19
10
|
|
|
20
11
|
private
|
|
21
12
|
|
|
22
|
-
def set_status(smells, status)
|
|
13
|
+
def self.set_status(smells, status)
|
|
23
14
|
smells.each { |smell| smell.status = status }
|
|
24
15
|
end
|
|
25
16
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require "shellwords"
|
|
2
|
+
|
|
3
|
+
module Rubycritic
|
|
4
|
+
module SourceControlSystem
|
|
5
|
+
|
|
6
|
+
class Base
|
|
7
|
+
@@systems = []
|
|
8
|
+
|
|
9
|
+
def self.register_system
|
|
10
|
+
@@systems << self
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.systems
|
|
14
|
+
@@systems
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.create
|
|
18
|
+
supported_system = systems.find(&:supported?)
|
|
19
|
+
if supported_system
|
|
20
|
+
supported_system.new
|
|
21
|
+
else
|
|
22
|
+
puts "RubyCritic can provide more feedback if you use a #{connected_system_names} repository."
|
|
23
|
+
Double.new
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.connected_system_names
|
|
28
|
+
"#{systems[0...-1].join(', ')} or #{systems[-1]}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
require "rubycritic/source_control_systems/double"
|
|
36
|
+
require "rubycritic/source_control_systems/git"
|
|
37
|
+
require "rubycritic/source_control_systems/mercurial"
|