deprecation_collector 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,26 +2,31 @@
2
2
 
3
3
  class DeprecationCollector
4
4
  class Web
5
+ # :nodoc:
5
6
  module Helpers
6
7
  def collector_instance
7
8
  @collector_instance || DeprecationCollector.instance
8
9
  end
9
10
 
11
+ def import_enabled?
12
+ @web.import_enabled
13
+ end
14
+
10
15
  def root_path
11
16
  # request.base_url ?
12
17
  "#{env["SCRIPT_NAME"]}/"
13
18
  end
14
19
 
15
20
  def current_path
16
- @current_path ||= request.path_info.gsub(/^\//, "")
21
+ @current_path ||= request.path_info.gsub(%r{^/}, "")
17
22
  end
18
23
 
19
24
  def deprecations_path
20
- "#{root_path}"
25
+ root_path # /
21
26
  end
22
27
 
23
- def deprecation_path(id)
24
- "#{root_path}#{id}"
28
+ def deprecation_path(id, format: nil)
29
+ ["#{root_path}#{id}", format].compact.join('.')
25
30
  end
26
31
 
27
32
  def enable_deprecations_path
@@ -32,12 +37,51 @@ class DeprecationCollector
32
37
  "#{root_path}disable"
33
38
  end
34
39
 
40
+ def dump_deprecations_path
41
+ "#{root_path}dump.json"
42
+ end
43
+
44
+ def import_deprecations_path
45
+ "#{root_path}import"
46
+ end
47
+
35
48
  def trigger_kwargs_error_warning(foo: nil); end
36
49
 
37
50
  def trigger_rails_deprecation
38
51
  return unless defined?(ActiveSupport::Deprecation)
52
+
39
53
  -> { ActiveSupport::Deprecation.warn("Test deprecation") } []
40
54
  end
55
+
56
+ def current_color_theme
57
+ return "dark" if params["dark"]
58
+ return "light" if params["light"]
59
+ return "dark" if request.get_header("HTTP_Sec_CH_Prefers_Color_Scheme").to_s.downcase.include?("dark")
60
+
61
+ "auto"
62
+ end
63
+
64
+ def detect_tag(deprecation)
65
+ msg = deprecation[:message]
66
+ return :kwargs if msg.include?("Using the last argument as keyword parameters is deprecated") ||
67
+ msg.include?("Passing the keyword argument as the last hash parameter is deprecated")
68
+ return :test if msg.include?("trigger_kwargs_error_warning") || msg.include?("trigger_rails_deprecation")
69
+ end
70
+
71
+ def deprecation_tags(deprecation)
72
+ tags = Set.new
73
+ if (detected_tag = detect_tag(deprecation))
74
+ tags << detected_tag
75
+ end
76
+ tags << deprecation[:realm] if deprecation[:realm] && deprecation[:realm] != "rails"
77
+ tags.merge(deprecation.dig(:notes, :tags) || [])
78
+
79
+ tags.to_h do |tag|
80
+ next [tag, "bg-success"] if tag == :test
81
+
82
+ [tag, "bg-secondary"]
83
+ end
84
+ end
41
85
  end
42
86
  end
43
87
  end
@@ -2,19 +2,20 @@
2
2
 
3
3
  class DeprecationCollector
4
4
  class Web
5
+ # :nodoc:
5
6
  module Router
6
7
  HTTP_METHODS = %w[GET HEAD POST PUT PATCH DELETE].freeze
7
8
  HTTP_METHODS.each do |http_method|
8
9
  const_set http_method, http_method
9
- class_eval <<~RUBY, __FILE__, __LINE__+1
10
- def #{http_method.downcase}(path, &block)
11
- route(#{http_method}, path, &block)
12
- end
10
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
11
+ def #{http_method.downcase}(path, &block) # def get(path, &block)
12
+ route(#{http_method}, path, &block) # route('GET', path, &block)
13
+ end # end
13
14
  RUBY
14
15
  end
15
16
 
16
17
  def root(&block)
17
- route(GET, '/', &block)
18
+ route(GET, "/", &block)
18
19
  end
19
20
 
20
21
  def route(method, path, &block)
@@ -23,10 +24,10 @@ class DeprecationCollector
23
24
 
24
25
  def helpers(mod = nil, &block)
25
26
  return ActionContext.class_eval(&block) if block
27
+
26
28
  ActionContext.send(:include, mod)
27
29
  end
28
30
 
29
-
30
31
  ROUTE_PARAMS = "rack.route_params"
31
32
  PATH_INFO = "PATH_INFO"
32
33
 
@@ -39,35 +40,33 @@ class DeprecationCollector
39
40
  path_info = "/" if path_info == "" # some buggy servers may pass empty root path
40
41
 
41
42
  @routes[request_method.upcase]&.find do |route|
42
- params = route.match(request_method, path_info)
43
+ params = route.match(request_method.upcase, path_info)
43
44
  next unless params
45
+
44
46
  env[ROUTE_PARAMS] = params
45
47
  break ActionContext.new(request, &route.block)
46
48
  end
47
49
  end
48
50
 
49
- def call(env)
51
+ def call(env, application = nil)
50
52
  action = match(env)
51
53
  unless action
52
54
  return [
53
55
  404,
54
- {"content-type" => "text/plain", "x-cascade" => "pass"},
56
+ { "content-type" => "text/plain", "x-cascade" => "pass" },
55
57
  ["Not Found #{env["REQUEST_METHOD"].inspect} #{env[PATH_INFO].inspect}"]
56
58
  ]
57
59
  end
58
60
 
59
- resp = catch(:halt) do
60
- action.call(env)
61
- ensure
62
- end
61
+ resp = catch(:halt) { action.call(env, application) }
63
62
 
64
63
  return resp if resp.is_a?(Array) # raw rack responses (redirects etc.)
65
64
 
66
65
  # rendered content goes here
67
66
  headers = {
68
67
  "content-type" => "text/html",
69
- "cache-control" => "private, no-store",
70
- # TODO:
68
+ "cache-control" => "private, no-store"
69
+ # TODO: locale/csp
71
70
  # "content-language" => action.locale,
72
71
  # "content-security-policy" => CSP_HEADER
73
72
  }
@@ -75,10 +74,11 @@ class DeprecationCollector
75
74
  [200, headers, [resp]]
76
75
  end
77
76
 
77
+ # :nodoc:
78
78
  class Route
79
79
  attr_accessor :request_method, :pattern, :block
80
80
 
81
- NAMED_SEGMENTS_PATTERN = /\/([^\/]*):([^.:$\/]+)/
81
+ NAMED_SEGMENTS_PATTERN = %r{/([^/]*):([^.:$/]+)}.freeze
82
82
 
83
83
  def initialize(request_method, pattern, block)
84
84
  @request_method = request_method
@@ -92,12 +92,15 @@ class DeprecationCollector
92
92
 
93
93
  def compile_matcher
94
94
  return pattern unless pattern.match?(NAMED_SEGMENTS_PATTERN)
95
- regex_pattern = pattern.gsub(NAMED_SEGMENTS_PATTERN, '/\1(?<\2>[^$/]+)') # /some/:id => /some/(?<id>[^$/]+)
96
95
 
96
+ regex_pattern = pattern.gsub(NAMED_SEGMENTS_PATTERN, '/\1(?<\2>[^$/]+)') # /some/:id => /some/(?<id>[^$/]+)
97
97
  Regexp.new("\\A#{regex_pattern}\\Z")
98
98
  end
99
99
 
100
100
  def match(request_method, path)
101
+ # this is actually not needed because of groupping by method, but just in case:
102
+ return unless self.request_method == request_method
103
+
101
104
  case matcher
102
105
  when String
103
106
  {} if path == matcher
@@ -108,6 +111,7 @@ class DeprecationCollector
108
111
  end
109
112
  end
110
113
 
114
+ # :nodoc:
111
115
  class ActionContext
112
116
  attr_accessor :request
113
117
 
@@ -116,7 +120,8 @@ class DeprecationCollector
116
120
  @block = block
117
121
  end
118
122
 
119
- def call(env)
123
+ def call(_env, application)
124
+ @web = application.web
120
125
  instance_exec(&@block)
121
126
  end
122
127
 
@@ -129,24 +134,30 @@ class DeprecationCollector
129
134
  end
130
135
 
131
136
  def params
132
- @params ||= Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
133
- .merge!(request.params)
134
- .merge!(route_params.transform_keys(&:to_s))
137
+ @params ||= Hash.new { |hash, key| hash[key.to_s] if key.is_a?(Symbol) }
138
+ .merge!(request.params)
139
+ .merge!(route_params.transform_keys(&:to_s))
135
140
  end
136
141
 
137
- def halt(res)
138
- throw :halt, [res, {"content-type" => "text/plain"}, [res.to_s]]
142
+ def halt(res, content = nil)
143
+ throw :halt, [res, { "content-type" => "text/plain" }, [content || res.to_s]]
139
144
  end
140
145
 
141
146
  def redirect_to(location)
142
- throw :halt, [302, {"location" => "#{request.base_url}#{location}"}, []]
147
+ throw :halt, [302, { "location" => "#{request.base_url}#{location}" }, []]
143
148
  end
144
149
 
145
- def render(plain: nil, html: nil, json: nil, erb: nil, slim: nil, status: 200, locals: nil, layout: 'layout.html.slim')
146
- raise ArgumentError, "provide exactly one render format" unless [plain, html, json, erb, slim].compact.size == 1
150
+ def render(plain: nil, html: nil, json: nil, erb: nil, slim: nil, # rubocop:disable Metrics
151
+ status: 200, locals: nil, layout: "layout.html.slim")
152
+ unless [plain, html, json, erb, slim].compact.size == 1
153
+ raise ArgumentError, "provide exactly one render format"
154
+ end
147
155
 
148
- return [status, {"content-type" => "application/json"}, [JSON.generate(json)]] if json
149
- return [status, {"content-type" => "text/plain"}, [plain.to_s]] if plain
156
+ if json
157
+ json = JSON.generate(json) unless json.is_a?(String)
158
+ return [status, { "content-type" => "application/json" }, [json]]
159
+ end
160
+ return [status, { "content-type" => "text/plain" }, [plain.to_s]] if plain
150
161
 
151
162
  _define_locals(locals) if locals
152
163
  template = "#{erb}.erb" if erb
@@ -154,39 +165,55 @@ class DeprecationCollector
154
165
  html = render_template(template) if template
155
166
  html = render_template(layout) { html } if layout
156
167
 
157
- return [status, {"content-type" => "text/html"}, [html.to_s]] if html
168
+ color_scheme_headers = {
169
+ "Accept-CH" => "Sec-CH-Prefers-Color-Scheme",
170
+ "Vary" => "Sec-CH-Prefers-Color-Scheme",
171
+ "Critical-CH" => "Sec-CH-Prefers-Color-Scheme"
172
+ }
173
+
174
+ return [status, { "content-type" => "text/html" }.merge(color_scheme_headers), [html.to_s]] if html
158
175
  end
159
176
 
160
177
  VIEW_PATH = "#{__dir__}/views"
161
178
 
162
179
  def render_template(template, &block)
163
- original_template_name = File.join(VIEW_PATH, template.to_s)
164
- template = template.gsub(/\.slim\z/, '.template.rb')
165
- template_method_name = "_template_#{template.gsub(/[^\w]/, '_')}"
166
- template_filename = File.join(VIEW_PATH, template.to_s)
167
-
168
- if ENV['DEPRECATION_COLLECTOR_RELOAD_WEB_TEMPLATES']
169
- require 'slim'
170
- puts "Recompiling #{original_template_name}"
171
- ActionContext.class_eval { undef_method(template_method_name) } if respond_to?(template_method_name)
172
- if original_template_name.end_with?('.slim')
173
- File.write(template_filename, Slim::Template.new(original_template_name).precompiled_template)
174
- end
175
- end
180
+ template_target = template.gsub(/\.slim\z/, ".template.rb")
181
+ template_method_name = "_template_#{template_target.gsub(/[^\w]/, "_")}"
182
+ template_filename = File.join(VIEW_PATH, template_target.to_s)
176
183
 
177
- unless respond_to?(template_method_name)
178
- src = File.read(template_filename)
179
- src = ERB.new(src).src if template_filename.end_with?('.erb')
180
- ActionContext.class_eval <<-RUBY, template_filename.gsub(/\.template\.rb\z/, '.slim'), 1
181
- def #{template_method_name}; #{src}
182
- end
183
- RUBY
184
+ if ENV["DEPRECATION_COLLECTOR_RELOAD_WEB_TEMPLATES"]
185
+ _recompile_template(template, template_filename, template_method_name)
184
186
  end
185
187
 
188
+ _load_template(template_filename, template_method_name) unless respond_to?(template_method_name)
189
+
186
190
  send(template_method_name, &block)
187
191
  end
188
192
 
189
193
  private
194
+
195
+ def _load_template(template_filename, template_method_name)
196
+ src = File.read(template_filename)
197
+ src = ERB.new(src).src if template_filename.end_with?(".erb")
198
+ src = <<-RUBY
199
+ def #{template_method_name}; #{src}
200
+ end
201
+ RUBY
202
+ ActionContext.class_eval(src, template_filename.gsub(/\.template\.rb\z/, ".slim"), 1)
203
+ end
204
+
205
+ def _recompile_template(template, template_filename, template_method_name)
206
+ original_template_name = File.join(VIEW_PATH, template.to_s)
207
+ puts "Recompiling #{original_template_name}"
208
+ ActionContext.class_eval { undef_method(template_method_name) } if respond_to?(template_method_name)
209
+
210
+ if original_template_name.end_with?(".slim")
211
+ require "slim"
212
+ File.write(template_filename, Slim::Template.new(original_template_name).precompiled_template)
213
+ end
214
+ template_method_name
215
+ end
216
+
190
217
  def _define_locals(locals)
191
218
  locals&.each { |k, v| define_singleton_method(k) { v } unless singleton_methods.include?(k) }
192
219
  end
@@ -1,13 +1,16 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  begin
3
- require 'cgi/escape'
4
+ # this is stdgem in ruby 2.7+
5
+ require "cgi/escape"
4
6
  rescue LoadError
7
+ # optional dependency not present
5
8
  end
6
9
 
7
10
  module Temple
8
11
  # @api public
9
12
  module Utils
10
- extend self
13
+ extend self # rubocop:disable Style/ModuleFunction
11
14
 
12
15
  # Returns an escaped copy of `html`.
13
16
  # Strings which are declared as html_safe are not escaped.
@@ -31,11 +34,11 @@ module Temple
31
34
  # Used by escape_html
32
35
  # @api private
33
36
  ESCAPE_HTML = {
34
- '&' => '&amp;',
35
- '"' => '&quot;',
36
- '\'' => '&#39;',
37
- '<' => '&lt;',
38
- '>' => '&gt;'
37
+ "&" => "&amp;",
38
+ '"' => "&quot;",
39
+ "'" => "&#39;",
40
+ "<" => "&lt;",
41
+ ">" => "&gt;"
39
42
  }.freeze
40
43
 
41
44
  ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys)
@@ -0,0 +1,13 @@
1
+ _buf = ''; _buf << ("<header><h1>Import dump</h1></header><main><form".freeze);
2
+ ;
3
+ ;
4
+ ;
5
+ ; _slim_codeattributes1 = import_deprecations_path; if _slim_codeattributes1; if _slim_codeattributes1 == true; _buf << (" action=\"\"".freeze); else; _buf << (" action=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes1))).to_s); _buf << ("\"".freeze); end; end; _buf << (" enctype=\"multipart/form-data\" method=\"post\"><div class=\"mb-3\"><label class=\"form-label\" for=\"file\">Choose a JSON file to upload:</label> <input class=\"form-comtrol\" id=\"file\" name=\"file\" type=\"file\" /></div><div class=\"mb-3\"><button class=\"btn btn-primary\" type=\"submit\">Upload</button> <a class=\"btn btn-secondary\"".freeze);
6
+ ;
7
+ ;
8
+ ;
9
+ ;
10
+ ;
11
+ ; _slim_codeattributes2 = dump_deprecations_path; if _slim_codeattributes2; if _slim_codeattributes2 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes2))).to_s); _buf << ("\"".freeze); end; end; _buf << (">Dump</a> <a class=\"btn btn-secondary\"".freeze);
12
+ ; _slim_codeattributes3 = deprecations_path; if _slim_codeattributes3; if _slim_codeattributes3 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes3))).to_s); _buf << ("\"".freeze); end; end; _buf << (">Back</a> </div></form></main>".freeze);
13
+ ; _buf
@@ -1,4 +1,4 @@
1
- _buf = ''; _buf << ("<header><h1>Deprecations</h1><a class=\"btn btn-primary\" data-method=\"post\"".freeze);
1
+ _buf = ''; _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);
@@ -25,67 +25,93 @@ _buf = ''; _buf << ("<header><h1>Deprecations</h1><a class=\"btn btn-primary\" d
25
25
  ;
26
26
  ;
27
27
  ; total = 0;
28
+ ; by_realm = Hash.new(0);
28
29
  ; @deprecations.each do |deprecation|;
29
30
  ; total += 1;
31
+ ; by_realm[deprecation[:realm]] += 1;
30
32
  ; _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);
31
33
  ;
32
34
  ; _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);
33
35
  ; _buf << ("</a><br />".freeze);
34
- ; if deprecation[:message].include?("Using the last argument as keyword parameters is deprecated") || \
35
- deprecation[:message].include?("Passing the keyword argument as the last hash parameter is deprecated");
36
- ; _buf << ("<div class=\"badge bg-secondary\">kwargs</div> ".freeze);
37
- ; end; if deprecation[:message].include?("trigger_kwargs_error_warning") || \
38
- deprecation[:message].include?("trigger_rails_deprecation");
39
- ; _buf << ("<div class=\"badge bg-success\">test</div> ".freeze);
40
- ; end; if deprecation[:realm] && deprecation[:realm] != 'rails';
41
- ; _buf << ("<div class=\"badge bg-secondary\">".freeze); _buf << ((::Temple::Utils.escape_html((deprecation[:realm]))).to_s);
42
- ; _buf << ("</div> ".freeze); end; deprecation.dig(:notes, :tags)&.each do |tag|;
43
- ; _buf << ("<div class=\"badge bg-secondary\">".freeze); _buf << ((::Temple::Utils.escape_html((tag))).to_s);
36
+ ; deprecation_tags(deprecation).each_pair do |tag, cls|;
37
+ ; _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);
44
38
  ;
45
39
  ; _buf << ("</div> ".freeze); end; _buf << ("</td><td>".freeze);
46
40
  ;
47
41
  ; msg = deprecation[:message]
48
42
  delete_prefixes = Gem.path + [defined?(Rails) && Rails.root.to_s].compact
49
43
  delete_prefixes.each { |path| msg.gsub!(path, '') }
50
- ;
51
- ; _buf << ("<div class=\"card text-dark bg-light\"><pre class=\"pre-scrollable\" style=\"overflow: auto; max-width: 700px; max-height: 200px; font-size: 11px\"><code>".freeze);
52
- ;
53
- ; _buf << ((::Temple::Utils.escape_html((msg.delete_prefix("DEPRECATION WARNING: ")))).to_s);
54
- ; _buf << ("</code></pre></div>".freeze); if deprecation.dig(:notes, :comment);
44
+ msg.delete_prefix! deprecation[:gem_traceline].gsub(/:in .+/, ':') if deprecation[:gem_traceline]
45
+ msg.delete_prefix! deprecation[:app_traceline].gsub(/:in .+/, ':') if deprecation[:app_traceline]
46
+ msg.strip!
47
+ msg.delete_prefix!("DEPRECATION WARNING: ")
48
+ msg.delete_prefix!("warning: ")
49
+ ;
50
+ ; if msg.lines.size > 2;
51
+ ; _buf << ("<pre class=\"pre-scrollable p-1\" style=\"overflow: auto; max-width: 700px; max-height: 200px; font-size: 11px\"><code>".freeze);
52
+ ; _buf << ((::Temple::Utils.escape_html((msg))).to_s);
53
+ ; _buf << ("</code></pre>".freeze); else;
54
+ ; _buf << ("<div class=\"msg\">".freeze); _buf << ((::Temple::Utils.escape_html((msg))).to_s);
55
+ ; _buf << ("</div>".freeze); end; if deprecation.dig(:notes, :comment);
55
56
  ; _buf << ((::Temple::Utils.escape_html((deprecation.dig(:notes, :comment)))).to_s);
56
57
  ;
57
58
  ; end; if deprecation.dig(:context, :action);
58
- ; _buf << ("<div class=\"small controller\">".freeze); _buf << ((::Temple::Utils.escape_html((deprecation.dig(:context, :action)))).to_s);
59
- ; _buf << ("</div>".freeze); elsif deprecation.dig(:context, :params, :controller);
60
- ; _buf << ("<div class=\"small controller\">".freeze); _buf << ((::Temple::Utils.escape_html((deprecation.dig(:context, :params).slice(:controller, :action).values.join('#')))).to_s);
61
- ; _buf << ("</div>".freeze); end; _buf << ("</td><td>".freeze);
59
+ ; _buf << ("<i class=\"small controller\">".freeze); _buf << ((::Temple::Utils.escape_html((deprecation.dig(:context, :action)))).to_s);
60
+ ; _buf << ("</i>".freeze); elsif deprecation.dig(:context, :params, :controller);
61
+ ; _buf << ("<i class=\"small controller\">".freeze); _buf << ((::Temple::Utils.escape_html((deprecation.dig(:context, :params).slice(:controller, :action).values.join('#')))).to_s);
62
+ ;
63
+ ; _buf << ("</i>".freeze); end; _buf << ("</td><td class=\"small\">".freeze);
62
64
  ; if deprecation[:gem_traceline];
63
- ; _buf << ((::Temple::Utils.escape_html((deprecation[:gem_traceline]))).to_s);
64
- ; _buf << ("<br>".freeze);
65
- ; end; if deprecation[:app_traceline];
65
+ ; _buf << ("<div class=\"gem_location\">".freeze);
66
+ ; location, function = deprecation[:gem_traceline].split(':in `', 2);
67
+ ; full_gemname = location.delete_prefix('/gems/').gsub(%r{/.*}, '');
68
+ ; location_in_gem = location.delete_prefix("/gems/#{full_gemname}/");
69
+ ; _buf << ("<i>".freeze); _buf << ((::Temple::Utils.escape_html((full_gemname))).to_s);
70
+ ; _buf << ("</i> <code class=\"code_location\"".freeze); _slim_codeattributes8 = location_in_gem; if _slim_codeattributes8; if _slim_codeattributes8 == true; _buf << (" data-copy-value=\"\"".freeze); else; _buf << (" data-copy-value=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes8))).to_s); _buf << ("\"".freeze); end; end; _buf << (">".freeze); _buf << ((::Temple::Utils.escape_html((location_in_gem.delete_prefix('lib/')))).to_s);
71
+ ; _buf << ("</code> <i>".freeze); _buf << ((::Temple::Utils.escape_html((function.delete_suffix("'")))).to_s);
72
+ ; _buf << ("</i></div>".freeze); end; if deprecation[:app_traceline];
73
+ ; _buf << ("<div class=\"app_location\">".freeze);
66
74
  ; location, function = deprecation[:app_traceline].split(':in `', 2);
67
- ; _buf << ("<code class=\"code_location\" style=\"cursor: pointer\">".freeze); _buf << ((::Temple::Utils.escape_html((location))).to_s);
68
- ; _buf << ("</code> ".freeze); _buf << ((::Temple::Utils.escape_html((function.delete_suffix("'")))).to_s);
69
- ; end; _buf << ("</td><td><div class=\"small ruby\">".freeze);
75
+ ; _buf << ("<code class=\"code_location\">".freeze); _buf << ((::Temple::Utils.escape_html((location))).to_s);
76
+ ; _buf << ("</code> <i>".freeze); _buf << ((::Temple::Utils.escape_html((function.delete_suffix("'")))).to_s);
77
+ ; _buf << ("</i></div>".freeze); end; _buf << ("</td><td><div class=\"small ruby\">".freeze);
70
78
  ; _buf << ((::Temple::Utils.escape_html((deprecation[:ruby_version]))).to_s);
71
79
  ; _buf << ("</div><div class=\"small rails\">".freeze); _buf << ((::Temple::Utils.escape_html((deprecation[:rails_version]))).to_s);
72
80
  ;
73
- ; _buf << ("</div><a data-confirm=\"Delete?\" data-method=\"delete\"".freeze); _slim_codeattributes7 = deprecation_path(deprecation[:digest]); if _slim_codeattributes7; if _slim_codeattributes7 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes7))).to_s); _buf << ("\"".freeze); end; end; _buf << (" rel=\"nofollow\" title=\"Delete\"><i class=\"bi bi-trash\"></i></a></td></tr>".freeze);
81
+ ; _buf << ("</div><a data-confirm=\"Delete?\" data-method=\"delete\"".freeze); _slim_codeattributes9 = deprecation_path(deprecation[:digest]); if _slim_codeattributes9; if _slim_codeattributes9 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes9))).to_s); _buf << ("\"".freeze); end; end; _buf << (" rel=\"nofollow\" title=\"Delete\"><i class=\"bi bi-trash\"></i></a></td></tr>".freeze);
74
82
  ;
75
83
  ; end; if total.zero?;
76
84
  ; _buf << ("<tr><td".freeze);
77
- ; _slim_codeattributes8 = 4; if _slim_codeattributes8; if _slim_codeattributes8 == true; _buf << (" colspan=\"\"".freeze); else; _buf << (" colspan=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes8))).to_s); _buf << ("\"".freeze); end; end; _buf << ("><p>Looks like there're no deprecations</p><p>You can try <a data-method=\"post\"".freeze);
85
+ ; _slim_codeattributes10 = 4; if _slim_codeattributes10; if _slim_codeattributes10 == true; _buf << (" colspan=\"\"".freeze); else; _buf << (" colspan=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes10))).to_s); _buf << ("\"".freeze); end; end; _buf << ("><p>Looks like there're no deprecations (or workers have not yet wrote to redis)</p><p>You can try <a data-method=\"post\"".freeze);
78
86
  ;
79
87
  ;
80
88
  ;
81
- ; _slim_codeattributes9 = deprecation_path(:trigger); if _slim_codeattributes9; if _slim_codeattributes9 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes9))).to_s); _buf << ("\"".freeze); end; end; _buf << (" rel=\"nofollow\">trigger a couple</a></p></td></tr>".freeze);
89
+ ; _slim_codeattributes11 = deprecation_path(:trigger); if _slim_codeattributes11; if _slim_codeattributes11 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes11))).to_s); _buf << ("\"".freeze); end; end; _buf << (" rel=\"nofollow\">trigger a couple</a>".freeze);
90
+ ; if import_enabled?;
91
+ ; _buf << (", or <a".freeze);
92
+ ; _slim_codeattributes12 = import_deprecations_path; if _slim_codeattributes12; if _slim_codeattributes12 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes12))).to_s); _buf << ("\"".freeze); end; end; _buf << (">import</a> ".freeze);
82
93
  ;
83
- ; end; _buf << ("</table></main><footer>".freeze);
94
+ ;
95
+ ; end; _buf << ("</p></td></tr>".freeze); end; _buf << ("</table></main><footer>".freeze);
84
96
  ; if total > 3;
85
97
  ; _buf << ((::Temple::Utils.escape_html((total))).to_s);
86
98
  ; _buf << (" deprecations ".freeze);
99
+ ; end; by_realm.each_pair do |realm, count|;
100
+ ; _buf << ("<a class=\"btn btn-sm btn-outline-secondary\" href=\"?realm=".freeze); _buf << ((::Temple::Utils.escape_html((realm))).to_s); _buf << ("\">".freeze);
101
+ ; _buf << ((::Temple::Utils.escape_html((realm))).to_s);
102
+ ; _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> </a> ".freeze); end; if params[:realm] && params[:realm] != '';
104
+ ; _buf << ("<a class=\"btn btn-sm btn-outline-primary\" href=\"?realm=\">Other realms </a> ".freeze);
105
+ ;
106
+ ;
107
+ ; end; _buf << ("</footer><style>.code_location {\n cursor: pointer;\n}</style><script>document.querySelectorAll('.code_location').forEach(function(elem){\n elem.addEventListener('click', function () {\n let textToCopy = elem.getAttribute('data-copy-value');\n if(!textToCopy) textToCopy = elem.innerText;\n console.log(\"Copying\", textToCopy)\n navigator.clipboard.writeText(textToCopy);\n }, false);\n});</script>".freeze);
108
+ ;
109
+ ;
110
+ ;
111
+ ;
112
+ ;
113
+ ;
87
114
  ;
88
- ; end; _buf << ("</footer><script>document.querySelectorAll('.code_location').forEach(function(elem){\n elem.addEventListener('click', function () {\n console.log(\"Copying\", elem.innerText)\n navigator.clipboard.writeText(elem.innerText);\n }, false);\n});</script>".freeze);
89
115
  ;
90
116
  ;
91
117
  ;
@@ -1,11 +1,11 @@
1
- _buf = ''; _buf << ("<!DOCTYPE html><html><head><meta charset=\"utf-8\" /><meta content=\"IE=edge;chrome=1\" http-equiv=\"X-UA-Compatible\" /><title>".freeze);
2
- ;
1
+ _buf = ''; _buf << ("<!DOCTYPE html><html".freeze);
2
+ ; _slim_codeattributes1 = current_color_theme; if _slim_codeattributes1; if _slim_codeattributes1 == true; _buf << (" data-bs-theme=\"\"".freeze); else; _buf << (" data-bs-theme=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes1))).to_s); _buf << ("\"".freeze); end; end; _buf << (" lang=\"en\"><head><meta charset=\"utf-8\" /><meta content=\"IE=edge;chrome=1\" http-equiv=\"X-UA-Compatible\" /><title>".freeze);
3
3
  ;
4
4
  ;
5
5
  ;
6
6
  ;
7
7
  ; _buf << ((::Temple::Utils.escape_html(("Deprecations"))).to_s);
8
- ; _buf << ("</title><meta content=\"\" name=\"description\" /><meta content=\"width=device-width\" name=\"viewport\" /><link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css\" rel=\"stylesheet\" /><link href=\"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.2/font/bootstrap-icons.css\" rel=\"stylesheet\" /></head><body><div class=\"container-fluid\">".freeze);
8
+ ; _buf << ("</title><meta content=\"Deprecation collector ui\" name=\"description\" /><meta content=\"width=device-width\" name=\"viewport\" /><link crossorigin=\"anonymous\" href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css\" integrity=\"sha256-Fu5/PVNGJlC70y4mPEjA6nWVdPz2IMaBrXGQCJEsRho= sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ\" rel=\"stylesheet\" /><link crossorigin=\"anonymous\" href=\"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.2/font/bootstrap-icons.css\" integrity=\"sha256-4RctOgogjPAdwGbwq+rxfwAmSpZhWaafcZR9btzUk18= sha384-b6lVK+yci+bfDmaY1u0zE8YYJt0TZxLEAFyYSLHId4xoVvsrQu3INevFKo+Xir8e\" rel=\"stylesheet\" /></head><body><div class=\"container-fluid\">".freeze);
9
9
  ;
10
10
  ;
11
11
  ;
@@ -14,5 +14,78 @@ _buf = ''; _buf << ("<!DOCTYPE html><html><head><meta charset=\"utf-8\" /><meta
14
14
  ;
15
15
  ; _buf << ((yield).to_s);
16
16
  ;
17
- ; _buf << ("</div><script src=\"https://cdn.jsdelivr.net/npm/rails-ujs@5.2.8-1/lib/assets/compiled/rails-ujs.min.js\"></script></body></html>".freeze);
17
+ ; _buf << ("</div><script async=\"\" crossorigin=\"anonymous\" integrity=\"sha256-9Mbe9mGA7d+AJbnz0O6CoLGabCbe6JAYnGshvGIADiE=\" src=\"https://cdn.jsdelivr.net/npm/@rails/ujs@7.0.4-3/lib/assets/compiled/rails-ujs.js\"></script><script async=\"\" crossorigin=\"anonymous\" integrity=\"sha256-QucgBAKNM4KKPJHqTfH8e+JON1G/gmPPqtMmBb+wHpc= sha384-Y4oOpwW3duJdCWv5ly8SCFYWqFDsfob/3GkgExXKV4idmbt98QcxXYs9UoXAB7BZ\" src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.min.js\"></script><script>(() => {\n 'use strict'\n\n const storedTheme = localStorage.getItem('theme')\n\n const getPreferredTheme = () => {\n if (storedTheme) { return storedTheme }\n let fromServer = document.documentElement.getAttribute('data-bs-theme')\n if(fromServer) { return fromServer }\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n }\n\n const setTheme = function (theme) {\n if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n document.documentElement.setAttribute('data-bs-theme', 'dark')\n } else {\n document.documentElement.setAttribute('data-bs-theme', theme)\n }\n }\n\n setTheme(getPreferredTheme())\n\n const showActiveTheme = (theme, focus = false) => {\n const themeSwitcher = document.querySelector('#bd-theme')\n\n if (!themeSwitcher) {\n return\n }\n\n const themeSwitcherText = document.querySelector('#bd-theme-text')\n const activeThemeIcon = document.querySelector('.theme-icon-active use')\n const btnToActive = document.querySelector(`[data-bs-theme-value=\"${theme}\"]`)\n const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href')\n\n document.querySelectorAll('[data-bs-theme-value]').forEach(element => {\n element.classList.remove('active')\n element.setAttribute('aria-pressed', 'false')\n })\n\n btnToActive.classList.add('active')\n btnToActive.setAttribute('aria-pressed', 'true')\n activeThemeIcon.setAttribute('href', svgOfActiveBtn)\n const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`\n themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)\n\n if (focus) {\n themeSwitcher.focus()\n }\n }\n\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n if (storedTheme !== 'light' || storedTheme !== 'dark') {\n setTheme(getPreferredTheme())\n }\n })\n\n window.addEventListener('DOMContentLoaded', () => {\n showActiveTheme(getPreferredTheme())\n\n document.querySelectorAll('[data-bs-theme-value]')\n .forEach(toggle => {\n toggle.addEventListener('click', () => {\n const theme = toggle.getAttribute('data-bs-theme-value')\n localStorage.setItem('theme', theme)\n setTheme(theme)\n showActiveTheme(theme, true)\n })\n })\n })\n})()</script></body></html>".freeze);
18
+ ;
19
+ ;
20
+ ;
21
+ ;
22
+ ;
23
+ ;
24
+ ;
25
+ ;
26
+ ;
27
+ ;
28
+ ;
29
+ ;
30
+ ;
31
+ ;
32
+ ;
33
+ ;
34
+ ;
35
+ ;
36
+ ;
37
+ ;
38
+ ;
39
+ ;
40
+ ;
41
+ ;
42
+ ;
43
+ ;
44
+ ;
45
+ ;
46
+ ;
47
+ ;
48
+ ;
49
+ ;
50
+ ;
51
+ ;
52
+ ;
53
+ ;
54
+ ;
55
+ ;
56
+ ;
57
+ ;
58
+ ;
59
+ ;
60
+ ;
61
+ ;
62
+ ;
63
+ ;
64
+ ;
65
+ ;
66
+ ;
67
+ ;
68
+ ;
69
+ ;
70
+ ;
71
+ ;
72
+ ;
73
+ ;
74
+ ;
75
+ ;
76
+ ;
77
+ ;
78
+ ;
79
+ ;
80
+ ;
81
+ ;
82
+ ;
83
+ ;
84
+ ;
85
+ ;
86
+ ;
87
+ ;
88
+ ;
89
+ ;
90
+ ;
18
91
  ; _buf