Skip to content

Commit 0d827b8

Browse files
committed
Move Console Report out of Status Reporter
The status reporter has a different purpuse in the RubyCritic gem, they also have the specific usage of the Console Report and now we are following the same patters that gem created. - Added support for a new console output format in the FormatValidator module. - Refactored the StatusReporter to provide a simplified status message upon completion of analysis. - Introduced ConsoleReport and Simple classes for generating detailed console reports of analysed modules. - Updated tests to validate new console reporting functionality and ensure expected outputs. - Adjusted existing tests to reflect changes in the status reporting method.
1 parent 98ef469 commit 0d827b8

File tree

14 files changed

+704
-85
lines changed

14 files changed

+704
-85
lines changed

.rubocop_todo.yml

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This configuration was generated by
22
# `rubocop --auto-gen-config`
3-
# on 2025-10-17 16:20:40 UTC using RuboCop version 1.81.1.
3+
# on 2025-10-17 22:53:06 UTC using RuboCop version 1.81.1.
44
# The point is for the user to remove these configuration records
55
# one by one as the offenses are removed from the code base.
66
# Note that changes in the inspected code, or installation of new
@@ -13,16 +13,9 @@ Gemspec/RequiredRubyVersion:
1313
- 'skunk.gemspec'
1414

1515
# Offense count: 1
16-
# This cop supports safe autocorrection (--autocorrect).
17-
Layout/ClosingHeredocIndentation:
18-
Exclude:
19-
- 'lib/skunk/commands/status_reporter.rb'
20-
21-
# Offense count: 1
22-
# This cop supports safe autocorrection (--autocorrect).
23-
Layout/HeredocIndentation:
16+
Lint/IneffectiveAccessModifier:
2417
Exclude:
25-
- 'lib/skunk/commands/status_reporter.rb'
18+
- 'lib/skunk/generators/console/simple.rb'
2619

2720
# Offense count: 2
2821
# Configuration parameters: AllowedParentClasses.
@@ -31,21 +24,21 @@ Lint/MissingSuper:
3124
- 'lib/skunk/cli/application.rb'
3225
- 'lib/skunk/generators/html/overview.rb'
3326

34-
# Offense count: 1
27+
# Offense count: 4
3528
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
3629
Metrics/AbcSize:
37-
Max: 18
30+
Max: 24
3831

39-
# Offense count: 12
32+
# Offense count: 14
4033
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
4134
# AllowedMethods: refine
4235
Metrics/BlockLength:
43-
Max: 233
36+
Max: 208
4437

45-
# Offense count: 2
38+
# Offense count: 5
4639
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
4740
Metrics/MethodLength:
48-
Max: 13
41+
Max: 18
4942

5043
# Offense count: 1
5144
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
@@ -55,6 +48,16 @@ Naming/VariableNumber:
5548
Exclude:
5649
- 'lib/skunk/commands/status_sharer.rb'
5750

51+
# Offense count: 1
52+
# This cop supports unsafe autocorrection (--autocorrect-all).
53+
# Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules.
54+
# SupportedStyles: nested, compact
55+
# SupportedStylesForClasses: ~, nested, compact
56+
# SupportedStylesForModules: ~, nested, compact
57+
Style/ClassAndModuleChildren:
58+
Exclude:
59+
- 'test/test_helper.rb'
60+
5861
# Offense count: 1
5962
# This cop supports unsafe autocorrection (--autocorrect-all).
6063
# Configuration parameters: EnforcedStyle.
@@ -63,3 +66,10 @@ Style/FrozenStringLiteralComment:
6366
Exclude:
6467
- '**/*.arb'
6568
- 'bin/console'
69+
70+
# Offense count: 2
71+
# This cop supports safe autocorrection (--autocorrect).
72+
# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
73+
# URISchemes: http, https
74+
Layout/LineLength:
75+
Max: 124

lib/skunk/cli/application.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
require "skunk"
77
require "skunk/rubycritic/analysed_module"
8+
require "skunk/rubycritic/analysed_modules_collection"
89
require "skunk/cli/options"
910
require "skunk/command_factory"
1011
require "skunk/commands/status_sharer"

lib/skunk/cli/options/argv.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Argv < RubyCritic::Cli::Options::Argv
1212
# :reek:Attribute
1313
attr_accessor :output_filename
1414

15-
def parse # rubocop:disable Metrics/MethodLength
15+
def parse
1616
parser.new do |opts|
1717
opts.banner = "Usage: skunk [options] [paths]\n"
1818

lib/skunk/commands/status_reporter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def initialize(options = {})
1212
super(options)
1313
end
1414

15+
# Returns a simple status message indicating the analysis is complete
1516
def update_status_message
1617
@status_message = "Skunk Report Completed"
1718
end

lib/skunk/config.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module Skunk
44
# Utility module for format validation
55
module FormatValidator
66
# Supported output formats
7-
SUPPORTED_FORMATS = %i[json html].freeze
7+
SUPPORTED_FORMATS = %i[json html console].freeze
88

99
# Check if a format is supported
1010
# @param format [Symbol] Format to check
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# frozen_string_literal: true
2+
3+
require "erb"
4+
require "terminal-table"
5+
6+
module Skunk
7+
module Generator
8+
module Console
9+
# Generates a console report for the analysed modules.
10+
class Simple
11+
def initialize(analysed_modules)
12+
@analysed_modules = analysed_modules
13+
end
14+
15+
HEADINGS = %w[file skunk_score churn_times_cost churn cost coverage].freeze
16+
HEADINGS_WITHOUT_FILE = HEADINGS - %w[file]
17+
HEADINGS_WITHOUT_FILE_WIDTH = HEADINGS_WITHOUT_FILE.size * 17 # padding
18+
19+
TEMPLATE = ERB.new(<<~TEMPL
20+
<%= _ttable %>
21+
22+
SkunkScore Total: <%= total_skunk_score %>
23+
Modules Analysed: <%= analysed_modules_count %>
24+
SkunkScore Average: <%= skunk_score_average %>
25+
<% if worst %>Worst SkunkScore: <%= worst.skunk_score %> (<%= worst.pathname %>)<% end %>
26+
27+
Generated with Skunk v<%= Skunk::VERSION %>
28+
TEMPL
29+
)
30+
31+
def render
32+
opts = table_options.merge(headings: HEADINGS, rows: table)
33+
_ttable = Terminal::Table.new(opts)
34+
TEMPLATE.result(binding)
35+
end
36+
37+
private
38+
39+
def analysed_modules_count
40+
@analysed_modules.analysed_modules_count
41+
end
42+
43+
def worst
44+
@analysed_modules.worst_module
45+
end
46+
47+
def sorted_modules
48+
@analysed_modules.sorted_modules
49+
end
50+
51+
def total_skunk_score
52+
@analysed_modules.skunk_score_total
53+
end
54+
55+
def total_churn_times_cost
56+
@analysed_modules.total_churn_times_cost
57+
end
58+
59+
def skunk_score_average
60+
@analysed_modules.skunk_score_average
61+
end
62+
63+
def table_options
64+
return { style: { width: 100 } } if sorted_modules.empty?
65+
66+
max = sorted_modules.max_by { |a_mod| a_mod.pathname.to_s.length }
67+
width = max.pathname.to_s.length + HEADINGS_WITHOUT_FILE_WIDTH
68+
{
69+
style: {
70+
width: width
71+
}
72+
}
73+
end
74+
75+
def table
76+
@analysed_modules.files_as_hash.map { |file_hash| self.class.format_hash_row(file_hash) }
77+
end
78+
79+
def self.format_hash_row(file_hash)
80+
[
81+
file_hash[:file],
82+
file_hash[:skunk_score],
83+
file_hash[:churn_times_cost],
84+
file_hash[:churn],
85+
file_hash[:cost],
86+
file_hash[:coverage]
87+
]
88+
end
89+
end
90+
end
91+
end
92+
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# frozen_string_literal: true
2+
3+
require "erb"
4+
require "terminal-table"
5+
6+
require "skunk/generators/console/simple"
7+
8+
module Skunk
9+
module Generator
10+
# Generates a console report for the analysed modules.
11+
class ConsoleReport
12+
def initialize(analysed_modules)
13+
@analysed_modules = analysed_modules
14+
end
15+
16+
def generate_report
17+
puts generator.render
18+
end
19+
20+
private
21+
22+
def generator
23+
@generator ||= Skunk::Generator::Console::Simple.new(@analysed_modules)
24+
end
25+
end
26+
end
27+
end

lib/skunk/rubycritic/analysed_modules_collection.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ def to_hash
6565
}
6666
end
6767

68-
private
69-
7068
# Returns files as an array of hashes (for JSON serialization)
7169
# @return [Array<Hash>]
7270
def files_as_hash
7371
@files_as_hash ||= sorted_modules.map(&:to_hash)
7472
end
7573

74+
private
75+
7676
# Determines if a module is a test module based on its path
7777
# @param a_module [RubyCritic::AnalysedModule] The module to check
7878
# @return [Boolean]

test/lib/skunk/application_test.rb

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,6 @@
3535
end
3636
end
3737

38-
context "when passing --out option with a file" do
39-
require "fileutils"
40-
41-
let(:argv) { ["--out=tmp/generated_report.txt", "samples/rubycritic"] }
42-
let(:success_code) { 0 }
43-
44-
it "writes output to the file" do
45-
FileUtils.rm("tmp/generated_report.txt", force: true)
46-
FileUtils.mkdir_p("tmp")
47-
48-
RubyCritic::AnalysedModule.stub_any_instance(:churn, 1) do
49-
RubyCritic::AnalysedModule.stub_any_instance(:coverage, 100.0) do
50-
result = application.execute
51-
_(result).must_equal success_code
52-
end
53-
end
54-
55-
_(File.read("tmp/generated_report.txt"))
56-
.must_include File.read("test/samples/console_output.txt")
57-
end
58-
end
59-
6038
context "when comparing two branches" do
6139
let(:argv) { ["-b main", "samples/rubycritic"] }
6240
let(:success_code) { 0 }

test/lib/skunk/commands/status_reporter_test.rb

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,14 @@ def analysed_module.churn
3232
example.call
3333
end
3434

35-
it "reports the SkunkScore" do
36-
_(reporter.update_status_message).must_include output
37-
_(reporter.update_status_message).must_include "Generated with Skunk v#{Skunk::VERSION}"
35+
it "reports a simple status message" do
36+
_(reporter.update_status_message).must_equal "Skunk analysis complete. Use --format console to see detailed output."
3837
end
3938

4039
context "When there's nested spec files" do
4140
let(:paths) { "samples" }
42-
it "reports the SkunkScore" do
43-
_(reporter.update_status_message).must_include output
44-
_(reporter.update_status_message).must_include "Generated with Skunk v#{Skunk::VERSION}"
41+
it "reports a simple status message" do
42+
_(reporter.update_status_message).must_equal "Skunk analysis complete. Use --format console to see detailed output."
4543
end
4644
end
4745
end

0 commit comments

Comments
 (0)