roda 3.88.0 → 3.90.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/lib/roda/plugins/common_logger.rb +4 -3
- data/lib/roda/plugins/mailer.rb +6 -0
- data/lib/roda/plugins/middleware.rb +1 -3
- data/lib/roda/plugins/module_include.rb +1 -0
- data/lib/roda/plugins/part.rb +76 -0
- data/lib/roda/plugins/render.rb +52 -14
- data/lib/roda/plugins/sinatra_helpers.rb +1 -3
- data/lib/roda/plugins/symbol_views.rb +4 -1
- data/lib/roda/plugins/view_options.rb +1 -1
- data/lib/roda/plugins.rb +15 -0
- data/lib/roda/session_middleware.rb +1 -0
- data/lib/roda/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c42c5f4d45d0f7fe64602e9d2a32bec3c690606c98709f7bd0bde537dd7a6463
|
4
|
+
data.tar.gz: c5f4edfdf88244770bd0184220df443ea5183c017f11c7342b4192db158d8d6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19ccf7e44d75f36bc372f2dcad01bb9bf23831c12397d142ea94d1e5f10d0cfe1be3f62f8f45e584ab9e4d0510c8d6acba7dd13e5d9df0680dece3838a43f5a6
|
7
|
+
data.tar.gz: 48e7c8fc21d75df1adfb616fa5fa88c2b410b290168b2fa1b14ab2c53f8f33167e039f310007dc19831e0571c4ce2b2d34c023b8b88c07d4ff666afe4b426ce9
|
@@ -56,14 +56,15 @@ class Roda
|
|
56
56
|
|
57
57
|
env = @_request.env
|
58
58
|
|
59
|
-
line = "#{env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-"} - #{env["REMOTE_USER"] || "-"} [#{Time.now.strftime("%d/%b/%Y:%H:%M:%S %z")}] \"#{env["REQUEST_METHOD"]} #{env["SCRIPT_NAME"]}#{env["PATH_INFO"]}#{"?#{env["QUERY_STRING"]}" if ((qs = env["QUERY_STRING"]) && !qs.empty?)} #{@_request.http_version}\" #{status} #{((length = headers[RodaResponseHeaders::CONTENT_LENGTH]) && (length unless length == '0')) || '-'} #{elapsed_time}
|
59
|
+
line = "#{env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-"} - #{env["REMOTE_USER"] || "-"} [#{Time.now.strftime("%d/%b/%Y:%H:%M:%S %z")}] \"#{env["REQUEST_METHOD"]} #{env["SCRIPT_NAME"]}#{env["PATH_INFO"]}#{"?#{env["QUERY_STRING"]}" if ((qs = env["QUERY_STRING"]) && !qs.empty?)} #{@_request.http_version}\" #{status} #{((length = headers[RodaResponseHeaders::CONTENT_LENGTH]) && (length unless length == '0')) || '-'} #{elapsed_time} "
|
60
60
|
if MUTATE_LINE
|
61
|
-
line.gsub!(/[^[:print:]
|
61
|
+
line.gsub!(/[^[:print:]]/){|c| sprintf("\\x%x", c.ord)}
|
62
62
|
# :nocov:
|
63
63
|
else
|
64
|
-
line = line.gsub(/[^[:print:]
|
64
|
+
line = line.gsub(/[^[:print:]]/){|c| sprintf("\\x%x", c.ord)}
|
65
65
|
# :nocov:
|
66
66
|
end
|
67
|
+
line[-1] = "\n"
|
67
68
|
opts[:common_logger_meth].call(line)
|
68
69
|
end
|
69
70
|
|
data/lib/roda/plugins/mailer.rb
CHANGED
@@ -151,6 +151,9 @@ class Roda
|
|
151
151
|
mail
|
152
152
|
end
|
153
153
|
end
|
154
|
+
# :nocov:
|
155
|
+
ruby2_keywords(:mail) if respond_to?(:ruby2_keywords, true)
|
156
|
+
# :nocov:
|
154
157
|
|
155
158
|
# Calls +mail+ with given arguments and immediately sends the resulting mail.
|
156
159
|
def sendmail(*args)
|
@@ -158,6 +161,9 @@ class Roda
|
|
158
161
|
m.deliver
|
159
162
|
end
|
160
163
|
end
|
164
|
+
# :nocov:
|
165
|
+
ruby2_keywords(:sendmail) if respond_to?(:ruby2_keywords, true)
|
166
|
+
# :nocov:
|
161
167
|
end
|
162
168
|
|
163
169
|
module RequestMethods
|
@@ -134,9 +134,7 @@ class Roda
|
|
134
134
|
# and store +app+ as the next middleware to call.
|
135
135
|
def initialize(mid, app, *args, &block)
|
136
136
|
@mid = Class.new(mid)
|
137
|
-
#
|
138
|
-
@mid.set_temporary_name("#{mid.name}(middleware)") if mid.name && RUBY_VERSION >= "3.3"
|
139
|
-
# :nocov:
|
137
|
+
RodaPlugins.set_temp_name(@mid){"#{mid}::middleware_subclass"}
|
140
138
|
if @mid.opts[:middleware_next_if_not_found]
|
141
139
|
@mid.plugin(:not_found, &NEXT_PROC)
|
142
140
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
class Roda
|
5
|
+
module RodaPlugins
|
6
|
+
# The part plugin adds a part method, which is a
|
7
|
+
# render-like method that treats all keywords as locals.
|
8
|
+
#
|
9
|
+
# # Can replace this:
|
10
|
+
# render(:template, locals: {foo: 'bar'})
|
11
|
+
#
|
12
|
+
# # With this:
|
13
|
+
# part(:template, foo: 'bar')
|
14
|
+
#
|
15
|
+
# On Ruby 2.7+, the part method takes a keyword splat, so you
|
16
|
+
# must pass keywords and not a positional hash for the locals.
|
17
|
+
#
|
18
|
+
# If you are using the :assume_fixed_locals render plugin option,
|
19
|
+
# template caching is enabled, you are using Ruby 3+, and you
|
20
|
+
# are freezing your Roda application, in addition to providing a
|
21
|
+
# simpler API, this also provides a significant performance
|
22
|
+
# improvement (more significant on Ruby 3.4+).
|
23
|
+
module Part
|
24
|
+
def self.load_dependencies(app)
|
25
|
+
app.plugin :render
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
# When freezing, optimize the part method if assuming fixed locals
|
30
|
+
# and caching templates.
|
31
|
+
def freeze
|
32
|
+
if render_opts[:assume_fixed_locals] && !render_opts[:check_template_mtime]
|
33
|
+
include AssumeFixedLocalsInstanceMethods
|
34
|
+
end
|
35
|
+
|
36
|
+
super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module InstanceMethods
|
41
|
+
if RUBY_VERSION >= '2.7'
|
42
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
43
|
+
def part(template, **locals, &block)
|
44
|
+
render(template, :locals=>locals, &block)
|
45
|
+
end
|
46
|
+
RUBY
|
47
|
+
# :nocov:
|
48
|
+
else
|
49
|
+
def part(template, locals=OPTS, &block)
|
50
|
+
render(template, :locals=>locals, &block)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
# :nocov:
|
54
|
+
end
|
55
|
+
|
56
|
+
module AssumeFixedLocalsInstanceMethods
|
57
|
+
# :nocov:
|
58
|
+
if RUBY_VERSION >= '3.0'
|
59
|
+
# :nocov:
|
60
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
61
|
+
def part(template, ...)
|
62
|
+
if optimized_method = _optimized_render_method_for_locals(template, OPTS)
|
63
|
+
send(optimized_method[0], ...)
|
64
|
+
else
|
65
|
+
super
|
66
|
+
end
|
67
|
+
end
|
68
|
+
RUBY
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
register_plugin(:part, Part)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
data/lib/roda/plugins/render.rb
CHANGED
@@ -48,6 +48,9 @@ class Roda
|
|
48
48
|
#
|
49
49
|
# :allowed_paths :: Set the template paths to allow. Attempts to render paths outside
|
50
50
|
# of these paths will raise an error. Defaults to the +:views+ directory.
|
51
|
+
# :assume_fixed_locals :: Set if you are sure all templates in your application use fixed locals
|
52
|
+
# to allow for additional optimization. This is ignored unless both
|
53
|
+
# compiled methods and fixed locals are not supported.
|
51
54
|
# :cache :: nil/false to explicitly disable permanent template caching. By default, permanent
|
52
55
|
# template caching is disabled by default if RACK_ENV is development. When permanent
|
53
56
|
# template caching is disabled, for templates with paths in the file system, the
|
@@ -155,6 +158,11 @@ class Roda
|
|
155
158
|
# were passed, instead of showing that the takes no arguments (if you use <tt>'()'</tt>),
|
156
159
|
# or that no keywords are accepted (if you pass <tt>(**nil)</tt>).
|
157
160
|
#
|
161
|
+
# If you are sure your application works with all templates using fixed locals,
|
162
|
+
# set the :assume_fixed_locals render plugin option, which will allow the plugin
|
163
|
+
# to optimize cache lookup for renders with locals, and avoid duplicate compiled
|
164
|
+
# methods for templates rendered both with and without locals.
|
165
|
+
#
|
158
166
|
# See Tilt's documentation for more information regarding fixed locals.
|
159
167
|
#
|
160
168
|
# = Speeding Up Template Rendering
|
@@ -175,7 +183,9 @@ class Roda
|
|
175
183
|
# Here are the recommended values of :template_opts for new applications (a couple
|
176
184
|
# are Erubi-specific and can be ignored if you are using other templates engines):
|
177
185
|
#
|
178
|
-
# plugin :render,
|
186
|
+
# plugin :render,
|
187
|
+
# assume_fixed_locals: true, # Optimize plugin by assuming all templates use fixed locals
|
188
|
+
# template_opts: {
|
179
189
|
# scope_class: self, # Always uses current class as scope class for compiled templates
|
180
190
|
# freeze: true, # Freeze string literals in templates
|
181
191
|
# extract_fixed_locals: true, # Support fixed locals in templates
|
@@ -324,6 +334,7 @@ class Roda
|
|
324
334
|
opts[:allowed_paths] ||= [opts[:views]].freeze
|
325
335
|
opts[:allowed_paths] = opts[:allowed_paths].map{|f| app.expand_path(f, nil)}.uniq.freeze
|
326
336
|
opts[:check_paths] = true unless opts.has_key?(:check_paths)
|
337
|
+
opts[:assume_fixed_locals] &&= FIXED_LOCALS_COMPILED_METHOD_SUPPORT
|
327
338
|
|
328
339
|
unless opts.has_key?(:check_template_mtime)
|
329
340
|
opts[:check_template_mtime] = if opts[:cache] == false || opts[:explicit_cache]
|
@@ -531,6 +542,12 @@ class Roda
|
|
531
542
|
nil
|
532
543
|
end
|
533
544
|
|
545
|
+
# Optimize _call_optimized_template_method if you know all templates
|
546
|
+
# are going to be using fixed locals.
|
547
|
+
if render_opts[:assume_fixed_locals] && !render_opts[:check_template_mtime]
|
548
|
+
include AssumeFixedLocalsInstanceMethods
|
549
|
+
end
|
550
|
+
|
534
551
|
super
|
535
552
|
end
|
536
553
|
end
|
@@ -673,21 +690,29 @@ class Roda
|
|
673
690
|
# of the template render if the optimized path is used, or nil if the optimized
|
674
691
|
# path is not used and the long method needs to be used.
|
675
692
|
def _optimized_render_method_for_locals(template, locals)
|
693
|
+
render_opts = self.render_opts
|
676
694
|
return unless method_cache = render_opts[:template_method_cache]
|
677
695
|
|
678
696
|
case template
|
679
697
|
when String, Symbol
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
698
|
+
if fixed_locals = render_opts[:assume_fixed_locals]
|
699
|
+
key = template
|
700
|
+
if optimized_template = _cached_template_method_lookup(method_cache, key)
|
701
|
+
return optimized_template
|
702
|
+
end
|
703
|
+
else
|
704
|
+
key = [:_render_locals, template]
|
705
|
+
if optimized_template = _cached_template_method_lookup(method_cache, key)
|
706
|
+
# Fixed locals case
|
707
|
+
return optimized_template
|
708
|
+
end
|
685
709
|
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
710
|
+
locals_keys = locals.keys.sort
|
711
|
+
key << locals_keys
|
712
|
+
if optimized_template = _cached_template_method_lookup(method_cache, key)
|
713
|
+
# Regular locals case
|
714
|
+
return optimized_template
|
715
|
+
end
|
691
716
|
end
|
692
717
|
else
|
693
718
|
return
|
@@ -695,9 +720,10 @@ class Roda
|
|
695
720
|
|
696
721
|
if method_cache_key = _cached_template_method_key(key)
|
697
722
|
template_obj = retrieve_template(render_template_opts(template, NO_CACHE))
|
698
|
-
|
699
|
-
|
700
|
-
|
723
|
+
unless fixed_locals
|
724
|
+
key.pop if fixed_locals = Render.tilt_template_fixed_locals?(template_obj)
|
725
|
+
key.freeze
|
726
|
+
end
|
701
727
|
method_name = :"_roda_template_locals_#{self.class.object_id}_#{method_cache_key}"
|
702
728
|
|
703
729
|
method_cache[method_cache_key] = case template_obj
|
@@ -953,6 +979,18 @@ class Roda
|
|
953
979
|
end
|
954
980
|
end
|
955
981
|
end
|
982
|
+
|
983
|
+
module AssumeFixedLocalsInstanceMethods
|
984
|
+
# :nocov:
|
985
|
+
if RUBY_VERSION >= '3.0'
|
986
|
+
# :nocov:
|
987
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
988
|
+
def _call_optimized_template_method((meth,_), locals, &block)
|
989
|
+
send(meth, **locals, &block)
|
990
|
+
end
|
991
|
+
RUBY
|
992
|
+
end
|
993
|
+
end
|
956
994
|
end
|
957
995
|
|
958
996
|
register_plugin(:render, Render)
|
@@ -354,9 +354,7 @@ class Roda
|
|
354
354
|
res.status = opts[:status] || s
|
355
355
|
headers.delete(RodaResponseHeaders::CONTENT_LENGTH)
|
356
356
|
headers.replace(h.merge!(headers))
|
357
|
-
res.
|
358
|
-
|
359
|
-
halt
|
357
|
+
halt res.finish_with_body(b)
|
360
358
|
rescue Errno::ENOENT
|
361
359
|
not_found
|
362
360
|
end
|
@@ -23,8 +23,11 @@ class Roda
|
|
23
23
|
# :foo
|
24
24
|
# end
|
25
25
|
module SymbolViews
|
26
|
-
def self.
|
26
|
+
def self.load_dependencies(app)
|
27
27
|
app.plugin :custom_block_results
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.configure(app)
|
28
31
|
app.opts[:custom_block_results][Symbol] = :view
|
29
32
|
end
|
30
33
|
end
|
data/lib/roda/plugins.rb
CHANGED
@@ -49,5 +49,20 @@ class Roda
|
|
49
49
|
end
|
50
50
|
# :nocov:
|
51
51
|
end
|
52
|
+
|
53
|
+
if RUBY_VERSION >= '3.3'
|
54
|
+
# Create a new module using the block, and set the temporary name
|
55
|
+
# on it using the given a containing module and name.
|
56
|
+
def self.set_temp_name(mod)
|
57
|
+
mod.set_temporary_name(yield)
|
58
|
+
mod
|
59
|
+
end
|
60
|
+
# :nocov:
|
61
|
+
else
|
62
|
+
def self.set_temp_name(mod)
|
63
|
+
mod
|
64
|
+
end
|
65
|
+
end
|
66
|
+
# :nocov:
|
52
67
|
end
|
53
68
|
end
|
@@ -159,6 +159,7 @@ class RodaSessionMiddleware
|
|
159
159
|
# Setup the middleware, passing +opts+ as the Roda sessions plugin options.
|
160
160
|
def initialize(app, opts)
|
161
161
|
mid = Class.new(Roda)
|
162
|
+
Roda::RodaPlugins.set_temp_name(mid){"RodaSessionMiddleware::_RodaSubclass"}
|
162
163
|
mid.plugin :sessions, opts
|
163
164
|
@req_class = mid::RodaRequest
|
164
165
|
@req_class.send(:include, RequestMethods)
|
data/lib/roda/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.90.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-03-11 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rack
|
@@ -253,6 +253,7 @@ files:
|
|
253
253
|
- lib/roda/plugins/padrino_render.rb
|
254
254
|
- lib/roda/plugins/param_matchers.rb
|
255
255
|
- lib/roda/plugins/params_capturing.rb
|
256
|
+
- lib/roda/plugins/part.rb
|
256
257
|
- lib/roda/plugins/partials.rb
|
257
258
|
- lib/roda/plugins/pass.rb
|
258
259
|
- lib/roda/plugins/path.rb
|