deprecation_collector 0.5.2 → 0.7.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 +9 -0
- data/README.md +10 -0
- data/deprecation_collector.gemspec +1 -10
- data/lib/deprecation_collector/collectors.rb +32 -6
- data/lib/deprecation_collector/storage/active_record.rb +155 -0
- data/lib/deprecation_collector/storage.rb +6 -1
- data/lib/deprecation_collector/version.rb +1 -1
- data/lib/deprecation_collector/web/application.rb +6 -5
- data/lib/deprecation_collector/web/helpers.rb +18 -11
- data/lib/deprecation_collector/web/router.rb +9 -5
- data/lib/deprecation_collector/web/views/import.html.slim +12 -0
- data/lib/deprecation_collector/web/views/import.html.template.rb +1 -1
- data/lib/deprecation_collector/web/views/index.html.slim +121 -0
- data/lib/deprecation_collector/web/views/index.html.template.rb +6 -6
- data/lib/deprecation_collector/web/views/layout.html.slim +90 -0
- data/lib/deprecation_collector/web/views/layout.html.template.rb +1 -1
- data/lib/deprecation_collector/web/views/show.html.slim +81 -0
- data/lib/deprecation_collector/web/views/show.html.template.rb +2 -2
- data/lib/deprecation_collector.rb +13 -3
- metadata +7 -43
- data/.rspec +0 -3
- data/.rubocop.yml +0 -34
- data/Appraisals +0 -13
- data/Gemfile +0 -33
- data/Gemfile.lock +0 -249
- data/LICENSE +0 -21
- data/Rakefile +0 -30
- data/gemfiles/rails_6.gemfile +0 -15
- data/gemfiles/rails_6.gemfile.lock +0 -198
- data/gemfiles/rails_7.gemfile +0 -15
- data/gemfiles/rails_7.gemfile.lock +0 -197
- data/gemfiles/rails_none.gemfile +0 -14
- data/gemfiles/rails_none.gemfile.lock +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26bc69b0016762d0f5e8546f48177a7b2d90334bc8f4c995853c51e814386731
|
4
|
+
data.tar.gz: d059f4d6985f9136305160d0e0a6ffe184a6ac1a927e31959241e525974d78ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a4609b79edbf7f54aa11538a7201595951ced8194d2a65fd01f4ef9be21cc75719fb27c1e0debbfcad5be2fc5407a9e8a04a6b398e7af2bc19c196461017437
|
7
|
+
data.tar.gz: 70f742f7dbd0525ee444c5aa076ccd241f1b8b5acd7c20a10b8778e838a40b3ba383dffd2b58b8776da6bc978583775f16104e89db5d1f1746bfe03e6e1ef8a3
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
== 0.7.0
|
2
|
+
- support for Rails 7.1
|
3
|
+
- make install critical section smaller to prevent installation deprecations preventing installation
|
4
|
+
|
5
|
+
== 0.6.0
|
6
|
+
- added active_record storage
|
7
|
+
- redis dependency will become optional in v1.0
|
8
|
+
- more test coverage
|
9
|
+
|
1
10
|
== 0.5.0
|
2
11
|
- more work on ui
|
3
12
|
- refactored to separate deprecations storage from other logic
|
data/README.md
CHANGED
@@ -55,6 +55,16 @@ Rails.application.routes.draw do
|
|
55
55
|
end
|
56
56
|
```
|
57
57
|
|
58
|
+
usually it's a good idea to secure the ui in some way, you can use rails route constraint (actual check will depend on your app):
|
59
|
+
```ruby
|
60
|
+
Rails.application.routes.draw do
|
61
|
+
constraints(->(request) { request.session[:admin] }) do
|
62
|
+
require 'deprecation_collector/web'
|
63
|
+
mount DeprecationCollector::Web => '/deprecations', as: :deprecations
|
64
|
+
end
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
58
68
|
## Development
|
59
69
|
|
60
70
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -18,17 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.metadata["source_code_uri"] = "https://github.com/Vasfed/deprecation_collector"
|
19
19
|
spec.metadata["changelog_uri"] = "https://github.com/Vasfed/deprecation_collector/blob/main/CHANGELOG.md"
|
20
20
|
|
21
|
-
|
22
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)}) ||
|
26
|
-
f.match(%r{\Alib/deprecation_collector/web/views/.+\.slim\z})
|
27
|
-
end
|
28
|
-
end + Dir["lib/deprecation_collector/web/views/*.slim"].map { |template| template.sub(/\.slim\z/, ".template.rb") }
|
21
|
+
spec.files = Dir["lib/**/*", "sig/**/*", "*.md", "*.txt", "*.gemspec"].select { |filename| File.file?(filename) }
|
29
22
|
spec.require_paths = ["lib"]
|
30
23
|
|
31
24
|
spec.add_dependency "redis", ">= 3.0"
|
32
|
-
spec.add_development_dependency "appraisal"
|
33
|
-
spec.add_development_dependency "rack-test"
|
34
25
|
end
|
@@ -2,6 +2,27 @@
|
|
2
2
|
|
3
3
|
# :nodoc:
|
4
4
|
class DeprecationCollector
|
5
|
+
ACTIVE_SUPPORT_BEHAVIORS = {
|
6
|
+
rails71: ->(message, callstack, deprecator) do
|
7
|
+
# TODO: use deprecator.gem_name, deprecator.deprecation_horizon
|
8
|
+
DeprecationCollector.collect(message, callstack, :rails)
|
9
|
+
ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[stock_activesupport_behavior].call(message, callstack, deprecator)
|
10
|
+
end,
|
11
|
+
legacy: ->(message, callstack, deprecation_horizon, gem_name) do
|
12
|
+
DeprecationCollector.collect(message, callstack, :rails)
|
13
|
+
ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[stock_activesupport_behavior].call(
|
14
|
+
message, callstack, deprecation_horizon, gem_name
|
15
|
+
)
|
16
|
+
end
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
# for intercepting deprecations from deprecators not installed in Rails.application.deprecators
|
20
|
+
module ActiveSupportDeprecationCollectionPatch
|
21
|
+
def behavior
|
22
|
+
@behavior ||= [DeprecationCollector::ACTIVE_SUPPORT_BEHAVIORS[:rails71]]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
5
26
|
class << self
|
6
27
|
protected
|
7
28
|
|
@@ -18,12 +39,17 @@ class DeprecationCollector
|
|
18
39
|
|
19
40
|
def tap_activesupport
|
20
41
|
# TODO: a more polite hook
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
42
|
+
# not polite to turn off all other possible behaviors, but otherwise may get duplicate calls
|
43
|
+
if Rails.respond_to?(:gem_version) && Rails.gem_version >= "7.1"
|
44
|
+
Rails.application.deprecators.behavior = ACTIVE_SUPPORT_BEHAVIORS[:rails71] if Rails.application&.deprecators
|
45
|
+
# Rails.application.deprecators.behavior only captures new-style deprecations, but we need all:
|
46
|
+
if ActiveSupport::Deprecation.respond_to?(:_instance)
|
47
|
+
ActiveSupport::Deprecation._instance.behavior = ACTIVE_SUPPORT_BEHAVIORS[:rails71]
|
48
|
+
end
|
49
|
+
# collect deprecations from deprecators that are not installed in `Rails.application.deprecators`
|
50
|
+
ActiveSupport::Deprecation.prepend(ActiveSupportDeprecationCollectionPatch)
|
51
|
+
else
|
52
|
+
ActiveSupport::Deprecation.behavior = ACTIVE_SUPPORT_BEHAVIORS[:legacy]
|
27
53
|
end
|
28
54
|
end
|
29
55
|
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class DeprecationCollector
|
4
|
+
module Storage
|
5
|
+
# NB: this will not work in tests because of transactions, and may be affected by transactions of the app
|
6
|
+
# TODO: use separate db connection to mitigate this
|
7
|
+
class ActiveRecord < DeprecationCollector::Storage::Base
|
8
|
+
def initialize(model: nil, mutex: nil, count: false, write_interval: 900, write_interval_jitter: 60,
|
9
|
+
key_prefix: nil)
|
10
|
+
super
|
11
|
+
raise "key prefix not supported in AR" if key_prefix && key_prefix != "deprecations"
|
12
|
+
|
13
|
+
self.model = model if model
|
14
|
+
@last_write_time = current_time
|
15
|
+
@count = count
|
16
|
+
@write_interval = write_interval
|
17
|
+
@write_interval_jitter = write_interval_jitter
|
18
|
+
# on cruby hash itself is threadsafe, but we need to prevent races
|
19
|
+
@deprecations_mutex = mutex || Mutex.new
|
20
|
+
@deprecations = {}
|
21
|
+
@known_digests = Set.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def model=(model)
|
25
|
+
expected_class_methods = %i[column_names where pluck delete_all upsert_all find_in_batches find_by]
|
26
|
+
unless expected_class_methods.all? { |method_name| model.respond_to?(method_name) }
|
27
|
+
raise ArgumentError, "model expected to be a AR-like class responding to #{expected_class_methods.join(', ')}"
|
28
|
+
end
|
29
|
+
|
30
|
+
expected_fields = %w[digest data notes created_at updated_at]
|
31
|
+
unless expected_fields.all? { |column_name| model.column_names.include?(column_name) }
|
32
|
+
raise ArgumentError, "model expected to be a AR-like class with fields #{expected_fields.join(', ')}"
|
33
|
+
end
|
34
|
+
|
35
|
+
@model = model
|
36
|
+
end
|
37
|
+
|
38
|
+
def model
|
39
|
+
@model ||= ::Deprecation
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_writer :key_prefix
|
43
|
+
|
44
|
+
def unsent_deprecations
|
45
|
+
@deprecations
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete(remove_digests)
|
49
|
+
model.where(digest: remove_digests).delete_all
|
50
|
+
end
|
51
|
+
|
52
|
+
def clear(enable: false) # rubocop:disable Lint/UnusedMethodArgument
|
53
|
+
model.delete_all
|
54
|
+
@known_digests.clear
|
55
|
+
@deprecations.clear
|
56
|
+
end
|
57
|
+
|
58
|
+
def fetch_known_digests
|
59
|
+
@known_digests.merge(model.pluck(:digest))
|
60
|
+
end
|
61
|
+
|
62
|
+
def store(deprecation)
|
63
|
+
fresh = !@deprecations.key?(deprecation.digest)
|
64
|
+
@deprecations_mutex.synchronize do
|
65
|
+
(@deprecations[deprecation.digest] ||= deprecation).touch
|
66
|
+
end
|
67
|
+
|
68
|
+
flush if current_time - @last_write_time > (@write_interval + rand(@write_interval_jitter))
|
69
|
+
fresh
|
70
|
+
end
|
71
|
+
|
72
|
+
def flush(force: false)
|
73
|
+
return unless force || (current_time > @last_write_time + @write_interval)
|
74
|
+
|
75
|
+
deprecations_to_flush = nil
|
76
|
+
@deprecations_mutex.synchronize do
|
77
|
+
deprecations_to_flush = @deprecations
|
78
|
+
@deprecations = {}
|
79
|
+
@last_write_time = current_time
|
80
|
+
# checking in this section to prevent multiple parallel check requests
|
81
|
+
return DeprecationCollector.instance.instance_variable_set(:@enabled, false) unless enabled?
|
82
|
+
end
|
83
|
+
|
84
|
+
# write_count_to_redis(deprecations_to_flush) if @count
|
85
|
+
|
86
|
+
# make as few writes as possible, other workers may already have reported our warning
|
87
|
+
fetch_known_digests
|
88
|
+
deprecations_to_flush.reject! { |digest, _val| @known_digests.include?(digest) }
|
89
|
+
return unless deprecations_to_flush.any?
|
90
|
+
|
91
|
+
@known_digests.merge(deprecations_to_flush.keys)
|
92
|
+
|
93
|
+
model.upsert_all(
|
94
|
+
deprecations_to_flush.map do |key, deprecation|
|
95
|
+
{
|
96
|
+
digest: key, data: deprecation.as_json,
|
97
|
+
created_at: timestamp_to_time(deprecation.first_timestamp),
|
98
|
+
updated_at: timestamp_to_time(deprecation.first_timestamp)
|
99
|
+
}
|
100
|
+
end,
|
101
|
+
unique_by: :digest # , update_only: %i[data updated_at] # rails 7
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
def read_each
|
106
|
+
model.find_in_batches do |batch| # this is find_each, but do not require it to be implemented
|
107
|
+
batch.each do |record|
|
108
|
+
yield(record.digest, record.data.to_json, record.data&.dig("count"), record.notes)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def read_one(digest)
|
114
|
+
return [nil] * 4 unless (record = model.find_by(digest: digest))
|
115
|
+
|
116
|
+
[record.digest, record.data.to_json, record.data&.dig("count"), record.notes]
|
117
|
+
end
|
118
|
+
|
119
|
+
def import(dump_hash)
|
120
|
+
attrs = dump_hash.map do |key, deprecation|
|
121
|
+
time = deprecation["first_timestamp"] || deprecation[:first_timestamp]
|
122
|
+
time = time&.yield_self { |tme| timestamp_to_time(tme) } || current_time
|
123
|
+
{ digest: key, data: deprecation, created_at: time, updated_at: time }
|
124
|
+
end
|
125
|
+
model.upsert_all(attrs, unique_by: :digest) # , update_only: %i[data updated_at])
|
126
|
+
end
|
127
|
+
|
128
|
+
def cleanup(&_block)
|
129
|
+
removed = total = 0
|
130
|
+
|
131
|
+
model.find_in_batches do |batch|
|
132
|
+
total += batch.size
|
133
|
+
removed += delete(
|
134
|
+
batch.select { |record| yield(record.data.deep_symbolize_keys) }.map(&:digest)
|
135
|
+
)
|
136
|
+
end
|
137
|
+
"#{removed} removed, #{total - removed} left"
|
138
|
+
end
|
139
|
+
|
140
|
+
protected
|
141
|
+
|
142
|
+
def current_time
|
143
|
+
return Time.zone.now if Time.respond_to?(:zone) && Time.zone
|
144
|
+
|
145
|
+
Time.now
|
146
|
+
end
|
147
|
+
|
148
|
+
def timestamp_to_time(timestamp)
|
149
|
+
return Time.zone.at(timestamp) if Time.respond_to?(:zone) && Time.zone
|
150
|
+
|
151
|
+
Time.at(timestamp)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -21,6 +21,11 @@ class DeprecationCollector
|
|
21
21
|
def flush(**); end
|
22
22
|
|
23
23
|
def store(_deprecation); raise("Not implemented"); end
|
24
|
+
|
25
|
+
def read_each; end
|
26
|
+
def read_one(_digest); [nil] * 4 end
|
27
|
+
|
28
|
+
def import(_dump); end
|
24
29
|
# rubocop:enable Style/SingleLineMethods
|
25
30
|
end
|
26
31
|
|
@@ -36,7 +41,7 @@ class DeprecationCollector
|
|
36
41
|
attr_accessor :write_interval, :write_interval_jitter, :redis, :count
|
37
42
|
|
38
43
|
def initialize(redis: nil, mutex: nil, count: false, write_interval: 900, write_interval_jitter: 60,
|
39
|
-
|
44
|
+
key_prefix: nil)
|
40
45
|
super
|
41
46
|
@key_prefix = key_prefix || "deprecations"
|
42
47
|
@redis = redis
|
@@ -24,17 +24,17 @@ class DeprecationCollector
|
|
24
24
|
|
25
25
|
root do # index
|
26
26
|
@deprecations = collector_instance.read_each.to_a.compact
|
27
|
-
@deprecations = @deprecations.sort_by { |dep| dep[:message] } unless params[:sort] == "0"
|
27
|
+
@deprecations = @deprecations.sort_by { |dep| dep[:message].to_s } unless params[:sort] == "0"
|
28
28
|
|
29
29
|
if params[:reject]
|
30
|
-
@deprecations = @deprecations.reject { |dep| dep[:message]
|
30
|
+
@deprecations = @deprecations.reject { |dep| dep[:message]&.match?(Regexp.union(Array(params[:reject]))) }
|
31
31
|
end
|
32
32
|
|
33
33
|
if params[:realm]
|
34
|
-
@deprecations = @deprecations.select { |dep| dep[:realm]
|
34
|
+
@deprecations = @deprecations.select { |dep| dep[:realm]&.match?(Regexp.union(Array(params[:realm]))) }
|
35
35
|
end
|
36
36
|
|
37
|
-
render slim: "index.html"
|
37
|
+
render slim: "index.html", locals: { deprecations: @deprecations }
|
38
38
|
end
|
39
39
|
|
40
40
|
get "/dump.json" do
|
@@ -42,12 +42,13 @@ class DeprecationCollector
|
|
42
42
|
end
|
43
43
|
|
44
44
|
get "/import" do
|
45
|
-
|
45
|
+
halt 403, "Import not enabled" unless import_enabled?
|
46
46
|
|
47
47
|
render slim: "import.html"
|
48
48
|
end
|
49
49
|
|
50
50
|
post "/import" do
|
51
|
+
halt 403, "Import not enabled" unless import_enabled?
|
51
52
|
unless env["CONTENT_TYPE"]&.start_with?("multipart/form-data") && params.dig(:file, :tempfile)
|
52
53
|
halt 422, "need multipart json file"
|
53
54
|
end
|
@@ -14,7 +14,7 @@ class DeprecationCollector
|
|
14
14
|
|
15
15
|
def root_path
|
16
16
|
# request.base_url ?
|
17
|
-
"#{env[
|
17
|
+
"#{env['SCRIPT_NAME']}/"
|
18
18
|
end
|
19
19
|
|
20
20
|
def current_path
|
@@ -26,7 +26,7 @@ class DeprecationCollector
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def deprecation_path(id, format: nil)
|
29
|
-
["#{root_path}#{id}", format].compact.join(
|
29
|
+
["#{root_path}#{id}", format].compact.join(".")
|
30
30
|
end
|
31
31
|
|
32
32
|
def enable_deprecations_path
|
@@ -50,7 +50,10 @@ class DeprecationCollector
|
|
50
50
|
def trigger_rails_deprecation
|
51
51
|
return unless defined?(ActiveSupport::Deprecation)
|
52
52
|
|
53
|
-
|
53
|
+
deprecator = ActiveSupport::Deprecation
|
54
|
+
deprecator = ActiveSupport::Deprecation.new("0.0", "deprecation_collector") if Rails.gem_version >= "7.1"
|
55
|
+
|
56
|
+
-> { deprecator.warn("Test deprecation") } []
|
54
57
|
end
|
55
58
|
|
56
59
|
def current_color_theme
|
@@ -62,14 +65,16 @@ class DeprecationCollector
|
|
62
65
|
end
|
63
66
|
|
64
67
|
def detect_tag(deprecation)
|
65
|
-
msg = deprecation[:message]
|
68
|
+
msg = deprecation[:message].to_s
|
66
69
|
return :kwargs if msg.include?("Using the last argument as keyword parameters is deprecated") ||
|
67
70
|
msg.include?("Passing the keyword argument as the last hash parameter is deprecated")
|
71
|
+
|
72
|
+
nil
|
68
73
|
end
|
69
74
|
|
70
75
|
def test_deprecation?(deprecation)
|
71
|
-
%w[trigger_kwargs_error_warning trigger_rails_deprecation].any? do
|
72
|
-
|
76
|
+
%w[trigger_kwargs_error_warning trigger_rails_deprecation].any? do |method|
|
77
|
+
deprecation[:message].to_s.include?(method)
|
73
78
|
end
|
74
79
|
end
|
75
80
|
|
@@ -82,11 +87,13 @@ class DeprecationCollector
|
|
82
87
|
tags << deprecation[:realm] if deprecation[:realm] && deprecation[:realm] != "rails"
|
83
88
|
tags.merge(deprecation.dig(:notes, :tags) || [])
|
84
89
|
|
85
|
-
tags.
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
+
tags.map do |tag|
|
91
|
+
if tag == :test
|
92
|
+
[tag, "bg-success"]
|
93
|
+
else
|
94
|
+
[tag, "bg-secondary"]
|
95
|
+
end
|
96
|
+
end.to_h
|
90
97
|
end
|
91
98
|
end
|
92
99
|
end
|
@@ -54,7 +54,7 @@ class DeprecationCollector
|
|
54
54
|
return [
|
55
55
|
404,
|
56
56
|
{ "content-type" => "text/plain", "x-cascade" => "pass" },
|
57
|
-
["Not Found #{env[
|
57
|
+
["Not Found #{env['REQUEST_METHOD'].inspect} #{env[PATH_INFO].inspect}"]
|
58
58
|
]
|
59
59
|
end
|
60
60
|
|
@@ -172,18 +172,18 @@ class DeprecationCollector
|
|
172
172
|
}
|
173
173
|
|
174
174
|
return [status, { "content-type" => "text/html" }.merge(color_scheme_headers), [html.to_s]] if html
|
175
|
+
|
176
|
+
nil
|
175
177
|
end
|
176
178
|
|
177
179
|
VIEW_PATH = "#{__dir__}/views"
|
178
180
|
|
179
181
|
def render_template(template, &block)
|
180
182
|
template_target = template.gsub(/\.slim\z/, ".template.rb")
|
181
|
-
template_method_name = "_template_#{template_target.gsub(/[^\w]/,
|
183
|
+
template_method_name = "_template_#{template_target.gsub(/[^\w]/, '_')}"
|
182
184
|
template_filename = File.join(VIEW_PATH, template_target.to_s)
|
183
185
|
|
184
|
-
if
|
185
|
-
_recompile_template(template, template_filename, template_method_name)
|
186
|
-
end
|
186
|
+
_recompile_template(template, template_filename, template_method_name) if _recompile_enabled?
|
187
187
|
|
188
188
|
_load_template(template_filename, template_method_name) unless respond_to?(template_method_name)
|
189
189
|
|
@@ -202,6 +202,10 @@ class DeprecationCollector
|
|
202
202
|
ActionContext.class_eval(src, template_filename.gsub(/\.template\.rb\z/, ".slim"), 1)
|
203
203
|
end
|
204
204
|
|
205
|
+
def _recompile_enabled?
|
206
|
+
ENV["DEPRECATION_COLLECTOR_RELOAD_WEB_TEMPLATES"]
|
207
|
+
end
|
208
|
+
|
205
209
|
def _recompile_template(template, template_filename, template_method_name)
|
206
210
|
original_template_name = File.join(VIEW_PATH, template.to_s)
|
207
211
|
puts "Recompiling #{original_template_name}"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
header
|
2
|
+
h1 Import dump
|
3
|
+
|
4
|
+
main
|
5
|
+
form method="post" action=import_deprecations_path enctype="multipart/form-data"
|
6
|
+
.mb-3
|
7
|
+
label.form-label> for="file" Choose a JSON file to upload:
|
8
|
+
input.form-comtrol type="file" name="file" id="file"
|
9
|
+
.mb-3
|
10
|
+
button.btn.btn-primary> type="submit" Upload
|
11
|
+
a.btn.btn-secondary> href=dump_deprecations_path Dump
|
12
|
+
a.btn.btn-secondary> href=deprecations_path Back
|
@@ -0,0 +1,121 @@
|
|
1
|
+
header.mb-3
|
2
|
+
h1 Deprecations
|
3
|
+
|
4
|
+
a.btn.btn-primary>(data-method="post" href=deprecation_path(:trigger) rel="nofollow") Trigger a couple
|
5
|
+
a.btn.btn-danger>(data-method="delete" data-confirm="Sure?" href=deprecation_path(:all) rel="nofollow")
|
6
|
+
i.bi.bi-trash
|
7
|
+
' Delete all
|
8
|
+
|
9
|
+
- if DeprecationCollector.instance.storage.support_disabling?
|
10
|
+
- if DeprecationCollector.instance.storage.enabled?
|
11
|
+
a.btn.btn-danger>(
|
12
|
+
data-method="delete" href=disable_deprecations_path rel="nofollow"
|
13
|
+
data-confirm="Sure? Will need to restart workers after enabling"
|
14
|
+
) Disable
|
15
|
+
- else
|
16
|
+
a.btn.btn-secondary>(
|
17
|
+
data-method="post" href=enable_deprecations_path rel="nofollow"
|
18
|
+
) Turn on (after workers restart)
|
19
|
+
|
20
|
+
main
|
21
|
+
table.table.table-striped
|
22
|
+
tr
|
23
|
+
th Count
|
24
|
+
th Message
|
25
|
+
th Location
|
26
|
+
th Ruby/Rails
|
27
|
+
|
28
|
+
- total = 0
|
29
|
+
- by_realm = Hash.new(0)
|
30
|
+
- deprecations.each do |deprecation|
|
31
|
+
- total += 1
|
32
|
+
- by_realm[deprecation[:realm]] += 1
|
33
|
+
tr data-digest=deprecation[:digest]
|
34
|
+
td
|
35
|
+
a href=deprecation_path(deprecation[:digest]) = deprecation[:count]
|
36
|
+
br
|
37
|
+
- deprecation_tags(deprecation).each_pair do |tag, cls|
|
38
|
+
.badge> class=cls = tag
|
39
|
+
|
40
|
+
td
|
41
|
+
ruby:
|
42
|
+
msg = deprecation[:message].to_s
|
43
|
+
delete_prefixes = Gem.path + [defined?(Rails) && Rails.root.to_s].compact
|
44
|
+
delete_prefixes.each { |path| msg = msg.gsub(path, '') }
|
45
|
+
msg.delete_prefix! deprecation[:gem_traceline].gsub(/:in .+/, ':') if deprecation[:gem_traceline]
|
46
|
+
msg.delete_prefix! deprecation[:app_traceline].gsub(/:in .+/, ':') if deprecation[:app_traceline]
|
47
|
+
msg.strip!
|
48
|
+
msg.delete_prefix!("DEPRECATION WARNING: ")
|
49
|
+
msg.delete_prefix!("warning: ")
|
50
|
+
|
51
|
+
- if msg.lines.size > 2
|
52
|
+
pre.pre-scrollable.p-1(style="overflow: auto; max-width: 700px; max-height: 200px; font-size: 11px")
|
53
|
+
code = msg
|
54
|
+
- else
|
55
|
+
.msg = msg
|
56
|
+
- if deprecation.dig(:notes, :comment)
|
57
|
+
= deprecation.dig(:notes, :comment)
|
58
|
+
|
59
|
+
- if deprecation.dig(:context, :action)
|
60
|
+
i.small.controller = deprecation.dig(:context, :action)
|
61
|
+
- elsif deprecation.dig(:context, :params, :controller)
|
62
|
+
i.small.controller = deprecation.dig(:context, :params).slice(:controller, :action).values.join('#')
|
63
|
+
|
64
|
+
td.small
|
65
|
+
- if deprecation[:gem_traceline]
|
66
|
+
.gem_location
|
67
|
+
- location, function = deprecation[:gem_traceline].split(':in `', 2)
|
68
|
+
- full_gemname = location.delete_prefix('/gems/').gsub(%r{/.*}, '')
|
69
|
+
- location_in_gem = location.delete_prefix("/gems/#{full_gemname}/")
|
70
|
+
i>= full_gemname
|
71
|
+
code.code_location> data-copy-value=location_in_gem = location_in_gem.delete_prefix('lib/')
|
72
|
+
i= function.delete_suffix("'")
|
73
|
+
- if deprecation[:app_traceline]
|
74
|
+
.app_location
|
75
|
+
- location, function = deprecation[:app_traceline].split(':in `', 2)
|
76
|
+
code.code_location>= location
|
77
|
+
i= function.delete_suffix("'")
|
78
|
+
td
|
79
|
+
.small.ruby = deprecation[:ruby_version]
|
80
|
+
.small.rails = deprecation[:rails_version]
|
81
|
+
|
82
|
+
a href=deprecation_path(deprecation[:digest]) data-method="delete" data-confirm="Delete?" rel="nofollow" title="Delete"
|
83
|
+
i.bi.bi-trash
|
84
|
+
- if total.zero?
|
85
|
+
tr
|
86
|
+
td colspan=4
|
87
|
+
p Looks like there're no deprecations (or workers have not yet wrote to redis)
|
88
|
+
p
|
89
|
+
' You can try
|
90
|
+
a href=deprecation_path(:trigger) data-method="post" rel="nofollow" trigger a couple
|
91
|
+
- if import_enabled?
|
92
|
+
|> , or
|
93
|
+
a> href=import_deprecations_path import
|
94
|
+
|
95
|
+
|
96
|
+
footer
|
97
|
+
- if total > 3
|
98
|
+
=> total
|
99
|
+
' deprecations
|
100
|
+
- by_realm.each_pair do |realm, count|
|
101
|
+
a.btn.btn-sm.btn-outline-secondary> href="?realm=#{realm}"
|
102
|
+
=> realm
|
103
|
+
.badge> class=(count == 0 ? 'bg-success' : 'bg-secondary') = count
|
104
|
+
- if params[:realm] && params[:realm] != ''
|
105
|
+
a.btn.btn-sm.btn-outline-primary> href="?realm="
|
106
|
+
' Other realms
|
107
|
+
|
108
|
+
css:
|
109
|
+
.code_location {
|
110
|
+
cursor: pointer;
|
111
|
+
}
|
112
|
+
|
113
|
+
javascript:
|
114
|
+
document.querySelectorAll('.code_location').forEach(function(elem){
|
115
|
+
elem.addEventListener('click', function () {
|
116
|
+
let textToCopy = elem.getAttribute('data-copy-value');
|
117
|
+
if(!textToCopy) textToCopy = elem.innerText;
|
118
|
+
console.log("Copying", textToCopy)
|
119
|
+
navigator.clipboard.writeText(textToCopy);
|
120
|
+
}, false);
|
121
|
+
});
|
@@ -1,4 +1,4 @@
|
|
1
|
-
_buf = ''; _buf << ("<header class=\"mb-3\"><h1>Deprecations</h1><a class=\"btn btn-primary\" data-method=\"post\"".freeze);
|
1
|
+
_buf = ''.dup; _buf << ("<header class=\"mb-3\"><h1>Deprecations</h1><a class=\"btn btn-primary\" data-method=\"post\"".freeze);
|
2
2
|
;
|
3
3
|
;
|
4
4
|
; _slim_codeattributes1 = deprecation_path(:trigger); if _slim_codeattributes1; if _slim_codeattributes1 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes1))).to_s); _buf << ("\"".freeze); end; end; _buf << (" rel=\"nofollow\">Trigger a couple</a> <a class=\"btn btn-danger\" data-confirm=\"Sure?\" data-method=\"delete\"".freeze);
|
@@ -27,7 +27,7 @@ _buf = ''; _buf << ("<header class=\"mb-3\"><h1>Deprecations</h1><a class=\"btn
|
|
27
27
|
;
|
28
28
|
; total = 0;
|
29
29
|
; by_realm = Hash.new(0);
|
30
|
-
;
|
30
|
+
; deprecations.each do |deprecation|;
|
31
31
|
; total += 1;
|
32
32
|
; by_realm[deprecation[:realm]] += 1;
|
33
33
|
; _buf << ("<tr".freeze); _slim_codeattributes5 = deprecation[:digest]; if _slim_codeattributes5; if _slim_codeattributes5 == true; _buf << (" data-digest=\"\"".freeze); else; _buf << (" data-digest=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes5))).to_s); _buf << ("\"".freeze); end; end; _buf << ("><td><a".freeze);
|
@@ -35,13 +35,13 @@ _buf = ''; _buf << ("<header class=\"mb-3\"><h1>Deprecations</h1><a class=\"btn
|
|
35
35
|
; _slim_codeattributes6 = deprecation_path(deprecation[:digest]); if _slim_codeattributes6; if _slim_codeattributes6 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes6))).to_s); _buf << ("\"".freeze); end; end; _buf << (">".freeze); _buf << ((::Temple::Utils.escape_html((deprecation[:count]))).to_s);
|
36
36
|
; _buf << ("</a><br />".freeze);
|
37
37
|
; deprecation_tags(deprecation).each_pair do |tag, cls|;
|
38
|
-
; _buf << ("<div".freeze); _temple_html_attributeremover1 = ''; _temple_html_attributemerger1 = []; _temple_html_attributemerger1[0] = "badge"; _temple_html_attributemerger1[1] = ''; _slim_codeattributes7 = cls; if Array === _slim_codeattributes7; _slim_codeattributes7 = _slim_codeattributes7.flatten; _slim_codeattributes7.map!(&:to_s); _slim_codeattributes7.reject!(&:empty?); _temple_html_attributemerger1[1] << ((::Temple::Utils.escape_html((_slim_codeattributes7.join(" ")))).to_s); else; _temple_html_attributemerger1[1] << ((::Temple::Utils.escape_html((_slim_codeattributes7))).to_s); end; _temple_html_attributemerger1[1]; _temple_html_attributeremover1 << ((_temple_html_attributemerger1.reject(&:empty?).join(" ")).to_s); _temple_html_attributeremover1; if !_temple_html_attributeremover1.empty?; _buf << (" class=\"".freeze); _buf << ((_temple_html_attributeremover1).to_s); _buf << ("\"".freeze); end; _buf << (">".freeze); _buf << ((::Temple::Utils.escape_html((tag))).to_s);
|
38
|
+
; _buf << ("<div".freeze); _temple_html_attributeremover1 = ''.dup; _temple_html_attributemerger1 = []; _temple_html_attributemerger1[0] = "badge"; _temple_html_attributemerger1[1] = ''.dup; _slim_codeattributes7 = cls; if Array === _slim_codeattributes7; _slim_codeattributes7 = _slim_codeattributes7.flatten; _slim_codeattributes7.map!(&:to_s); _slim_codeattributes7.reject!(&:empty?); _temple_html_attributemerger1[1] << ((::Temple::Utils.escape_html((_slim_codeattributes7.join(" ")))).to_s); else; _temple_html_attributemerger1[1] << ((::Temple::Utils.escape_html((_slim_codeattributes7))).to_s); end; _temple_html_attributemerger1[1]; _temple_html_attributeremover1 << ((_temple_html_attributemerger1.reject(&:empty?).join(" ")).to_s); _temple_html_attributeremover1; if !_temple_html_attributeremover1.empty?; _buf << (" class=\"".freeze); _buf << ((_temple_html_attributeremover1).to_s); _buf << ("\"".freeze); end; _buf << (">".freeze); _buf << ((::Temple::Utils.escape_html((tag))).to_s);
|
39
39
|
;
|
40
40
|
; _buf << ("</div> ".freeze); end; _buf << ("</td><td>".freeze);
|
41
41
|
;
|
42
|
-
; msg = deprecation[:message]
|
42
|
+
; msg = deprecation[:message].to_s
|
43
43
|
delete_prefixes = Gem.path + [defined?(Rails) && Rails.root.to_s].compact
|
44
|
-
delete_prefixes.each { |path| msg.gsub
|
44
|
+
delete_prefixes.each { |path| msg = msg.gsub(path, '') }
|
45
45
|
msg.delete_prefix! deprecation[:gem_traceline].gsub(/:in .+/, ':') if deprecation[:gem_traceline]
|
46
46
|
msg.delete_prefix! deprecation[:app_traceline].gsub(/:in .+/, ':') if deprecation[:app_traceline]
|
47
47
|
msg.strip!
|
@@ -100,7 +100,7 @@ msg.delete_prefix!("warning: ")
|
|
100
100
|
; end; by_realm.each_pair do |realm, count|;
|
101
101
|
; _buf << ("<a class=\"btn btn-sm btn-outline-secondary\" href=\"?realm=".freeze); _buf << ((::Temple::Utils.escape_html((realm))).to_s); _buf << ("\">".freeze);
|
102
102
|
; _buf << ((::Temple::Utils.escape_html((realm))).to_s);
|
103
|
-
; _buf << (" <div".freeze); _temple_html_attributeremover2 = ''; _temple_html_attributemerger2 = []; _temple_html_attributemerger2[0] = "badge"; _temple_html_attributemerger2[1] = ''; _slim_codeattributes13 = (count == 0 ? 'bg-success' : 'bg-secondary'); if Array === _slim_codeattributes13; _slim_codeattributes13 = _slim_codeattributes13.flatten; _slim_codeattributes13.map!(&:to_s); _slim_codeattributes13.reject!(&:empty?); _temple_html_attributemerger2[1] << ((::Temple::Utils.escape_html((_slim_codeattributes13.join(" ")))).to_s); else; _temple_html_attributemerger2[1] << ((::Temple::Utils.escape_html((_slim_codeattributes13))).to_s); end; _temple_html_attributemerger2[1]; _temple_html_attributeremover2 << ((_temple_html_attributemerger2.reject(&:empty?).join(" ")).to_s); _temple_html_attributeremover2; if !_temple_html_attributeremover2.empty?; _buf << (" class=\"".freeze); _buf << ((_temple_html_attributeremover2).to_s); _buf << ("\"".freeze); end; _buf << (">".freeze); _buf << ((::Temple::Utils.escape_html((count))).to_s);
|
103
|
+
; _buf << (" <div".freeze); _temple_html_attributeremover2 = ''.dup; _temple_html_attributemerger2 = []; _temple_html_attributemerger2[0] = "badge"; _temple_html_attributemerger2[1] = ''.dup; _slim_codeattributes13 = (count == 0 ? 'bg-success' : 'bg-secondary'); if Array === _slim_codeattributes13; _slim_codeattributes13 = _slim_codeattributes13.flatten; _slim_codeattributes13.map!(&:to_s); _slim_codeattributes13.reject!(&:empty?); _temple_html_attributemerger2[1] << ((::Temple::Utils.escape_html((_slim_codeattributes13.join(" ")))).to_s); else; _temple_html_attributemerger2[1] << ((::Temple::Utils.escape_html((_slim_codeattributes13))).to_s); end; _temple_html_attributemerger2[1]; _temple_html_attributeremover2 << ((_temple_html_attributemerger2.reject(&:empty?).join(" ")).to_s); _temple_html_attributeremover2; if !_temple_html_attributeremover2.empty?; _buf << (" class=\"".freeze); _buf << ((_temple_html_attributeremover2).to_s); _buf << ("\"".freeze); end; _buf << (">".freeze); _buf << ((::Temple::Utils.escape_html((count))).to_s);
|
104
104
|
; _buf << ("</div> </a> ".freeze); end; if params[:realm] && params[:realm] != '';
|
105
105
|
; _buf << ("<a class=\"btn btn-sm btn-outline-primary\" href=\"?realm=\">Other realms </a> ".freeze);
|
106
106
|
;
|