Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JSON output format option to rails stats command #51675

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 30 additions & 0 deletions railties/CHANGELOG.md
@@ -1,3 +1,33 @@
* Add JSON output format to `rails stats` via `format` option.

Enables JSON formatted output for better integration with automated systems. Maintains default table format unless specified.

```shell
$ bin/rails stats[json] | jq .
{
"code_statistics": [
{
"name": "Controllers",
"statistic": {
"lines": 12345,
"code_lines": 12345,
"classes": 123,
"methods": 1234
}
},
...
],
"total": {
"lines": 12345,
"code_lines": 12345,
"classes": 123,
"methods": 1234
}
}
```

*Teppei Shintani*

* Allow Actionable Errors encountered when running tests to be retried.

```txt
Expand Down
12 changes: 12 additions & 0 deletions railties/lib/rails/code_statistics.rb
Expand Up @@ -35,6 +35,18 @@ def to_s
print_code_test_stats
end

def to_h
{
code_statistics: @statistics.map do |k, v|
{
name: k,
statistic: v.to_h
}
end,
total: @total&.to_h
}
end

private
def calculate_statistics
Hash[@pairs.map { |pair| [pair.first, calculate_directory_statistics(pair.last)] }]
Expand Down
9 changes: 9 additions & 0 deletions railties/lib/rails/code_statistics_calculator.rb
Expand Up @@ -86,6 +86,15 @@ def add_by_io(io, file_type)
end
end

def to_h
{
lines: lines,
code_lines: code_lines,
classes: classes,
methods: methods
}
end

private
def file_type(file_path)
if file_path.end_with? "_test.rb"
Expand Down
10 changes: 8 additions & 2 deletions railties/lib/rails/tasks/statistics.rake
Expand Up @@ -29,10 +29,16 @@ STATS_DIRECTORIES ||= [
]

desc "Report code statistics (KLOCs, etc) from the application or engine"
task :stats do
task :stats, :format do |_, args|
require "rails/code_statistics"
stat_directories = STATS_DIRECTORIES.collect do |name, dir|
[ name, "#{File.dirname(Rake.application.rakefile_location)}/#{dir}" ]
end.select { |name, dir| File.directory?(dir) }
CodeStatistics.new(*stat_directories).to_s
statistics = CodeStatistics.new(*stat_directories)
case args[:format]
when "json"
puts statistics.to_h.to_json
else
statistics.to_s
end
end
5 changes: 5 additions & 0 deletions railties/test/code_statistics_calculator_test.rb
Expand Up @@ -84,6 +84,11 @@ class A; end
assert_equal 6, @code_statistics_calculator.methods
end

test "return statistics as a hash" do
code_statistics_calculator = CodeStatisticsCalculator.new(1, 2, 3, 4)
assert_equal({ lines: 1, code_lines: 2, classes: 3, methods: 4 }, code_statistics_calculator.to_h)
end

test "calculate number of Ruby methods" do
code = <<-'CODE'
def foo
Expand Down
55 changes: 55 additions & 0 deletions railties/test/code_statistics_test.rb
Expand Up @@ -31,4 +31,59 @@ def foo
CodeStatistics.new(["hidden file", @tmp_path])
end
end

test "output results in table format" do
File.write File.join(@tmp_path, "example.rb"), <<-CODE
class Example
def foo
puts 'foo'
end
end
CODE

code_statistics = CodeStatistics.new(["tmp dir", @tmp_path])
expected = <<~TABLE
+----------------------+--------+--------+---------+---------+-----+-------+
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
+----------------------+--------+--------+---------+---------+-----+-------+
| tmp dir | 5 | 5 | 1 | 1 | 1 | 3 |
+----------------------+--------+--------+---------+---------+-----+-------+
Code LOC: 5 Test LOC: 0 Code to Test Ratio: 1:0.0

TABLE

output, _ = capture_io do
code_statistics.to_s
end

assert_equal expected, output
end

test "return results in hash format" do
File.write File.join(@tmp_path, "example.rb"), <<-CODE
class Example
def foo
puts 'foo'
end
end
CODE

code_statistics = CodeStatistics.new(["tmp dir", @tmp_path])
expected = {
code_statistics: [
{
name: "tmp dir",
statistic: {
lines: 5,
code_lines: 5,
classes: 1,
methods: 1
}
}
],
total: nil
}

assert_equal expected, code_statistics.to_h
end
end