Skip to content
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* [BUGFIX: Fix JSON output missing Code and Tests total count](https://github.com/fastruby/rails_stats/pull/40)
* Update README examples
* [FEATURE: Output number of table created from schema.rb or structure.sql, add STI count add polymorphic models count](https://github.com/fastruby/rails_stats/pull/37)

# v2.0.1 ([commits](https://github.com/fastruby/rails_stats/compare/v2.0.0...v2.0.1))

Expand Down
21 changes: 21 additions & 0 deletions lib/rails_stats/console_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ def to_s
end

print_code_test_stats
print_sti_stats
print_polymorphic_stats
print_schema_stats
end

private
Expand Down Expand Up @@ -53,5 +56,23 @@ def print_code_test_stats
puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f/code)} Files: #{calculator.files_total}"
puts ""
end

def print_sti_stats
puts " STI models count: #{calculator.sti} STI classes"
end

def print_polymorphic_stats
puts " Polymorphic models count: #{calculator.polymorphic} polymorphic associations"
end

def print_schema_stats
if File.exist?(calculator.schema_path)
puts " Schema Stats: #{calculator.schema} `create_table` calls in schema.rb"
elsif File.exist?(calculator.structure_path)
puts " Schema Stats: #{calculator.schema} `CREATE TABLE` calls in structure.sql"
else
puts " Schema Stats: No schema.rb or structure.sql file found"
end
end
end
end
38 changes: 37 additions & 1 deletion lib/rails_stats/json_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ def result
@result << stat_hash("Tests", @tests_total).merge(code_test_hash) if @tests_total
@result << stat_hash("Total", @grand_total).merge(code_test_hash) if @grand_total

@result << { "schema_stats" => schema_info }
@result << { "sti_stats" => print_sti_stat }
@result << { "polymorphic_stats" => print_polymorphic_stats }

@result
end

Expand Down Expand Up @@ -50,5 +54,37 @@ def stat_hash(name, statistics)
"loc_over_m" => loc_over_m.to_s
}
end

def print_sti_stat
if calculator.sti
{
"sti_models_count" => calculator.sti,
}
end
end

def print_polymorphic_stats
if calculator.polymorphic
{
"polymorphic_models_count" => calculator.polymorphic,
}
end
end

def schema_info
if File.exist?(calculator.schema_path)
{
"schema_path" => calculator.schema_path,
"create_table calls count" => calculator.schema,
}
elsif File.exist?(calculator.structure_path)
{
"structure_path" => calculator.structure_path,
"create_table calls count" => calculator.schema
}
else
{ "schema_stats" => "No schema.rb or structure.sql file found" }
end
end
end
end
end
51 changes: 48 additions & 3 deletions lib/rails_stats/stats_calculator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@ class StatsCalculator

def initialize(root_directory)
@root_directory = root_directory
@schema_path = File.join(@root_directory, "db", "schema.rb")
@structure_path = File.join(@root_directory, "db", "structure.sql")
@key_concepts = calculate_key_concepts
@projects = calculate_projects
@statistics = calculate_statistics
@code_loc = calculate_code
@test_loc = calculate_tests
@schema = calculate_create_table_calls
@sti = calculate_sti
@polymorphic = calculate_polymorphic
@files_total, @code_total, @tests_total, @grand_total = calculate_totals
end

attr_reader :code_loc, :code_total, :files_total, :grand_total, :statistics, :test_loc, :tests_total
attr_reader :code_loc, :code_total, :files_total, :grand_total, :statistics, :test_loc, :tests_total, :schema, :schema_path, :structure_path, :sti, :polymorphic

private

Expand Down Expand Up @@ -46,7 +51,6 @@ def calculate_projects
out
end


def app_projects
@app_projects ||= calculate_app_projects
end
Expand Down Expand Up @@ -79,7 +83,6 @@ def calculate_test_projects
end
end


def calculate_root_projects
[RootStatistics.new(@root_directory)]
end
Expand Down Expand Up @@ -133,5 +136,47 @@ def calculate_tests
@statistics.each { |k, v| @test_loc += v.code_lines if v.test }
@test_loc
end

def calculate_create_table_calls
if @schema_path && File.exist?(@schema_path)
count_create_table_calls(schema_path, "create_table")
elsif @structure_path && File.exist?(@structure_path)
count_create_table_calls(structure_path, "CREATE TABLE")
else
0
end
end

def count_create_table_calls(file_path, keyword)
create_table_count = 0
File.foreach(file_path) do |line|
create_table_count += 1 if line.strip.start_with?(keyword)
end
create_table_count
end

def calculate_sti
@sti = 0
Dir.glob(File.join(@root_directory, "app", "models", "*.rb")).each do |file|
File.foreach(file) do |line|
if line =~ /class\s+(\w+)\s*<\s*(\w+)/ && !(line =~ /class\s+(\w+)\s*<\s*(ActiveRecord::Base|ApplicationRecord)/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hmdros I think this is too optimistic and it will generate false positives in certain applications.

Many projects use app/models as a place to put models that don't necessarily extend an ActiveRecord::Base|ApplicationRecord descendant.

I see that in your test you have this example:

class Pets < User
end

That's certainly an STI.

But what if someone has this in their app/models directory:

class Pets < User
end

And then:

class User 
...
end

That is not an STI and it will be counted as one (or two?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree that this can get confusing and the code to check this would need to be extra careful for this. I can try to get this in a different PR then. Removing

@sti += 1
end
end
end
@sti
end

def calculate_polymorphic
polymorphic_count = 0
Dir.glob(File.join(@root_directory, "app", "models", "*.rb")).each do |file|
File.foreach(file) do |line|
if line =~ /belongs_to\s+:\w+,\s+polymorphic:\s+true/
polymorphic_count += 1
end
end
end
polymorphic_count
end
end
end
3 changes: 3 additions & 0 deletions test/dummy/app/models/comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Comments < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
2 changes: 2 additions & 0 deletions test/dummy/app/models/pet.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Pets < User
end
2 changes: 2 additions & 0 deletions test/dummy/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Users < ApplicationRecord
end
10 changes: 10 additions & 0 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

ActiveRecord::Schema[7.0].define(version: 2023_04_25_154701) do
create_table "users", force: :cascade do |t|
t.string "email"
end
create_table "comments", force: :cascade do |t|
t.bigint :commentable_id
t.string :commentable_type
end
end
14 changes: 9 additions & 5 deletions test/fixtures/console-output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,24 @@
| Name | Files | Lines | LOC | Classes | Methods | M/C | LOC/M |
+----------------------+---------+---------+---------+---------+---------+-----+-------+
| Channels | 2 | 8 | 8 | 2 | 0 | 0 | 0 |
| Configuration | 19 | 417 | 111 | 1 | 0 | 0 | 0 |
| Configuration | 19 | 417 | 111 | 1 | 0 | 0 | 0 |
| Controllers | 1 | 7 | 6 | 1 | 1 | 1 | 4 |
| Helpers | 1 | 3 | 3 | 0 | 0 | 0 | 0 |
| Javascripts | 3 | 27 | 7 | 0 | 0 | 0 | 0 |
| Jobs | 1 | 7 | 2 | 1 | 0 | 0 | 0 |
| Libraries | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| Mailers | 1 | 4 | 4 | 1 | 0 | 0 | 0 |
| Model Tests | 2 | 5 | 4 | 2 | 0 | 0 | 0 |
| Models | 1 | 3 | 3 | 1 | 0 | 0 | 0 |
| Models | 4 | 10 | 10 | 4 | 0 | 0 | 0 |
| Spec Support | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| Test Support | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
+----------------------+---------+---------+---------+---------+---------+-----+-------+
| Code | 30 | 477 | 145 | 7 | 1 | 0 | 143 |
| Code | 33 | 484 | 152 | 10 | 1 | 0 | 150 |
| Tests | 4 | 7 | 6 | 2 | 0 | 0 | 0 |
| Total | 34 | 484 | 151 | 9 | 1 | 0 | 149 |
| Total | 37 | 491 | 158 | 12 | 1 | 0 | 156 |
+----------------------+---------+---------+---------+---------+---------+-----+-------+
Code LOC: 145 Test LOC: 6 Code to Test Ratio: 1:0.0 Files: 34
Code LOC: 152 Test LOC: 6 Code to Test Ratio: 1:0.0 Files: 37

STI models count: 1 STI classes
Polymorphic models count: 1 polymorphic associations
Schema Stats: 2 `create_table` calls in schema.rb
5 changes: 4 additions & 1 deletion test/lib/rails_stats/code_statistics_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
RailsStats::CodeStatistics.new(root_directory).to_s
end

assert_equal table, out
assert_equal(
table.lines.map(&:rstrip).join,
out.lines.map(&:rstrip).join
)
end
end
end
Loading