modelscope 0.1.0 → 0.1.1
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/lib/modelscope/analyzers/callback_analyzer.rb +1 -10
- data/lib/modelscope/callback.rb +19 -1
- data/lib/modelscope/collector.rb +20 -2
- data/lib/modelscope/reports/base.rb +2 -2
- data/lib/modelscope/runner.rb +6 -4
- data/lib/modelscope/stats.rb +18 -2
- data/lib/modelscope/version.rb +1 -1
- data/lib/modelscope.rb +10 -0
- data/lib/tasks/modelscope.rake +54 -21
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e40c1dcb806b8b59a48b18a239a7160b6c816e61a173896bc1f5b233395d884
|
4
|
+
data.tar.gz: 3cb1b59b808eaa01eba216b5e53c4b7286a8aa145fdca08697835a8716c20621
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37802c37e0d1cb44f696eaea22c8531f1433e543a15ae23a5a3e283c0bb31f5bb26b948f3558d25a37aa64a81ca9ebcb1129b18aec9a4147b04500e62812b12f
|
7
|
+
data.tar.gz: a1c81b68ae3d3b3dfe8ff9108216ce5ec554de75724d061b8d99d1f6b1af87956f04328bf020eb3a0a71723c82ee32e89853667b60865673a9b6311d4feca8f5
|
@@ -34,16 +34,7 @@ module ModelScope
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def inherited?
|
37
|
-
|
38
|
-
return false unless owner
|
39
|
-
|
40
|
-
if validator?(@filter)
|
41
|
-
@model != @defining_class
|
42
|
-
else
|
43
|
-
owner != @model &&
|
44
|
-
!rails_module?(owner) &&
|
45
|
-
owner != @defining_class
|
46
|
-
end
|
37
|
+
@model != @defining_class
|
47
38
|
end
|
48
39
|
|
49
40
|
def conditional?
|
data/lib/modelscope/callback.rb
CHANGED
@@ -3,7 +3,8 @@
|
|
3
3
|
module ModelScope
|
4
4
|
class Callback
|
5
5
|
attr_reader :model, :method_name, :conditional, :origin, :inherited, :kind,
|
6
|
-
:association_generated, :attribute_generated
|
6
|
+
:association_generated, :attribute_generated, :callback, :defining_class,
|
7
|
+
:fingerprint
|
7
8
|
|
8
9
|
def initialize(model:, rails_callback:, name:, defining_class:)
|
9
10
|
@model = model
|
@@ -20,6 +21,11 @@ module ModelScope
|
|
20
21
|
@inherited = analyzer.inherited?
|
21
22
|
@association_generated = analyzer.association_generated?
|
22
23
|
@attribute_generated = analyzer.attribute_generated?
|
24
|
+
# fingerprint allows us to de-duplicate callbacks/validations;
|
25
|
+
# in most cases, it's just an object_id, but for named validations/callbacks,
|
26
|
+
# it's a combination of the name, kind and the method_name.
|
27
|
+
# The "0" and "1" prefixes define how to handle duplicates (1 means last write wins, 0 means first write wins)
|
28
|
+
@fingerprint = (@method_name.is_a?(Symbol) && @origin != :rails) ? ["1", @name, @kind, @method_name].join("-") : "0-#{@callback.object_id}"
|
23
29
|
end
|
24
30
|
|
25
31
|
def callback_group
|
@@ -34,5 +40,17 @@ module ModelScope
|
|
34
40
|
def human_method_name
|
35
41
|
Analyzers::ValidationAnalyzer.human_method_name(@callback.filter)
|
36
42
|
end
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
[
|
46
|
+
"#{model.name}: #{human_method_name}",
|
47
|
+
"kind=#{kind}_#{callback_group}",
|
48
|
+
"origin=#{origin}",
|
49
|
+
inherited ? "inherited=true" : nil,
|
50
|
+
conditional ? "conditional=true" : nil,
|
51
|
+
association_generated ? "association=true" : nil,
|
52
|
+
attribute_generated ? "attribute=true" : nil
|
53
|
+
].compact.join(" ")
|
54
|
+
end
|
37
55
|
end
|
38
56
|
end
|
data/lib/modelscope/collector.rb
CHANGED
@@ -14,8 +14,8 @@ module ModelScope
|
|
14
14
|
@models = Set.new(models ? [*models] : ApplicationRecord.descendants)
|
15
15
|
end
|
16
16
|
|
17
|
-
def collect
|
18
|
-
|
17
|
+
def collect(select_models = models)
|
18
|
+
select_models.flat_map { |model| collect_for_model(model) }
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
@@ -27,7 +27,25 @@ module ModelScope
|
|
27
27
|
|
28
28
|
def collect_for_model(model)
|
29
29
|
model.ancestors.select { |ancestor| ancestor < ActiveRecord::Base }
|
30
|
+
# collect from parent to child to correctly handle inheritance
|
31
|
+
.reverse
|
30
32
|
.flat_map { |ancestor| collect_callbacks_for_class(model, ancestor) }
|
33
|
+
.group_by(&:fingerprint)
|
34
|
+
# merge groups
|
35
|
+
.transform_values do |callbacks|
|
36
|
+
probe = callbacks.first
|
37
|
+
if probe.fingerprint.start_with?("1")
|
38
|
+
# we must keep the last non-matching callback (i.e., if all callbacks are the same,
|
39
|
+
# we must keep the first one)
|
40
|
+
callbacks.each do |clbk|
|
41
|
+
if clbk.callback != probe.callback
|
42
|
+
probe = clbk
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
probe
|
47
|
+
end
|
48
|
+
.values
|
31
49
|
end
|
32
50
|
|
33
51
|
def collect_callbacks_for_class(model, klass)
|
data/lib/modelscope/runner.rb
CHANGED
@@ -4,15 +4,17 @@ module ModelScope
|
|
4
4
|
class Runner
|
5
5
|
DEFAULT_FORMAT = :table
|
6
6
|
|
7
|
-
def self.run(format: DEFAULT_FORMAT, model: nil, paths: nil, kind: :callbacks)
|
8
|
-
new(format: format, model: model, paths: paths, kind: kind).run
|
7
|
+
def self.run(format: DEFAULT_FORMAT, model: nil, paths: nil, kind: :callbacks, **opts)
|
8
|
+
new(format: format, model: model, paths: paths, kind: kind, **opts).run
|
9
9
|
end
|
10
10
|
|
11
|
-
def initialize(format:, model:, paths:, kind: :callbacks)
|
11
|
+
def initialize(format:, model:, paths:, kind: :callbacks, sort_by: :size, sort_order: :desc)
|
12
12
|
@format = (format || DEFAULT_FORMAT).to_sym
|
13
13
|
@model_name = model
|
14
14
|
@paths = paths
|
15
15
|
@kind = kind
|
16
|
+
@sort_by = sort_by
|
17
|
+
@sort_order = sort_order
|
16
18
|
end
|
17
19
|
|
18
20
|
def run
|
@@ -32,7 +34,7 @@ module ModelScope
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def generate_report(callbacks, ckind)
|
35
|
-
find_reporter_class(ckind).new(callbacks).generate
|
37
|
+
find_reporter_class(ckind).new(callbacks, sort_by: @sort_by, sort_order: @sort_order).generate
|
36
38
|
end
|
37
39
|
|
38
40
|
def find_reporter_class(ckind)
|
data/lib/modelscope/stats.rb
CHANGED
@@ -7,15 +7,31 @@ module ModelScope
|
|
7
7
|
association_generated attribute_generated
|
8
8
|
].freeze
|
9
9
|
|
10
|
+
SORT = %i[size name].freeze
|
11
|
+
SORT_ORDER = %i[desc asc].freeze
|
12
|
+
|
10
13
|
attr_reader :callbacks
|
14
|
+
private attr_reader :sort_by, :sort_order
|
11
15
|
|
12
|
-
def initialize(callbacks)
|
16
|
+
def initialize(callbacks, sort_by: :size, sort_order: :desc)
|
13
17
|
@callbacks = callbacks
|
14
18
|
@stats_cache = {}
|
19
|
+
@sort_by = sort_by
|
20
|
+
raise ArgumentError, "Invalid sort_by: #{@sort_by}. Available: #{SORT.join(", ")}" unless SORT.include?(@sort_by)
|
21
|
+
@sort_order = sort_order
|
22
|
+
raise ArgumentError, "Invalid sort_order: #{@sort_order}. Available: #{SORT_ORDER.join(", ")}" unless SORT_ORDER.include?(@sort_order)
|
15
23
|
end
|
16
24
|
|
17
25
|
def by_model
|
18
|
-
@by_model ||= callbacks.group_by { |cb| cb.model.name }
|
26
|
+
@by_model ||= callbacks.group_by { |cb| cb.model.name }.sort_by do |name, callbacks|
|
27
|
+
if sort_by == :size
|
28
|
+
callbacks.size
|
29
|
+
elsif sort_by == :name
|
30
|
+
name
|
31
|
+
end
|
32
|
+
end.tap do |sorted|
|
33
|
+
sorted.reverse! if sort_order == :desc
|
34
|
+
end.to_h
|
19
35
|
end
|
20
36
|
|
21
37
|
def stats_for(model_name)
|
data/lib/modelscope/version.rb
CHANGED
data/lib/modelscope.rb
CHANGED
@@ -12,6 +12,16 @@ module ModelScope
|
|
12
12
|
loader.setup
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
def self.collect_callbacks(*models)
|
17
|
+
collector = Collector.new
|
18
|
+
collector.collect(models)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.collect_validations(*models)
|
22
|
+
collector = Collector.new(kind: :validations)
|
23
|
+
collector.collect(models)
|
24
|
+
end
|
15
25
|
end
|
16
26
|
|
17
27
|
ModelScope.loader
|
data/lib/tasks/modelscope.rake
CHANGED
@@ -13,6 +13,7 @@ namespace :modelscope do
|
|
13
13
|
specified as constant
|
14
14
|
name (MessageThread) or file path
|
15
15
|
(message_thread, admin/message_thread)
|
16
|
+
sort=total|name Sort by score or name (default: score:desc)
|
16
17
|
path=DIR1,DIR2 Additional model directories (comma-separated)
|
17
18
|
|
18
19
|
Examples:
|
@@ -20,14 +21,24 @@ namespace :modelscope do
|
|
20
21
|
rake modelscope:callbacks
|
21
22
|
DESC
|
22
23
|
task callbacks: :environment do
|
23
|
-
|
24
|
-
|
25
|
-
puts ModelScope::Runner.run(
|
24
|
+
opts = {
|
25
|
+
kind: :callbacks,
|
26
26
|
format: ENV["format"],
|
27
|
-
model: ENV["model"]
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
model: ENV["model"]
|
28
|
+
}.compact
|
29
|
+
|
30
|
+
if ENV["path"]
|
31
|
+
opts[:paths] = ENV["path"]&.split(",")&.map { |p| Rails.root.join(p) }
|
32
|
+
end
|
33
|
+
|
34
|
+
if ENV["sort"]
|
35
|
+
sort_by, sort_order = ENV["sort"].split(":")
|
36
|
+
opts[:sort_by] = sort_by.to_sym
|
37
|
+
sort_order ||= ((sort_by == "size") ? :desc : :asc)
|
38
|
+
opts[:sort_order] = sort_order.to_sym
|
39
|
+
end
|
40
|
+
|
41
|
+
puts ModelScope::Runner.run(**opts)
|
31
42
|
end
|
32
43
|
|
33
44
|
desc <<~DESC
|
@@ -39,6 +50,7 @@ namespace :modelscope do
|
|
39
50
|
specified as constant
|
40
51
|
name (MessageThread) or file path
|
41
52
|
(message_thread, admin/message_thread)
|
53
|
+
sort=total|name Sort by score or name (default: score:desc)
|
42
54
|
path=DIR1,DIR2 Additional model directories (comma-separated)
|
43
55
|
|
44
56
|
Examples:
|
@@ -46,14 +58,24 @@ namespace :modelscope do
|
|
46
58
|
rake modelscope:validations
|
47
59
|
DESC
|
48
60
|
task validations: :environment do
|
49
|
-
|
50
|
-
|
51
|
-
puts ModelScope::Runner.run(
|
61
|
+
opts = {
|
62
|
+
kind: :validations,
|
52
63
|
format: ENV["format"],
|
53
|
-
model: ENV["model"]
|
54
|
-
|
55
|
-
|
56
|
-
|
64
|
+
model: ENV["model"]
|
65
|
+
}.compact
|
66
|
+
|
67
|
+
if ENV["path"]
|
68
|
+
opts[:paths] = ENV["path"]&.split(",")&.map { |p| Rails.root.join(p) }
|
69
|
+
end
|
70
|
+
|
71
|
+
if ENV["sort"]
|
72
|
+
sort_by, sort_order = ENV["sort"].split(":")
|
73
|
+
opts[:sort_by] = sort_by.to_sym
|
74
|
+
sort_order ||= ((sort_by == "size") ? :desc : :asc)
|
75
|
+
opts[:sort_order] = sort_order.to_sym
|
76
|
+
end
|
77
|
+
|
78
|
+
puts ModelScope::Runner.run(**opts)
|
57
79
|
end
|
58
80
|
|
59
81
|
desc <<~DESC
|
@@ -65,16 +87,27 @@ namespace :modelscope do
|
|
65
87
|
specified as constant
|
66
88
|
name (MessageThread) or file path
|
67
89
|
(message_thread, admin/message_thread)
|
90
|
+
sort=total|name Sort by score or name (default: score:desc)
|
68
91
|
path=DIR1,DIR2 Additional model directories (comma-separated)
|
69
92
|
DESC
|
70
93
|
task report: :environment do
|
71
|
-
|
72
|
-
|
73
|
-
puts ModelScope::Runner.run(
|
94
|
+
opts = {
|
95
|
+
kind: :report,
|
74
96
|
format: ENV["format"],
|
75
|
-
model: ENV["model"]
|
76
|
-
|
77
|
-
|
78
|
-
|
97
|
+
model: ENV["model"]
|
98
|
+
}.compact
|
99
|
+
|
100
|
+
if ENV["path"]
|
101
|
+
opts[:paths] = ENV["path"]&.split(",")&.map { |p| Rails.root.join(p) }
|
102
|
+
end
|
103
|
+
|
104
|
+
if ENV["sort"]
|
105
|
+
sort_by, sort_order = ENV["sort"].split(":")
|
106
|
+
opts[:sort_by] = sort_by.to_sym
|
107
|
+
sort_order ||= ((sort_by == "size") ? :desc : :asc)
|
108
|
+
opts[:sort_order] = sort_order.to_sym
|
109
|
+
end
|
110
|
+
|
111
|
+
puts ModelScope::Runner.run(**opts)
|
79
112
|
end
|
80
113
|
end
|