rails_stats 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/README.md +95 -18
- data/bin/rails-stats +27 -0
- data/lib/rails_stats/all.rb +8 -0
- data/lib/rails_stats/app_statistics.rb +1 -1
- data/lib/rails_stats/console_formatter.rb +42 -10
- data/lib/rails_stats/cucumber_statistics.rb +1 -1
- data/lib/rails_stats/gem_statistics.rb +1 -1
- data/lib/rails_stats/json_formatter.rb +18 -0
- data/lib/rails_stats/pack_finder.rb +67 -0
- data/lib/rails_stats/root_statistics.rb +1 -1
- data/lib/rails_stats/spec_statistics.rb +1 -1
- data/lib/rails_stats/stats_calculator.rb +101 -3
- data/lib/rails_stats/stats_formatter.rb +1 -0
- data/lib/rails_stats/tasks.rb +4 -1
- data/lib/rails_stats/test_statistics.rb +1 -1
- data/lib/rails_stats/util.rb +9 -1
- data/lib/rails_stats/version.rb +1 -1
- data/rails_stats.gemspec +4 -3
- data/test/fixtures/packwerk_app/app/controllers/core_controller.rb +4 -0
- data/test/fixtures/packwerk_app/app/models/core_model.rb +5 -0
- data/test/fixtures/packwerk_app/components/billing/app/models/billing_model.rb +4 -0
- data/test/fixtures/packwerk_app/components/billing/lib/billing.rb +2 -0
- data/test/fixtures/packwerk_app/lib/core_lib.rb +3 -0
- data/test/fixtures/packwerk_app/package.yml +1 -0
- data/test/fixtures/packwerk_app/packs/pack1/app/controllers/pack1_controller.rb +4 -0
- data/test/fixtures/packwerk_app/packs/pack1/app/models/pack1_model.rb +6 -0
- data/test/fixtures/packwerk_app/packs/pack1/lib/pack1_lib.rb +2 -0
- data/test/fixtures/packwerk_app/packs/pack1/package.yml +3 -0
- data/test/fixtures/packwerk_app/packs/pack1/spec/models/pack1_model_spec.rb +4 -0
- data/test/fixtures/packwerk_app/packs/pack2/app/models/pack2_model.rb +4 -0
- data/test/fixtures/packwerk_app/packs/pack2/test/models/pack2_model_test.rb +4 -0
- data/test/lib/rails_stats/console_formatter_test.rb +22 -0
- data/test/lib/rails_stats/pack_finder_test.rb +29 -0
- data/test/lib/rails_stats/stats_calculator_test.rb +64 -0
- data/test/lib/rails_stats/util_test.rb +49 -0
- metadata +44 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c0ec937a76e806cef21dd005c123dc0cea07bdf4f83d565ee8d141b3169dda2
|
|
4
|
+
data.tar.gz: e9d5aa5cf96dd02b9cd26247e2a41fa0aa44d812230176e1fd3af76e1a3bd593
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fcf370eb0f981441c2ea4c7a4ae54027c10daa03be92aa23b1c0455d95b98b697477dc04b18d7f9afe16f9a6b1bbdd3d3642b5acfeb7d3dcf5f7bf1395163e5a
|
|
7
|
+
data.tar.gz: fb0d687f57af91b8bb48caf85a4c9bfbc05a49ed4fdc73f7bf4d521a70a1824a84956854af11238d278eccf785c38baeb762964c0b5eb3b5b4b49335730fc488
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
# main ([unreleased](https://github.com/fastruby/rails_stats/compare/v2.
|
|
1
|
+
# main ([unreleased](https://github.com/fastruby/rails_stats/compare/v2.2.0...main))
|
|
2
2
|
|
|
3
|
+
* [FEATURE: ABC](LINK)
|
|
4
|
+
|
|
5
|
+
# v2.2.0 ([commits](https://github.com/fastruby/rails_stats/compare/v2.2.0...v2.1.0))
|
|
6
|
+
|
|
7
|
+
* [FEATURE: Add a `rails-stats` command line executable that accepts an absolute or relative directory](https://github.com/fastruby/rails_stats/pull/49)
|
|
8
|
+
* [FEATURE: Support component-based and Packwerk (packs) applications with a per-pack and Core breakdown](https://github.com/fastruby/rails_stats/issues/23)
|
|
9
|
+
* [BUGFIX: Respect an explicit path argument (e.g. `rake stats[packs/pack1]`) when running inside a booted Rails app](https://github.com/fastruby/rails_stats/issues/23)
|
|
3
10
|
* [CHORE: Improve the GH Test Workflow](https://github.com/fastruby/rails_stats/pull/35)
|
|
4
11
|
* [BUGFIX: Explicitly set format as text for `Bundler::Stats::CLI` on `ConsoleFormatter`](https://github.com/fastruby/rails_stats/pull/43)
|
|
5
12
|
|
data/README.md
CHANGED
|
@@ -6,22 +6,62 @@ There were a few things missing to the included `rake stats`
|
|
|
6
6
|
|
|
7
7
|
RailsStats mainly adds the ability to be run from outside the project in question. This can be helpful if the app you are interested in can not be booted for some reason.
|
|
8
8
|
|
|
9
|
-
### Run it
|
|
9
|
+
### Run it as a command line tool
|
|
10
|
+
|
|
11
|
+
Once the gem is installed you can point the `rails-stats` executable at any
|
|
12
|
+
directory, without setting up a `Rakefile`. It accepts both absolute and
|
|
13
|
+
relative paths:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
$ rails-stats /path/to/app
|
|
17
|
+
$ rails-stats path/to/app
|
|
18
|
+
```
|
|
10
19
|
|
|
11
|
-
|
|
12
|
-
need to require `rails_stats`:
|
|
20
|
+
When no path is given it defaults to the current directory:
|
|
13
21
|
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
```bash
|
|
23
|
+
$ rails-stats
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
You can also request JSON output by passing `json` as a second argument:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
$ rails-stats path/to/app json
|
|
17
30
|
```
|
|
18
31
|
|
|
19
|
-
|
|
32
|
+
#### Calling it through `rake`
|
|
33
|
+
|
|
34
|
+
If you prefer `rake`, there are two ways to reach the same code:
|
|
35
|
+
|
|
36
|
+
- **From any directory**, add a `Rakefile` that requires `rails_stats` and call
|
|
37
|
+
the task with a path:
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
# Rakefile
|
|
41
|
+
require "rails_stats"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
$ rake stats\[/path/to/app/\]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- **Inside your own Rails app**, add `rails_stats` to your `Gemfile` to
|
|
49
|
+
_replace_ the default `rake stats` implementation (you might need to
|
|
50
|
+
`require "rails_stats"` in your `Rakefile`), then run:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
$ bundle exec rake stats
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Run it outside Rails project
|
|
57
|
+
|
|
58
|
+
The quickest way is the `rails-stats` executable, which does not require a
|
|
59
|
+
`Rakefile`:
|
|
20
60
|
|
|
21
61
|
```bash
|
|
22
|
-
$
|
|
62
|
+
$ rails-stats /path/to/app
|
|
23
63
|
|
|
24
|
-
Directory: /path/to/app
|
|
64
|
+
Directory: /path/to/app
|
|
25
65
|
|
|
26
66
|
+-----------------------|------------|----------------+
|
|
27
67
|
| Name | Total Deps | 1st Level Deps |
|
|
@@ -68,20 +108,57 @@ Directory: /path/to/app/
|
|
|
68
108
|
### Run it on many Rails engines
|
|
69
109
|
|
|
70
110
|
```bash
|
|
71
|
-
$ for dir in /path/to/many/engines/*/; do
|
|
111
|
+
$ for dir in /path/to/many/engines/*/; do rails-stats "$dir"; done
|
|
72
112
|
```
|
|
73
113
|
|
|
74
|
-
###
|
|
114
|
+
### Component-based and Packwerk (packs) applications
|
|
75
115
|
|
|
76
|
-
|
|
116
|
+
RailsStats understands large Rails monoliths that are organized into
|
|
117
|
+
[packs](https://github.com/Shopify/packwerk) (via
|
|
118
|
+
[packs-rails](https://github.com/rubyatscale/packs-rails)) or
|
|
119
|
+
[components](https://cbra.info/) (component-based Rails).
|
|
77
120
|
|
|
78
|
-
|
|
79
|
-
|
|
121
|
+
When packs or components are detected, `rails-stats` automatically prints a
|
|
122
|
+
breakdown per pack/component, a `Core Application` section for everything that
|
|
123
|
+
lives in the main app, and a `Total (all packs)` section that aggregates the
|
|
124
|
+
whole monolith:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
$ rails-stats /path/to/monolith
|
|
128
|
+
|
|
129
|
+
== Core Application ==
|
|
130
|
+
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
131
|
+
| Name | Files | Lines | LOC | Classes | Methods | M/C | LOC/M |
|
|
132
|
+
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
133
|
+
| ... |
|
|
134
|
+
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
135
|
+
|
|
136
|
+
== Pack: packs/pack1 ==
|
|
137
|
+
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
138
|
+
| ... |
|
|
139
|
+
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
140
|
+
|
|
141
|
+
== Total (all packs) ==
|
|
142
|
+
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
143
|
+
| ... |
|
|
144
|
+
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
A directory is treated as a pack when it contains a `package.yml` file (the
|
|
148
|
+
Packwerk marker) or when it lives directly under a `packs/` or `components/`
|
|
149
|
+
directory and holds any of the usual code folders (`app`, `lib`, `spec`,
|
|
150
|
+
`test`). Nested packs (`packs/a/packs/b`) are supported.
|
|
151
|
+
|
|
152
|
+
You can also scope stats to a single pack:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
$ rails-stats packs/pack1
|
|
156
|
+
```
|
|
80
157
|
|
|
81
|
-
|
|
158
|
+
The same breakdown is available in JSON under a `"packs"` key:
|
|
82
159
|
|
|
83
160
|
```bash
|
|
84
|
-
$
|
|
161
|
+
$ rails-stats . json
|
|
85
162
|
```
|
|
86
163
|
|
|
87
164
|
### Things it knows about
|
|
@@ -101,7 +178,7 @@ Here are some open source Rails projects and their output.
|
|
|
101
178
|
|
|
102
179
|
```bash
|
|
103
180
|
|
|
104
|
-
$
|
|
181
|
+
$ rails-stats /users/brian/examples/redmine/
|
|
105
182
|
|
|
106
183
|
+-----------------------|------------|----------------+
|
|
107
184
|
| Name | Total Deps | 1st Level Deps |
|
|
@@ -190,7 +267,7 @@ $ bundle exec rake stats[/users/brian/examples/redmine/]
|
|
|
190
267
|
If you want to export the details using JSON, you can use this command:
|
|
191
268
|
|
|
192
269
|
```
|
|
193
|
-
$
|
|
270
|
+
$ rails-stats test/dummy json
|
|
194
271
|
|
|
195
272
|
Directory: /Users/etagwerker/Projects/redmine
|
|
196
273
|
|
data/bin/rails-stats
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Standalone CLI for running rails_stats against a directory without having to
|
|
5
|
+
# set up a Rakefile. Accepts both absolute and relative paths:
|
|
6
|
+
#
|
|
7
|
+
# rails-stats /path/to/app
|
|
8
|
+
# rails-stats path/to/app
|
|
9
|
+
# rails-stats # defaults to the current directory
|
|
10
|
+
# rails-stats path/to/app json
|
|
11
|
+
#
|
|
12
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
|
13
|
+
|
|
14
|
+
require "rails_stats/all"
|
|
15
|
+
|
|
16
|
+
path = ARGV[0] || "."
|
|
17
|
+
format = ARGV[1] || ""
|
|
18
|
+
|
|
19
|
+
root_directory = File.absolute_path(path)
|
|
20
|
+
|
|
21
|
+
unless File.directory?(root_directory)
|
|
22
|
+
warn "rails-stats: no such directory - #{path}"
|
|
23
|
+
exit 1
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
puts "\nDirectory: #{root_directory}\n\n"
|
|
27
|
+
RailsStats::CodeStatistics.new(root_directory, format: format).to_s
|
data/lib/rails_stats/all.rb
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
module RailsStats
|
|
2
|
+
# Vendored / generated directory names we never descend into or treat as a
|
|
3
|
+
# pack. Shared by PackFinder (which builds IGNORED_PATH from it) and Util
|
|
4
|
+
# (which matches them by basename while walking the tree).
|
|
5
|
+
IGNORED_DIRS = %w[node_modules vendor tmp log .git].freeze
|
|
6
|
+
end
|
|
7
|
+
|
|
1
8
|
require 'rails_stats/stats_calculator'
|
|
2
9
|
require 'rails_stats/stats_formatter'
|
|
3
10
|
require 'rails_stats/json_formatter'
|
|
4
11
|
require 'rails_stats/console_formatter'
|
|
5
12
|
require 'rails_stats/inflector'
|
|
6
13
|
require 'rails_stats/code_statistics_calculator'
|
|
14
|
+
require 'rails_stats/pack_finder'
|
|
7
15
|
require 'rails_stats/util'
|
|
8
16
|
require 'rails_stats/app_statistics'
|
|
9
17
|
require 'rails_stats/test_statistics'
|
|
@@ -5,16 +5,10 @@ module RailsStats
|
|
|
5
5
|
def to_s
|
|
6
6
|
Bundler::Stats::CLI.start(['--format', 'text'])
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if @grand_total
|
|
14
|
-
print_line("Code", @code_total)
|
|
15
|
-
print_line("Tests", @tests_total)
|
|
16
|
-
print_line("Total", @grand_total)
|
|
17
|
-
print_splitter
|
|
8
|
+
if calculator.packs?
|
|
9
|
+
print_grouped
|
|
10
|
+
else
|
|
11
|
+
print_flat
|
|
18
12
|
end
|
|
19
13
|
|
|
20
14
|
print_code_test_stats
|
|
@@ -24,6 +18,44 @@ module RailsStats
|
|
|
24
18
|
|
|
25
19
|
private
|
|
26
20
|
|
|
21
|
+
def print_flat
|
|
22
|
+
print_table(@statistics)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def print_grouped
|
|
26
|
+
@statistics_by_group.each do |group, group_statistics|
|
|
27
|
+
puts "== #{group_label(group)} =="
|
|
28
|
+
print_table(group_statistics)
|
|
29
|
+
puts ""
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
puts "== #{grand_total_label} =="
|
|
33
|
+
print_table(@statistics)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def group_label(group)
|
|
37
|
+
group == RailsStats::StatsCalculator::CORE_GROUP ? "Core Application" : "Pack: #{group}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def grand_total_label
|
|
41
|
+
"Total (all packs)"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Prints a full table (header, one line per concept, and Code/Tests/Total
|
|
45
|
+
# totals) for the given {concept => CodeStatisticsCalculator} hash.
|
|
46
|
+
def print_table(statistics)
|
|
47
|
+
code, tests, grand = calculator.totals_for(statistics)
|
|
48
|
+
|
|
49
|
+
print_header
|
|
50
|
+
statistics.keys.sort.each { |key| print_line(key, statistics[key]) }
|
|
51
|
+
print_splitter
|
|
52
|
+
|
|
53
|
+
print_line("Code", code)
|
|
54
|
+
print_line("Tests", tests)
|
|
55
|
+
print_line("Total", grand)
|
|
56
|
+
print_splitter
|
|
57
|
+
end
|
|
58
|
+
|
|
27
59
|
def print_header
|
|
28
60
|
print_splitter
|
|
29
61
|
puts "| Name | Files | Lines | LOC | Classes | Methods | M/C | LOC/M |"
|
|
@@ -17,6 +17,8 @@ module RailsStats
|
|
|
17
17
|
@result << stat_hash("Tests", @tests_total).merge(code_test_hash) if @tests_total
|
|
18
18
|
@result << stat_hash("Total", @grand_total).merge(code_test_hash) if @grand_total
|
|
19
19
|
|
|
20
|
+
@result << { "packs" => packs_breakdown } if calculator.packs?
|
|
21
|
+
|
|
20
22
|
@result << { "schema_stats" => schema_info }
|
|
21
23
|
@result << { "polymorphic_stats" => print_polymorphic_stats }
|
|
22
24
|
|
|
@@ -29,6 +31,22 @@ module RailsStats
|
|
|
29
31
|
|
|
30
32
|
private
|
|
31
33
|
|
|
34
|
+
# Per-pack / per-component breakdown, keyed by group name ("Core" plus
|
|
35
|
+
# each pack's relative path). Each group lists its concept stats followed
|
|
36
|
+
# by Code/Tests/Total rows for that group.
|
|
37
|
+
def packs_breakdown
|
|
38
|
+
@statistics_by_group.each_with_object({}) do |(group, group_statistics), out|
|
|
39
|
+
code, tests, grand = calculator.totals_for(group_statistics)
|
|
40
|
+
|
|
41
|
+
rows = group_statistics.map { |key, stats| stat_hash(key, stats) }
|
|
42
|
+
rows << stat_hash("Code", code).merge("total" => true)
|
|
43
|
+
rows << stat_hash("Tests", tests).merge("total" => true)
|
|
44
|
+
rows << stat_hash("Total", grand).merge("total" => true)
|
|
45
|
+
|
|
46
|
+
out[group] = rows
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
32
50
|
def code_test_hash
|
|
33
51
|
code = calculator.code_loc
|
|
34
52
|
tests = calculator.test_loc
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module RailsStats
|
|
2
|
+
# Detects "packs" (packwerk / packs-rails) and "components" (component-based
|
|
3
|
+
# Rails, à la Stephan Hagemann) inside a Rails application so that stats can
|
|
4
|
+
# be reported per pack/component plus a "Core" group for everything else.
|
|
5
|
+
#
|
|
6
|
+
# A directory is considered a pack when either:
|
|
7
|
+
#
|
|
8
|
+
# * it contains a `package.yml` file (the packwerk marker), or
|
|
9
|
+
# * it is a direct child of a `packs/` or `components/` directory and holds
|
|
10
|
+
# any of the usual code folders (`app`, `lib`, `spec`, `test`).
|
|
11
|
+
#
|
|
12
|
+
# Nested packs (e.g. `packs/a/packs/b`) are supported. The root directory
|
|
13
|
+
# itself is never reported as a pack.
|
|
14
|
+
module PackFinder
|
|
15
|
+
extend self
|
|
16
|
+
|
|
17
|
+
CODE_FOLDERS = %w[app lib spec test].freeze
|
|
18
|
+
PACK_CONTAINERS = %w[packs components].freeze
|
|
19
|
+
|
|
20
|
+
# Path regex used to filter glob results to skip vendored/generated
|
|
21
|
+
# directories. Built from the shared RailsStats::IGNORED_DIRS list.
|
|
22
|
+
IGNORED_PATH = %r{/(#{IGNORED_DIRS.map { |dir| Regexp.escape(dir) }.join("|")})/}.freeze
|
|
23
|
+
|
|
24
|
+
# Returns the absolute paths of every detected pack/component, sorted.
|
|
25
|
+
def find(root_directory)
|
|
26
|
+
root = File.absolute_path(root_directory)
|
|
27
|
+
packs = {}
|
|
28
|
+
|
|
29
|
+
collect_packwerk_packs(root, packs)
|
|
30
|
+
collect_convention_packs(root, packs)
|
|
31
|
+
|
|
32
|
+
packs.keys.sort
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def collect_packwerk_packs(root, packs)
|
|
38
|
+
Dir.glob(File.join(root, "**", "package.yml")).each do |marker_path|
|
|
39
|
+
next if marker_path =~ IGNORED_PATH
|
|
40
|
+
|
|
41
|
+
dir = File.absolute_path(File.dirname(marker_path))
|
|
42
|
+
next if dir == root
|
|
43
|
+
|
|
44
|
+
packs[dir] = true
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def collect_convention_packs(root, packs)
|
|
49
|
+
PACK_CONTAINERS.each do |container|
|
|
50
|
+
Dir.glob(File.join(root, "**", container, "*")).each do |path|
|
|
51
|
+
next if path =~ IGNORED_PATH
|
|
52
|
+
next unless File.directory?(path)
|
|
53
|
+
|
|
54
|
+
dir = File.absolute_path(path)
|
|
55
|
+
next if dir == root
|
|
56
|
+
next unless code_folder?(dir)
|
|
57
|
+
|
|
58
|
+
packs[dir] = true
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def code_folder?(dir)
|
|
64
|
+
CODE_FOLDERS.any? { |folder| File.directory?(File.join(dir, folder)) }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -8,12 +8,14 @@ module RailsStats
|
|
|
8
8
|
'assets']
|
|
9
9
|
|
|
10
10
|
def initialize(root_directory)
|
|
11
|
-
@root_directory = root_directory
|
|
11
|
+
@root_directory = File.absolute_path(root_directory)
|
|
12
12
|
@schema_path = File.join(@root_directory, "db", "schema.rb")
|
|
13
13
|
@structure_path = File.join(@root_directory, "db", "structure.sql")
|
|
14
|
+
@pack_roots = PackFinder.find(@root_directory)
|
|
14
15
|
@key_concepts = calculate_key_concepts
|
|
15
16
|
@projects = calculate_projects
|
|
16
17
|
@statistics = calculate_statistics
|
|
18
|
+
@statistics_by_group = calculate_statistics_by_group
|
|
17
19
|
@code_loc = calculate_code
|
|
18
20
|
@test_loc = calculate_tests
|
|
19
21
|
@schema = calculate_create_table_calls
|
|
@@ -21,7 +23,31 @@ module RailsStats
|
|
|
21
23
|
@files_total, @code_total, @tests_total, @grand_total = calculate_totals
|
|
22
24
|
end
|
|
23
25
|
|
|
24
|
-
attr_reader :code_loc, :code_total, :files_total, :grand_total, :statistics, :test_loc, :tests_total, :schema, :schema_path, :structure_path, :polymorphic
|
|
26
|
+
attr_reader :code_loc, :code_total, :files_total, :grand_total, :statistics, :test_loc, :tests_total, :schema, :schema_path, :structure_path, :polymorphic, :pack_roots, :statistics_by_group
|
|
27
|
+
|
|
28
|
+
CORE_GROUP = "Core".freeze
|
|
29
|
+
|
|
30
|
+
# Returns true when the application is split into packs/components, i.e.
|
|
31
|
+
# there is at least one group beyond the core application.
|
|
32
|
+
def packs?
|
|
33
|
+
@pack_roots.any?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Given a {concept => CodeStatisticsCalculator} hash (such as one of the
|
|
37
|
+
# values in +statistics_by_group+ or the flat +statistics+), returns the
|
|
38
|
+
# [code, tests, grand] totals for that group.
|
|
39
|
+
def totals_for(group_statistics)
|
|
40
|
+
code = CodeStatisticsCalculator.new
|
|
41
|
+
tests = CodeStatisticsCalculator.new
|
|
42
|
+
grand = CodeStatisticsCalculator.new
|
|
43
|
+
|
|
44
|
+
group_statistics.each_value do |stats|
|
|
45
|
+
grand.add(stats)
|
|
46
|
+
stats.test ? tests.add(stats) : code.add(stats)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
[code, tests, grand]
|
|
50
|
+
end
|
|
25
51
|
|
|
26
52
|
private
|
|
27
53
|
|
|
@@ -83,7 +109,23 @@ module RailsStats
|
|
|
83
109
|
end
|
|
84
110
|
|
|
85
111
|
def calculate_root_projects
|
|
86
|
-
[RootStatistics.new(@root_directory)]
|
|
112
|
+
projects = [RootStatistics.new(@root_directory)]
|
|
113
|
+
projects + calculate_pack_root_projects
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Packs that are not self-contained gems/engines (no gemspec) still have
|
|
117
|
+
# a `lib` (and sometimes `config`) directory that would otherwise be
|
|
118
|
+
# missed, since only the root RootStatistics scans the top-level lib.
|
|
119
|
+
# Gems are already covered by GemStatistics, so skip them here to avoid
|
|
120
|
+
# double-counting.
|
|
121
|
+
def calculate_pack_root_projects
|
|
122
|
+
@pack_roots.reject { |pack_root| gem_pack?(pack_root) }.collect do |pack_root|
|
|
123
|
+
RootStatistics.new(pack_root)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def gem_pack?(pack_root)
|
|
128
|
+
Dir[File.join(pack_root, "*.gemspec")].any?
|
|
87
129
|
end
|
|
88
130
|
|
|
89
131
|
def calculate_cucumber_projects
|
|
@@ -104,6 +146,62 @@ module RailsStats
|
|
|
104
146
|
out
|
|
105
147
|
end
|
|
106
148
|
|
|
149
|
+
# Same aggregation as +calculate_statistics+, but keeps each project's
|
|
150
|
+
# numbers grouped by the pack/component it belongs to (or "Core"). The
|
|
151
|
+
# returned hash is ordered with "Core" first followed by packs sorted by
|
|
152
|
+
# their relative path.
|
|
153
|
+
def calculate_statistics_by_group
|
|
154
|
+
grouped = {}
|
|
155
|
+
@projects.each do |project|
|
|
156
|
+
group = group_key_for(project.directory)
|
|
157
|
+
grouped[group] ||= {}
|
|
158
|
+
project.statistics.each do |key, stats|
|
|
159
|
+
grouped[group][key] ||= CodeStatisticsCalculator.new(project.test)
|
|
160
|
+
grouped[group][key].add(stats)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Drop empty concepts so a pack with, say, only models does not list a
|
|
165
|
+
# bunch of zero-line rows.
|
|
166
|
+
grouped.each_value do |group_statistics|
|
|
167
|
+
group_statistics.delete_if { |_key, stats| stats.lines == 0 }
|
|
168
|
+
end
|
|
169
|
+
grouped.delete_if { |_group, group_statistics| group_statistics.empty? }
|
|
170
|
+
|
|
171
|
+
sort_groups(grouped)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def sort_groups(grouped)
|
|
175
|
+
ordered = {}
|
|
176
|
+
ordered[CORE_GROUP] = grouped[CORE_GROUP] if grouped.key?(CORE_GROUP)
|
|
177
|
+
grouped.keys.reject { |key| key == CORE_GROUP }.sort.each do |key|
|
|
178
|
+
ordered[key] = grouped[key]
|
|
179
|
+
end
|
|
180
|
+
ordered
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Maps a project directory to its group: the relative path of the pack it
|
|
184
|
+
# lives in, or "Core" when it belongs to the main application.
|
|
185
|
+
def group_key_for(directory)
|
|
186
|
+
pack_root = pack_root_for(directory)
|
|
187
|
+
return CORE_GROUP unless pack_root
|
|
188
|
+
|
|
189
|
+
relative = pack_root.sub(/\A#{Regexp.escape(@root_directory)}\/?/, "")
|
|
190
|
+
relative.empty? ? CORE_GROUP : relative
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Returns the most specific (longest matching) pack root that contains the
|
|
194
|
+
# given directory, or nil when it is not part of any pack.
|
|
195
|
+
def pack_root_for(directory)
|
|
196
|
+
directory = File.absolute_path(directory.to_s)
|
|
197
|
+
best = nil
|
|
198
|
+
@pack_roots.each do |pack_root|
|
|
199
|
+
next unless directory == pack_root || directory.start_with?("#{pack_root}/")
|
|
200
|
+
best = pack_root if best.nil? || pack_root.length > best.length
|
|
201
|
+
end
|
|
202
|
+
best
|
|
203
|
+
end
|
|
204
|
+
|
|
107
205
|
def calculate_totals
|
|
108
206
|
files_total = @statistics.sum do |k,value|
|
|
109
207
|
value.files_total
|
|
@@ -3,6 +3,7 @@ module RailsStats
|
|
|
3
3
|
def initialize(calculator, opts = {})
|
|
4
4
|
@calculator = calculator
|
|
5
5
|
@statistics = calculator.statistics
|
|
6
|
+
@statistics_by_group = calculator.statistics_by_group
|
|
6
7
|
@code_total = calculator.code_total
|
|
7
8
|
@tests_total = calculator.tests_total
|
|
8
9
|
@grand_total = calculator.grand_total
|
data/lib/rails_stats/tasks.rb
CHANGED
|
@@ -3,8 +3,11 @@ task :stats, [:path, :format] do |t, args|
|
|
|
3
3
|
Rake::Task["stats"].clear # clear out normal one if there
|
|
4
4
|
require 'rails_stats/all'
|
|
5
5
|
|
|
6
|
+
# Respect an explicitly given path even when running inside a booted Rails
|
|
7
|
+
# app. Only fall back to Rails.root when no path was provided. This is what
|
|
8
|
+
# makes `rake stats[packs/pack1]` work from inside the app (see issue #23).
|
|
6
9
|
path = args[:path]
|
|
7
|
-
path
|
|
10
|
+
path ||= Rails.root.to_s if defined?(Rails)
|
|
8
11
|
fmt = args[:format] || ""
|
|
9
12
|
raise "no path given for stats" unless path
|
|
10
13
|
|
data/lib/rails_stats/util.rb
CHANGED
|
@@ -81,8 +81,16 @@ module RailsStats
|
|
|
81
81
|
Dir.foreach(directory) do |file_name|
|
|
82
82
|
path = "#{directory}/#{file_name}"
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
# Skip vendored / generated directories (e.g. a pack's
|
|
85
|
+
# app/webpack/node_modules). Pruning here avoids both the wasted walk
|
|
86
|
+
# and opening a directory that merely looks like a source file, such as
|
|
87
|
+
# node_modules/popper.js (which would raise Errno::EISDIR).
|
|
88
|
+
if File.directory?(path)
|
|
89
|
+
next if /^\./ =~ file_name
|
|
90
|
+
next if IGNORED_DIRS.include?(file_name)
|
|
91
|
+
|
|
85
92
|
stats.add(calculate_directory_statistics(path, pattern))
|
|
93
|
+
next
|
|
86
94
|
end
|
|
87
95
|
|
|
88
96
|
next unless file_name =~ pattern
|
data/lib/rails_stats/version.rb
CHANGED
data/rails_stats.gemspec
CHANGED
|
@@ -6,15 +6,16 @@ require 'rails_stats/version'
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "rails_stats"
|
|
8
8
|
spec.version = RailsStats::VERSION
|
|
9
|
-
spec.authors = ["Brian Leonard"]
|
|
10
|
-
spec.email = ["brian@bleonard.com"]
|
|
9
|
+
spec.authors = ["Brian Leonard", "Ernesto Tagwerker"]
|
|
10
|
+
spec.email = ["brian@bleonard.com", "ernesto@ombulabs.com"]
|
|
11
11
|
spec.summary = %q{Analyze a Rails project}
|
|
12
12
|
spec.description = %q{Point it to a directory and see stuff about the app}
|
|
13
13
|
spec.homepage = "https://github.com/fastruby/rails_stats"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
-
spec.
|
|
17
|
+
spec.bindir = "bin"
|
|
18
|
+
spec.executables = ["rails-stats"]
|
|
18
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
20
|
spec.require_paths = ["lib"]
|
|
20
21
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
enforce_dependencies: true
|
|
@@ -22,5 +22,27 @@ describe RailsStats::ConsoleFormatter do
|
|
|
22
22
|
|
|
23
23
|
assert_equal ['--format', 'text'], received_args
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
it 'prints a section per pack plus a Core and a grand total for packwerk apps' do
|
|
27
|
+
root_directory = File.absolute_path('./test/fixtures/packwerk_app')
|
|
28
|
+
calculator = RailsStats::StatsCalculator.new(root_directory)
|
|
29
|
+
formatter = RailsStats::ConsoleFormatter.new(calculator)
|
|
30
|
+
|
|
31
|
+
original = Bundler::Stats::CLI.method(:start)
|
|
32
|
+
Bundler::Stats::CLI.define_singleton_method(:start) { |args = []| nil }
|
|
33
|
+
|
|
34
|
+
begin
|
|
35
|
+
output, _ = capture_io { formatter.to_s }
|
|
36
|
+
ensure
|
|
37
|
+
Bundler::Stats::CLI.singleton_class.remove_method(:start)
|
|
38
|
+
Bundler::Stats::CLI.define_singleton_method(:start, original)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
assert_includes output, '== Core Application =='
|
|
42
|
+
assert_includes output, '== Pack: packs/pack1 =='
|
|
43
|
+
assert_includes output, '== Pack: packs/pack2 =='
|
|
44
|
+
assert_includes output, '== Pack: components/billing =='
|
|
45
|
+
assert_includes output, '== Total (all packs) =='
|
|
46
|
+
end
|
|
25
47
|
end
|
|
26
48
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
describe RailsStats::PackFinder do
|
|
6
|
+
describe ".find" do
|
|
7
|
+
it "detects packwerk packs and component-based components" do
|
|
8
|
+
root = File.absolute_path("./test/fixtures/packwerk_app")
|
|
9
|
+
|
|
10
|
+
packs = RailsStats::PackFinder.find(root).map { |path| path.sub("#{root}/", "") }
|
|
11
|
+
|
|
12
|
+
assert_equal ["components/billing", "packs/pack1", "packs/pack2"], packs.sort
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "does not treat the root package.yml as a pack" do
|
|
16
|
+
root = File.absolute_path("./test/fixtures/packwerk_app")
|
|
17
|
+
|
|
18
|
+
packs = RailsStats::PackFinder.find(root)
|
|
19
|
+
|
|
20
|
+
refute_includes packs, root
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "returns an empty list for a plain Rails app" do
|
|
24
|
+
root = File.absolute_path("./test/dummy")
|
|
25
|
+
|
|
26
|
+
assert_empty RailsStats::PackFinder.find(root)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
describe RailsStats::StatsCalculator do
|
|
6
|
+
describe "#statistics_by_group" do
|
|
7
|
+
before do
|
|
8
|
+
root = File.absolute_path("./test/fixtures/packwerk_app")
|
|
9
|
+
@calculator = RailsStats::StatsCalculator.new(root)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "reports that the app is split into packs" do
|
|
13
|
+
assert @calculator.packs?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "groups statistics per pack/component with Core first" do
|
|
17
|
+
groups = @calculator.statistics_by_group.keys
|
|
18
|
+
|
|
19
|
+
assert_equal "Core", groups.first
|
|
20
|
+
assert_equal ["Core", "components/billing", "packs/pack1", "packs/pack2"], groups
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "attributes each pack's files to its own group" do
|
|
24
|
+
by_group = @calculator.statistics_by_group
|
|
25
|
+
|
|
26
|
+
assert_equal 1, by_group["packs/pack1"]["Models"].files_total
|
|
27
|
+
assert_equal 1, by_group["packs/pack1"]["Controllers"].files_total
|
|
28
|
+
assert_equal 1, by_group["packs/pack1"]["Model Tests"].files_total
|
|
29
|
+
assert_equal 1, by_group["packs/pack2"]["Models"].files_total
|
|
30
|
+
assert_equal 1, by_group["components/billing"]["Models"].files_total
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "keeps core files in the Core group" do
|
|
34
|
+
core = @calculator.statistics_by_group["Core"]
|
|
35
|
+
|
|
36
|
+
assert_equal 1, core["Models"].files_total
|
|
37
|
+
assert_equal 1, core["Controllers"].files_total
|
|
38
|
+
assert_equal 1, core["Libraries"].files_total
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "includes pack lib directories that are not gems" do
|
|
42
|
+
assert_equal 1, @calculator.statistics_by_group["packs/pack1"]["Libraries"].files_total
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "has a grand total that matches the sum of every group" do
|
|
46
|
+
_code, _tests, grand = @calculator.totals_for(@calculator.statistics)
|
|
47
|
+
|
|
48
|
+
per_group_files = @calculator.statistics_by_group.sum do |_group, stats|
|
|
49
|
+
_c, _t, group_grand = @calculator.totals_for(stats)
|
|
50
|
+
group_grand.files_total
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
assert_equal grand.files_total, per_group_files
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe "#packs?" do
|
|
58
|
+
it "is false for a plain Rails app" do
|
|
59
|
+
calculator = RailsStats::StatsCalculator.new(File.absolute_path("./test/dummy"))
|
|
60
|
+
|
|
61
|
+
refute calculator.packs?
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
|
|
7
|
+
describe RailsStats::Util do
|
|
8
|
+
describe ".calculate_directory_statistics" do
|
|
9
|
+
it "ignores vendored directories and never counts a directory that looks like a source file" do
|
|
10
|
+
Dir.mktmpdir do |dir|
|
|
11
|
+
# A real source file that should be counted.
|
|
12
|
+
File.write(File.join(dir, "real.rb"), "class Real\nend\n")
|
|
13
|
+
|
|
14
|
+
# A directory whose name matches the source-file pattern. It must be
|
|
15
|
+
# walked (its contents counted) but never opened as a file itself,
|
|
16
|
+
# which previously raised Errno::EISDIR.
|
|
17
|
+
weird = File.join(dir, "weird.rb")
|
|
18
|
+
FileUtils.mkdir_p(weird)
|
|
19
|
+
File.write(File.join(weird, "inner.rb"), "class Inner\nend\n")
|
|
20
|
+
|
|
21
|
+
# A vendored tree that must be skipped entirely, including a directory
|
|
22
|
+
# named like a JS file (e.g. node_modules/popper.js), the exact case
|
|
23
|
+
# that crashed on a packs app.
|
|
24
|
+
popper = File.join(dir, "node_modules", "popper.js")
|
|
25
|
+
FileUtils.mkdir_p(popper)
|
|
26
|
+
File.write(File.join(popper, "index.js"), "function noop() {}\n")
|
|
27
|
+
|
|
28
|
+
stats = RailsStats::Util.calculate_directory_statistics(dir)
|
|
29
|
+
|
|
30
|
+
# real.rb + weird.rb/inner.rb, nothing under node_modules.
|
|
31
|
+
assert_equal 2, stats.files_total
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "skips every ignored directory name" do
|
|
36
|
+
RailsStats::IGNORED_DIRS.each do |ignored|
|
|
37
|
+
Dir.mktmpdir do |dir|
|
|
38
|
+
vendored = File.join(dir, ignored)
|
|
39
|
+
FileUtils.mkdir_p(vendored)
|
|
40
|
+
File.write(File.join(vendored, "ignored.rb"), "class Ignored\nend\n")
|
|
41
|
+
|
|
42
|
+
stats = RailsStats::Util.calculate_directory_statistics(dir)
|
|
43
|
+
|
|
44
|
+
assert_equal 0, stats.files_total, "expected #{ignored}/ to be skipped"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
metadata
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_stats
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brian Leonard
|
|
8
|
+
- Ernesto Tagwerker
|
|
9
|
+
autorequire:
|
|
8
10
|
bindir: bin
|
|
9
11
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
12
|
+
date: 2026-07-12 00:00:00.000000000 Z
|
|
11
13
|
dependencies:
|
|
12
14
|
- !ruby/object:Gem::Dependency
|
|
13
15
|
name: rake
|
|
@@ -40,7 +42,9 @@ dependencies:
|
|
|
40
42
|
description: Point it to a directory and see stuff about the app
|
|
41
43
|
email:
|
|
42
44
|
- brian@bleonard.com
|
|
43
|
-
|
|
45
|
+
- ernesto@ombulabs.com
|
|
46
|
+
executables:
|
|
47
|
+
- rails-stats
|
|
44
48
|
extensions: []
|
|
45
49
|
extra_rdoc_files: []
|
|
46
50
|
files:
|
|
@@ -52,6 +56,7 @@ files:
|
|
|
52
56
|
- LICENSE.txt
|
|
53
57
|
- README.md
|
|
54
58
|
- Rakefile
|
|
59
|
+
- bin/rails-stats
|
|
55
60
|
- codecov.yml
|
|
56
61
|
- lib/rails_stats.rb
|
|
57
62
|
- lib/rails_stats/all.rb
|
|
@@ -63,6 +68,7 @@ files:
|
|
|
63
68
|
- lib/rails_stats/gem_statistics.rb
|
|
64
69
|
- lib/rails_stats/inflector.rb
|
|
65
70
|
- lib/rails_stats/json_formatter.rb
|
|
71
|
+
- lib/rails_stats/pack_finder.rb
|
|
66
72
|
- lib/rails_stats/root_statistics.rb
|
|
67
73
|
- lib/rails_stats/spec_statistics.rb
|
|
68
74
|
- lib/rails_stats/stats_calculator.rb
|
|
@@ -137,14 +143,31 @@ files:
|
|
|
137
143
|
- test/dummy/test/models/user_test.rb
|
|
138
144
|
- test/dummy/test/support/test_helper.rb
|
|
139
145
|
- test/fixtures/console-output.txt
|
|
146
|
+
- test/fixtures/packwerk_app/app/controllers/core_controller.rb
|
|
147
|
+
- test/fixtures/packwerk_app/app/models/core_model.rb
|
|
148
|
+
- test/fixtures/packwerk_app/components/billing/app/models/billing_model.rb
|
|
149
|
+
- test/fixtures/packwerk_app/components/billing/lib/billing.rb
|
|
150
|
+
- test/fixtures/packwerk_app/lib/core_lib.rb
|
|
151
|
+
- test/fixtures/packwerk_app/package.yml
|
|
152
|
+
- test/fixtures/packwerk_app/packs/pack1/app/controllers/pack1_controller.rb
|
|
153
|
+
- test/fixtures/packwerk_app/packs/pack1/app/models/pack1_model.rb
|
|
154
|
+
- test/fixtures/packwerk_app/packs/pack1/lib/pack1_lib.rb
|
|
155
|
+
- test/fixtures/packwerk_app/packs/pack1/package.yml
|
|
156
|
+
- test/fixtures/packwerk_app/packs/pack1/spec/models/pack1_model_spec.rb
|
|
157
|
+
- test/fixtures/packwerk_app/packs/pack2/app/models/pack2_model.rb
|
|
158
|
+
- test/fixtures/packwerk_app/packs/pack2/test/models/pack2_model_test.rb
|
|
140
159
|
- test/lib/rails_stats/code_statistics_test.rb
|
|
141
160
|
- test/lib/rails_stats/console_formatter_test.rb
|
|
142
161
|
- test/lib/rails_stats/json_formatter_test.rb
|
|
162
|
+
- test/lib/rails_stats/pack_finder_test.rb
|
|
163
|
+
- test/lib/rails_stats/stats_calculator_test.rb
|
|
164
|
+
- test/lib/rails_stats/util_test.rb
|
|
143
165
|
- test/test_helper.rb
|
|
144
166
|
homepage: https://github.com/fastruby/rails_stats
|
|
145
167
|
licenses:
|
|
146
168
|
- MIT
|
|
147
169
|
metadata: {}
|
|
170
|
+
post_install_message:
|
|
148
171
|
rdoc_options: []
|
|
149
172
|
require_paths:
|
|
150
173
|
- lib
|
|
@@ -159,7 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
159
182
|
- !ruby/object:Gem::Version
|
|
160
183
|
version: '0'
|
|
161
184
|
requirements: []
|
|
162
|
-
rubygems_version: 3.
|
|
185
|
+
rubygems_version: 3.0.3.1
|
|
186
|
+
signing_key:
|
|
163
187
|
specification_version: 4
|
|
164
188
|
summary: Analyze a Rails project
|
|
165
189
|
test_files:
|
|
@@ -227,7 +251,23 @@ test_files:
|
|
|
227
251
|
- test/dummy/test/models/user_test.rb
|
|
228
252
|
- test/dummy/test/support/test_helper.rb
|
|
229
253
|
- test/fixtures/console-output.txt
|
|
254
|
+
- test/fixtures/packwerk_app/app/controllers/core_controller.rb
|
|
255
|
+
- test/fixtures/packwerk_app/app/models/core_model.rb
|
|
256
|
+
- test/fixtures/packwerk_app/components/billing/app/models/billing_model.rb
|
|
257
|
+
- test/fixtures/packwerk_app/components/billing/lib/billing.rb
|
|
258
|
+
- test/fixtures/packwerk_app/lib/core_lib.rb
|
|
259
|
+
- test/fixtures/packwerk_app/package.yml
|
|
260
|
+
- test/fixtures/packwerk_app/packs/pack1/app/controllers/pack1_controller.rb
|
|
261
|
+
- test/fixtures/packwerk_app/packs/pack1/app/models/pack1_model.rb
|
|
262
|
+
- test/fixtures/packwerk_app/packs/pack1/lib/pack1_lib.rb
|
|
263
|
+
- test/fixtures/packwerk_app/packs/pack1/package.yml
|
|
264
|
+
- test/fixtures/packwerk_app/packs/pack1/spec/models/pack1_model_spec.rb
|
|
265
|
+
- test/fixtures/packwerk_app/packs/pack2/app/models/pack2_model.rb
|
|
266
|
+
- test/fixtures/packwerk_app/packs/pack2/test/models/pack2_model_test.rb
|
|
230
267
|
- test/lib/rails_stats/code_statistics_test.rb
|
|
231
268
|
- test/lib/rails_stats/console_formatter_test.rb
|
|
232
269
|
- test/lib/rails_stats/json_formatter_test.rb
|
|
270
|
+
- test/lib/rails_stats/pack_finder_test.rb
|
|
271
|
+
- test/lib/rails_stats/stats_calculator_test.rb
|
|
272
|
+
- test/lib/rails_stats/util_test.rb
|
|
233
273
|
- test/test_helper.rb
|