Skip to content

Commit c6e3336

Browse files
authored
Merge pull request rails#52701 from p8/railties/namespace-code-statistics
Namespace CodeStatistics and CodeStatisticsCalculator to Rails
2 parents ec667e5 + 8c19758 commit c6e3336

File tree

8 files changed

+216
-212
lines changed

8 files changed

+216
-212
lines changed

railties/CHANGELOG.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
* Deprecate `::STATS_DIRECTORIES`.
22

33
The global constant `STATS_DIRECTORIES` has been deprecated in favor of
4-
`CodeStatistics.add_directory`.
4+
`Rails::CodeStatistics.add_directory`.
55

6-
Add extra directories with `CodeStatistics.add_directory(label, path)`:
6+
Add extra directories with `Rails::CodeStatistics.add_directory(label, path)`:
77

88
```ruby
99
require "rails/code_statistics"
10-
CodeStatistics.add_directory('My Directory', 'path/to/dir')
10+
Rails::CodeStatistics.add_directory('My Directory', 'path/to/dir')
1111
```
1212

1313
*Petrik de Heus*

railties/lib/rails/code_statistics.rb

Lines changed: 122 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -3,149 +3,151 @@
33
require "rails/code_statistics_calculator"
44
require "active_support/core_ext/enumerable"
55

6-
class CodeStatistics
7-
DIRECTORIES = [
8-
%w(Controllers app/controllers),
9-
%w(Helpers app/helpers),
10-
%w(Jobs app/jobs),
11-
%w(Models app/models),
12-
%w(Mailers app/mailers),
13-
%w(Mailboxes app/mailboxes),
14-
%w(Channels app/channels),
15-
%w(Views app/views),
16-
%w(JavaScripts app/assets/javascripts),
17-
%w(Stylesheets app/assets/stylesheets),
18-
%w(JavaScript app/javascript),
19-
%w(Libraries lib/),
20-
%w(APIs app/apis),
21-
%w(Controller\ tests test/controllers),
22-
%w(Helper\ tests test/helpers),
23-
%w(Job\ tests test/jobs),
24-
%w(Model\ tests test/models),
25-
%w(Mailer\ tests test/mailers),
26-
%w(Mailbox\ tests test/mailboxes),
27-
%w(Channel\ tests test/channels),
28-
%w(Integration\ tests test/integration),
29-
%w(System\ tests test/system),
30-
]
31-
32-
TEST_TYPES = ["Controller tests",
33-
"Helper tests",
34-
"Model tests",
35-
"Mailer tests",
36-
"Mailbox tests",
37-
"Channel tests",
38-
"Job tests",
39-
"Integration tests",
40-
"System tests"]
41-
42-
HEADERS = { lines: " Lines", code_lines: " LOC", classes: "Classes", methods: "Methods" }
43-
44-
class_attribute :directories, default: DIRECTORIES
45-
46-
# Add directories to the output of the `bin/rails stats` command.
47-
#
48-
# CodeStatistics.add_directory("My Directory", "path/to/dir")
49-
def self.add_directory(label, path)
50-
self.directories << [label, path]
51-
end
52-
53-
def initialize(*pairs)
54-
@pairs = pairs
55-
@statistics = calculate_statistics
56-
@total = calculate_total if pairs.length > 1
57-
end
6+
module Rails
7+
class CodeStatistics
8+
DIRECTORIES = [
9+
%w(Controllers app/controllers),
10+
%w(Helpers app/helpers),
11+
%w(Jobs app/jobs),
12+
%w(Models app/models),
13+
%w(Mailers app/mailers),
14+
%w(Mailboxes app/mailboxes),
15+
%w(Channels app/channels),
16+
%w(Views app/views),
17+
%w(JavaScripts app/assets/javascripts),
18+
%w(Stylesheets app/assets/stylesheets),
19+
%w(JavaScript app/javascript),
20+
%w(Libraries lib/),
21+
%w(APIs app/apis),
22+
%w(Controller\ tests test/controllers),
23+
%w(Helper\ tests test/helpers),
24+
%w(Job\ tests test/jobs),
25+
%w(Model\ tests test/models),
26+
%w(Mailer\ tests test/mailers),
27+
%w(Mailbox\ tests test/mailboxes),
28+
%w(Channel\ tests test/channels),
29+
%w(Integration\ tests test/integration),
30+
%w(System\ tests test/system),
31+
]
32+
33+
TEST_TYPES = ["Controller tests",
34+
"Helper tests",
35+
"Model tests",
36+
"Mailer tests",
37+
"Mailbox tests",
38+
"Channel tests",
39+
"Job tests",
40+
"Integration tests",
41+
"System tests"]
42+
43+
HEADERS = { lines: " Lines", code_lines: " LOC", classes: "Classes", methods: "Methods" }
44+
45+
class_attribute :directories, default: DIRECTORIES
46+
47+
# Add directories to the output of the `bin/rails stats` command.
48+
#
49+
# Rails::CodeStatistics.add_directory("My Directory", "path/to/dir")
50+
def self.add_directory(label, path)
51+
self.directories << [label, path]
52+
end
5853

59-
def to_s
60-
print_header
61-
@pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
62-
print_splitter
54+
def initialize(*pairs)
55+
@pairs = pairs
56+
@statistics = calculate_statistics
57+
@total = calculate_total if pairs.length > 1
58+
end
6359

64-
if @total
65-
print_line("Total", @total)
60+
def to_s
61+
print_header
62+
@pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
6663
print_splitter
67-
end
6864

69-
print_code_test_stats
70-
end
65+
if @total
66+
print_line("Total", @total)
67+
print_splitter
68+
end
7169

72-
private
73-
def calculate_statistics
74-
Hash[@pairs.map { |pair| [pair.first, calculate_directory_statistics(pair.last)] }]
70+
print_code_test_stats
7571
end
7672

77-
def calculate_directory_statistics(directory, pattern = /^(?!\.).*?\.(rb|js|ts|css|scss|coffee|rake|erb)$/)
78-
stats = CodeStatisticsCalculator.new
73+
private
74+
def calculate_statistics
75+
Hash[@pairs.map { |pair| [pair.first, calculate_directory_statistics(pair.last)] }]
76+
end
77+
78+
def calculate_directory_statistics(directory, pattern = /^(?!\.).*?\.(rb|js|ts|css|scss|coffee|rake|erb)$/)
79+
stats = Rails::CodeStatisticsCalculator.new
7980

80-
Dir.foreach(directory) do |file_name|
81-
path = "#{directory}/#{file_name}"
81+
Dir.foreach(directory) do |file_name|
82+
path = "#{directory}/#{file_name}"
8283

83-
if File.directory?(path) && !file_name.start_with?(".")
84-
stats.add(calculate_directory_statistics(path, pattern))
85-
elsif file_name&.match?(pattern)
86-
stats.add_by_file_path(path)
84+
if File.directory?(path) && !file_name.start_with?(".")
85+
stats.add(calculate_directory_statistics(path, pattern))
86+
elsif file_name&.match?(pattern)
87+
stats.add_by_file_path(path)
88+
end
8789
end
88-
end
8990

90-
stats
91-
end
91+
stats
92+
end
9293

93-
def calculate_total
94-
@statistics.each_with_object(CodeStatisticsCalculator.new) do |pair, total|
95-
total.add(pair.last)
94+
def calculate_total
95+
@statistics.each_with_object(Rails::CodeStatisticsCalculator.new) do |pair, total|
96+
total.add(pair.last)
97+
end
9698
end
97-
end
9899

99-
def calculate_code
100-
code_loc = 0
101-
@statistics.each { |k, v| code_loc += v.code_lines unless TEST_TYPES.include? k }
102-
code_loc
103-
end
100+
def calculate_code
101+
code_loc = 0
102+
@statistics.each { |k, v| code_loc += v.code_lines unless TEST_TYPES.include? k }
103+
code_loc
104+
end
104105

105-
def calculate_tests
106-
test_loc = 0
107-
@statistics.each { |k, v| test_loc += v.code_lines if TEST_TYPES.include? k }
108-
test_loc
109-
end
106+
def calculate_tests
107+
test_loc = 0
108+
@statistics.each { |k, v| test_loc += v.code_lines if TEST_TYPES.include? k }
109+
test_loc
110+
end
110111

111-
def width_for(label)
112-
[@statistics.values.sum { |s| s.public_send(label) }.to_s.size, HEADERS[label].length].max
113-
end
112+
def width_for(label)
113+
[@statistics.values.sum { |s| s.public_send(label) }.to_s.size, HEADERS[label].length].max
114+
end
114115

115-
def print_header
116-
print_splitter
117-
print "| Name "
118-
HEADERS.each do |k, v|
119-
print " | #{v.rjust(width_for(k))}"
116+
def print_header
117+
print_splitter
118+
print "| Name "
119+
HEADERS.each do |k, v|
120+
print " | #{v.rjust(width_for(k))}"
121+
end
122+
puts " | M/C | LOC/M |"
123+
print_splitter
120124
end
121-
puts " | M/C | LOC/M |"
122-
print_splitter
123-
end
124125

125-
def print_splitter
126-
print "+----------------------"
127-
HEADERS.each_key do |k|
128-
print "+#{'-' * (width_for(k) + 2)}"
126+
def print_splitter
127+
print "+----------------------"
128+
HEADERS.each_key do |k|
129+
print "+#{'-' * (width_for(k) + 2)}"
130+
end
131+
puts "+-----+-------+"
129132
end
130-
puts "+-----+-------+"
131-
end
132133

133-
def print_line(name, statistics)
134-
m_over_c = (statistics.methods / statistics.classes) rescue 0
135-
loc_over_m = (statistics.code_lines / statistics.methods) - 2 rescue 0
134+
def print_line(name, statistics)
135+
m_over_c = (statistics.methods / statistics.classes) rescue 0
136+
loc_over_m = (statistics.code_lines / statistics.methods) - 2 rescue 0
136137

137-
print "| #{name.ljust(20)} "
138-
HEADERS.each_key do |k|
139-
print "| #{statistics.send(k).to_s.rjust(width_for(k))} "
138+
print "| #{name.ljust(20)} "
139+
HEADERS.each_key do |k|
140+
print "| #{statistics.send(k).to_s.rjust(width_for(k))} "
141+
end
142+
puts "| #{m_over_c.to_s.rjust(3)} | #{loc_over_m.to_s.rjust(5)} |"
140143
end
141-
puts "| #{m_over_c.to_s.rjust(3)} | #{loc_over_m.to_s.rjust(5)} |"
142-
end
143144

144-
def print_code_test_stats
145-
code = calculate_code
146-
tests = calculate_tests
145+
def print_code_test_stats
146+
code = calculate_code
147+
tests = calculate_tests
147148

148-
puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f / code)}"
149-
puts ""
150-
end
149+
puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f / code)}"
150+
puts ""
151+
end
152+
end
151153
end

0 commit comments

Comments
 (0)