Skip to content

Commit 9a233fe

Browse files
committed
Move from class to module
Refactor Skunk analysis integration by removing the Analysis class and adding its methods directly to RubyCritic::AnalysedModulesCollection. Update related files to utilize the new methods for Skunk score calculations and reporting.
1 parent a91d530 commit 9a233fe

File tree

8 files changed

+136
-160
lines changed

8 files changed

+136
-160
lines changed

lib/skunk.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# frozen_string_literal: true
22

33
require "skunk/version"
4-
require "skunk/analysis"
54

65
# Knows how to calculate the `SkunkScore` for each file analyzed by `RubyCritic`
76
# and `SimpleCov`

lib/skunk/analysis.rb

Lines changed: 0 additions & 106 deletions
This file was deleted.

lib/skunk/commands/status_reporter.rb

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
require "erb"
44
require "rubycritic/commands/status_reporter"
55
require "terminal-table"
6-
require "skunk/analysis"
76

87
module Skunk
98
module Command
@@ -13,7 +12,6 @@ class StatusReporter < RubyCritic::Command::StatusReporter
1312

1413
def initialize(options = {})
1514
super(options)
16-
@analysis = nil
1715
end
1816

1917
HEADINGS = %w[file skunk_score churn_times_cost churn cost coverage].freeze
@@ -34,7 +32,6 @@ def initialize(options = {})
3432
# Returns a status message with a table of all analysed_modules and
3533
# a skunk score average
3634
def update_status_message
37-
@analysis = Skunk::Analysis.new(analysed_modules)
3835
opts = table_options.merge(headings: HEADINGS, rows: table)
3936

4037
_ttable = Terminal::Table.new(opts)
@@ -45,27 +42,27 @@ def update_status_message
4542
private
4643

4744
def analysed_modules_count
48-
@analysis.analysed_modules_count
45+
analysed_modules.analysed_modules_count
4946
end
5047

5148
def worst
52-
@analysis.worst_module
49+
analysed_modules.worst_module
5350
end
5451

5552
def sorted_modules
56-
@analysis.sorted_modules
53+
analysed_modules.sorted_modules
5754
end
5855

5956
def total_skunk_score
60-
@analysis.skunk_score_total
57+
analysed_modules.skunk_score_total
6158
end
6259

6360
def total_churn_times_cost
64-
@analysis.total_churn_times_cost
61+
analysed_modules.total_churn_times_cost
6562
end
6663

6764
def skunk_score_average
68-
@analysis.skunk_score_average
65+
analysed_modules.skunk_score_average
6966
end
7067

7168
def table_options

lib/skunk/generators/html/overview.rb

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
require "skunk/generators/html/path_truncator"
66
require "skunk/generators/html/file_data"
7-
require "skunk/analysis"
7+
require "skunk/rubycritic/analysed_modules_collection"
88

99
module Skunk
1010
module Generator
@@ -20,7 +20,6 @@ def self.erb_template(template_path)
2020

2121
def initialize(analysed_modules)
2222
@analysed_modules = analysed_modules
23-
@analysis = Skunk::Analysis.new(analysed_modules)
2423
@generated_at = Time.now.strftime("%Y-%m-%d %H:%M:%S")
2524
@skunk_version = Skunk::VERSION
2625
end
@@ -34,19 +33,19 @@ def render
3433
end
3534

3635
def analysed_modules_count
37-
@analysis.analysed_modules_count
36+
@analysed_modules.analysed_modules_count
3837
end
3938

4039
def skunk_score_total
41-
@analysis.skunk_score_total
40+
@analysed_modules.skunk_score_total
4241
end
4342

4443
def skunk_score_average
45-
@analysis.skunk_score_average
44+
@analysed_modules.skunk_score_average
4645
end
4746

4847
def files
49-
@files ||= @analysis.sorted_modules.map do |module_data|
48+
@files ||= @analysed_modules.sorted_modules.map do |module_data|
5049
FileData.new(module_data)
5150
end
5251
end

lib/skunk/generators/json/simple.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require "pathname"
44

55
require "rubycritic/configuration"
6-
require "skunk/analysis"
6+
require "skunk/rubycritic/analysed_modules_collection"
77

88
module Skunk
99
module Generator
@@ -12,7 +12,6 @@ module Json
1212
class Simple
1313
def initialize(analysed_modules)
1414
@analysed_modules = analysed_modules
15-
@analysis = Skunk::Analysis.new(analysed_modules)
1615
end
1716

1817
FILE_NAME = "skunk_report.json"
@@ -22,7 +21,7 @@ def render
2221
end
2322

2423
def data
25-
@analysis.to_hash
24+
@analysed_modules.to_hash
2625
end
2726

2827
def file_directory

lib/skunk/rubycritic/analysed_modules_collection.rb

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,100 @@
33
require "rubycritic/core/analysed_modules_collection"
44

55
module RubyCritic
6-
# nodoc #
6+
# Monkey-patches RubyCritic::AnalysedModulesCollection to add Skunk analysis methods
77
class AnalysedModulesCollection
8+
# Returns the count of non-test modules
9+
# @return [Integer]
10+
def analysed_modules_count
11+
@analysed_modules_count ||= non_test_modules.count
12+
end
13+
14+
# Returns the total Skunk score across all non-test modules
15+
# @return [Float]
16+
def skunk_score_total
17+
@skunk_score_total ||= non_test_modules.sum(&:skunk_score)
18+
end
19+
20+
# Returns the average Skunk score across all non-test modules
21+
# @return [Float]
822
def skunk_score_average
9-
num_modules = @modules.size
10-
if num_modules.positive?
11-
sum(&:skunk_score) / num_modules.to_f
12-
else
13-
0.0
23+
return 0.0 if analysed_modules_count.zero?
24+
25+
(skunk_score_total.to_d / analysed_modules_count).to_f.round(2)
26+
end
27+
28+
# Returns the total churn times cost across all non-test modules
29+
# @return [Float]
30+
def total_churn_times_cost
31+
@total_churn_times_cost ||= non_test_modules.sum(&:churn_times_cost)
32+
end
33+
34+
# Returns the module with the highest Skunk score (worst performing)
35+
# @return [RubyCritic::AnalysedModule, nil]
36+
def worst_module
37+
@worst_module ||= sorted_modules.first
38+
end
39+
40+
# Returns modules sorted by Skunk score in descending order (worst first)
41+
# @return [Array<RubyCritic::AnalysedModule>]
42+
def sorted_modules
43+
@sorted_modules ||= non_test_modules.sort_by(&:skunk_score).reverse!
44+
end
45+
46+
# Returns only non-test modules (excludes test and spec directories)
47+
# @return [Array<RubyCritic::AnalysedModule>]
48+
def non_test_modules
49+
@non_test_modules ||= reject do |a_module|
50+
test_module?(a_module)
1451
end
1552
end
53+
54+
# Returns a hash representation of the analysis results
55+
# @return [Hash]
56+
def to_hash
57+
{
58+
analysed_modules_count: analysed_modules_count,
59+
skunk_score_total: skunk_score_total,
60+
skunk_score_average: skunk_score_average,
61+
total_churn_times_cost: total_churn_times_cost,
62+
worst_pathname: worst_module&.pathname,
63+
worst_score: worst_module&.skunk_score,
64+
files: files_as_hash
65+
}
66+
end
67+
68+
private
69+
70+
# Returns files as an array of hashes (for JSON serialization)
71+
# @return [Array<Hash>]
72+
def files_as_hash
73+
@files_as_hash ||= sorted_modules.map(&:to_hash)
74+
end
75+
76+
# Determines if a module is a test module based on its path
77+
# @param a_module [RubyCritic::AnalysedModule] The module to check
78+
# @return [Boolean]
79+
def test_module?(a_module)
80+
pathname = a_module.pathname
81+
directory_is_test?(pathname) || filename_is_test?(pathname)
82+
end
83+
84+
# Checks if the directory path indicates a test module
85+
# @param pathname [Pathname] The pathname to check
86+
# @return [Boolean]
87+
# :reek:UtilityFunction
88+
def directory_is_test?(pathname)
89+
module_path = pathname.dirname.to_s
90+
module_path.start_with?("test", "spec") || module_path.end_with?("test", "spec")
91+
end
92+
93+
# Checks if the filename indicates a test module
94+
# @param pathname [Pathname] The pathname to check
95+
# @return [Boolean]
96+
# :reek:UtilityFunction
97+
def filename_is_test?(pathname)
98+
filename = pathname.basename.to_s
99+
filename.end_with?("_test.rb", "_spec.rb")
100+
end
16101
end
17102
end

test/lib/skunk/commands/status_reporter_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require "test_helper"
44

55
require "rubycritic/analysers_runner"
6+
require "skunk/rubycritic/analysed_modules_collection"
67
require "skunk/commands/status_reporter"
78

89
describe Skunk::Command::StatusReporter do

0 commit comments

Comments
 (0)