roda 3.59.0 → 3.60.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 963e2d9ac538dbe97835ef65e2e2ba4184838664696bb084ce423a85ef23c205
4
- data.tar.gz: d47a7f9c86357e99b0c9f470b6c33a32962df55189303020982af55d70907c7b
3
+ metadata.gz: 970d646c144f53a89f4f79e9d54b6929b7c10b55b1bbe9b2d5e72aea6a8eb3ae
4
+ data.tar.gz: ec2489d3d668b3abd2787a7f19c13de43c94685dce010d800296eb1194e36e11
5
5
  SHA512:
6
- metadata.gz: c84cb0ae8c66b537c0a7d32d83d9c5a639439b15fbc650d3569efab5e134e0883ba06183c7f17bfb379f4018060c7d276a5016431ae3e21d05c2db3801a85762
7
- data.tar.gz: 0c9495ec5fe24b774512f6495f97f5bb4cf8189b964f21a04c5e880d4a536ade2e045c7131f0a54a7c1cd203fe142d53c6d7cde4cf223a8e8be4cb5c5475fede
6
+ metadata.gz: ccc8d09c535a2c6a92ee314ff295ca5b8756b6c942f3224acbabdc6a92de5bf242a928b296c2e410ecf0bf59470a2143ac2c80d118030db5a2f45fb0cf262a8c
7
+ data.tar.gz: 79114184b64598e3d12d3773c5e7f8d717a05268c63c479758fe3ea1c3c78ccd933531c4e7ef6fd58a6d6af03a150d6e1dde8bf0f27dcc4c0c253482336879f0
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ = 3.60.0 (2022-09-13)
2
+
3
+ * Add link_to plugin with link_to method for creating HTML links (jeremyevans)
4
+
1
5
  = 3.59.0 (2022-08-12)
2
6
 
3
7
  * Add additional_render_engines plugin, for considering multiple render engines for templates (jeremyevans)
@@ -0,0 +1,56 @@
1
+ = New Features
2
+
3
+ * A link_to plugin has been added with a link_to method for
4
+ creating HTML links.
5
+
6
+ The simplest usage of link_to is passing the body and the location
7
+ to link to as strings:
8
+
9
+ # Instance level
10
+ link_to("body", "/path")
11
+ # => "<a href=\"/path\">body</a>"
12
+
13
+ The link_to plugin depends on the path plugin, and allows you to
14
+ pass symbols for named paths:
15
+
16
+ # Class level
17
+ path :foo, "/path/to/too"
18
+
19
+ # Instance level
20
+ link_to("body", :foo)
21
+ # => "<a href=\"/path/to/foo\">body</a>"
22
+
23
+ It also allows you to pass instances of classes that you have
24
+ registered with the path plugin:
25
+
26
+ # Class level
27
+ A = Struct.new(:id)
28
+ path A do
29
+ "/path/to/a/#{id}"
30
+ end
31
+
32
+ # Instance level
33
+ link_to("body", A.new(1))
34
+ # => "<a href=\"/path/to/a/1\">body</a>"
35
+
36
+ To set additional HTML attributes on the tag, you can pass them as
37
+ an options hash:
38
+
39
+ link_to("body", "/path", foo: "bar")
40
+ # => "<a href=\"/path\" foo=\"bar\">body</a>"
41
+
42
+ If the body is nil, it will be set to the same as the path:
43
+
44
+ link_to(nil, "/path")
45
+ # => "<a href=\"/path\">/path</a>"
46
+
47
+ The plugin will automatically HTML escape the path and any HTML
48
+ attribute values, using the h plugin:
49
+
50
+ link_to("body", "/path?a=1&b=2", foo: '"bar"')
51
+ # => "<a href=\"/path?a=1&amp;b=2\" foo=\"&quot;bar&quot;\">body</a>"
52
+
53
+ = Other Improvements
54
+
55
+ * Coverage testing has been expanded to multiple rack versions, instead
56
+ of just the current rack release.
@@ -34,9 +34,7 @@ class Roda
34
34
  module AllVerbs
35
35
  module RequestMethods
36
36
  %w'delete head options link patch put trace unlink'.each do |verb|
37
- # :nocov:
38
37
  if ::Rack::Request.method_defined?("#{verb}?")
39
- # :nocov:
40
38
  class_eval(<<-END, __FILE__, __LINE__+1)
41
39
  def #{verb}(*args, &block)
42
40
  _verb(args, &block) if #{verb}?
@@ -1,8 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- # :nocov:
4
3
  raise LoadError, "disallow_file_uploads plugin not supported on Rack <1.6" if Rack.release < '1.6'
5
- # :nocov:
6
4
 
7
5
  #
8
6
  class Roda
@@ -52,14 +52,12 @@ class Roda
52
52
  end
53
53
 
54
54
  class Params < Rack::QueryParser::Params
55
- # :nocov:
56
- if Rack.release >= '2.3'
55
+ if Rack.release >= '3'
57
56
  def initialize
58
57
  @size = 0
59
58
  @params = Hash.new(&INDIFFERENT_PROC)
60
59
  end
61
60
  else
62
- # :nocov:
63
61
  def initialize(limit = Rack::Utils.key_space_limit)
64
62
  @limit = limit
65
63
  @size = 0
@@ -71,9 +69,7 @@ class Roda
71
69
  end
72
70
 
73
71
  module RequestMethods
74
- # :nocov:
75
- query_parser = Rack.release >= '2.3' ? QueryParser.new(QueryParser::Params, 32) : QueryParser.new(QueryParser::Params, 65536, 32)
76
- # :nocov:
72
+ query_parser = Rack.release >= '3' ? QueryParser.new(QueryParser::Params, 32) : QueryParser.new(QueryParser::Params, 65536, 32)
77
73
  QUERY_PARSER = Rack::Utils.default_query_parser = query_parser
78
74
 
79
75
  private
@@ -89,7 +85,6 @@ class Roda
89
85
  end
90
86
  end
91
87
  else
92
- # :nocov:
93
88
  module InstanceMethods
94
89
  # A copy of the request params that will automatically
95
90
  # convert symbols to strings.
@@ -115,7 +110,6 @@ class Roda
115
110
  end
116
111
  end
117
112
  end
118
- # :nocov:
119
113
  end
120
114
  end
121
115
 
@@ -86,12 +86,10 @@ class Roda
86
86
 
87
87
 
88
88
  # Rack 3 dropped requirement that input be rewindable
89
- if Rack.release >= '2.3'
90
- # :nocov:
89
+ if Rack.release >= '3'
91
90
  def _read_json_input(input)
92
91
  input.read
93
92
  end
94
- # :nocov:
95
93
  else
96
94
  def _read_json_input(input)
97
95
  input.rewind
@@ -0,0 +1,83 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The link_to plugin adds the +link_to+ instance method, which can be used for constructing
7
+ # HTML links (+a+ tag with +href+ attribute).
8
+ #
9
+ # The simplest usage of +link_to+ is passing the body and the location to link to as strings:
10
+ #
11
+ # link_to("body", "/path")
12
+ # # => "<a href=\"/path\">body</a>"
13
+ #
14
+ # The link_to plugin depends on the path plugin, and allows you to pass symbols for named paths:
15
+ #
16
+ # # Class level
17
+ # path :foo, "/path/to/too"
18
+ #
19
+ # # Instance level
20
+ # link_to("body", :foo)
21
+ # # => "<a href=\"/path/to/foo\">body</a>"
22
+ #
23
+ # It also allows you to pass instances of classes that you have registered with the path plugin:
24
+ #
25
+ # # Class level
26
+ # A = Struct.new(:id)
27
+ # path A do
28
+ # "/path/to/a/#{id}"
29
+ # end
30
+ #
31
+ # # Instance level
32
+ # link_to("body", A.new(1))
33
+ # # => "<a href=\"/path/to/a/1\">body</a>"
34
+ #
35
+ # To set additional HTML attributes on the +a+ tag, you can pass them as an options hash:
36
+ #
37
+ # link_to("body", "/path", foo: "bar")
38
+ # # => "<a href=\"/path\" foo=\"bar\">body</a>"
39
+ #
40
+ # If the body is nil, it will be set to the same as the path:
41
+ #
42
+ # link_to(nil, "/path")
43
+ # # => "<a href=\"/path\">/path</a>"
44
+ #
45
+ # The plugin will automatically HTML escape the path and any HTML attribute values, using the h plugin:
46
+ #
47
+ # link_to("body", "/path?a=1&b=2", foo: '"bar"')
48
+ # # => "<a href=\"/path?a=1&amp;b=2\" foo=\"&quot;bar&quot;\">body</a>"
49
+ module LinkTo
50
+ def self.load_dependencies(app)
51
+ app.plugin :h
52
+ app.plugin :path
53
+ end
54
+
55
+ module InstanceMethods
56
+ # Return a string with an HTML +a+ tag with an +href+ attribute. See LinkTo
57
+ # module documentation for details.
58
+ def link_to(body, href, attributes=OPTS)
59
+ case href
60
+ when Symbol
61
+ href = public_send(:"#{href}_path")
62
+ when String
63
+ # nothing
64
+ else
65
+ href = path(href)
66
+ end
67
+
68
+ href = h(href)
69
+
70
+ body = href if body.nil?
71
+
72
+ buf = String.new << "<a href=\"#{href}\""
73
+ attributes.each do |k, v|
74
+ buf << " " << k.to_s << "=\"" << h(v) << "\""
75
+ end
76
+ buf << ">" << body << "</a>"
77
+ end
78
+ end
79
+ end
80
+
81
+ register_plugin(:link_to, LinkTo)
82
+ end
83
+ end
@@ -3,9 +3,7 @@
3
3
  begin
4
4
  require 'rack/files'
5
5
  rescue LoadError
6
- # :nocov:
7
6
  require 'rack/file'
8
- # :nocov:
9
7
  end
10
8
 
11
9
  #
@@ -66,9 +64,7 @@ class Roda
66
64
  # end
67
65
  # end
68
66
  module MultiPublic
69
- # :nocov:
70
67
  RACK_FILES = defined?(Rack::Files) ? Rack::Files : Rack::File
71
- # :nocov:
72
68
 
73
69
  def self.load_dependencies(app, _, opts=OPTS)
74
70
  app.plugin(:public, opts)
@@ -116,9 +116,7 @@ class Roda
116
116
  # arguments, record the verb used. If given an argument, add an is
117
117
  # check with the arguments.
118
118
  %w'get post delete head options link patch put trace unlink'.each do |verb|
119
- # :nocov:
120
119
  if ::Rack::Request.method_defined?("#{verb}?")
121
- # :nocov:
122
120
  class_eval(<<-END, __FILE__, __LINE__+1)
123
121
  def #{verb}(*args, &block)
124
122
  if (empty = args.empty?) && @_is_verbs
@@ -5,9 +5,7 @@ require 'uri'
5
5
  begin
6
6
  require 'rack/files'
7
7
  rescue LoadError
8
- # :nocov:
9
8
  require 'rack/file'
10
- # :nocov:
11
9
  end
12
10
 
13
11
  #
@@ -45,9 +43,7 @@ class Roda
45
43
  module Public
46
44
  SPLIT = Regexp.union(*[File::SEPARATOR, File::ALT_SEPARATOR].compact)
47
45
  PARSER = URI::DEFAULT_PARSER
48
- # :nocov:
49
46
  RACK_FILES = defined?(Rack::Files) ? Rack::Files : Rack::File
50
- # :nocov:
51
47
 
52
48
  # Use options given to setup a Rack::File instance for serving files. Options:
53
49
  # :default_mime :: The default mime type to use if the mime type is not recognized.
@@ -142,13 +138,11 @@ class Roda
142
138
  server.serving(self, path)
143
139
  end
144
140
  else
145
- # :nocov:
146
141
  def public_serve(server, path)
147
142
  server = server.dup
148
143
  server.path = path
149
144
  server.serving(env)
150
145
  end
151
- # :nocov:
152
146
  end
153
147
  end
154
148
  end
@@ -214,18 +214,18 @@ class Roda
214
214
  tilt_compiled_method_support = defined?(Tilt::VERSION) && Tilt::VERSION >= '1.2' &&
215
215
  ([1, -2].include?(((compiled_method_arity = Tilt::Template.instance_method(:compiled_method).arity) rescue false)))
216
216
  NO_CACHE = {:cache=>false}.freeze
217
- COMPILED_METHOD_SUPPORT = RUBY_VERSION >= '2.3' && tilt_compiled_method_support
217
+ COMPILED_METHOD_SUPPORT = RUBY_VERSION >= '2.3' && tilt_compiled_method_support && ENV['RODA_RENDER_COMPILED_METHOD_SUPPORT'] != 'no'
218
218
 
219
219
  if compiled_method_arity == -2
220
220
  def self.tilt_template_compiled_method(template, locals_keys, scope_class)
221
221
  template.send(:compiled_method, locals_keys, scope_class)
222
222
  end
223
+ # :nocov:
223
224
  else
224
- # :nocov:
225
225
  def self.tilt_template_compiled_method(template, locals_keys, scope_class)
226
226
  template.send(:compiled_method, locals_keys)
227
227
  end
228
- # :nocov:
228
+ # :nocov:
229
229
  end
230
230
 
231
231
  # Setup default rendering options. See Render for details.
@@ -366,9 +366,7 @@ class Roda
366
366
  false
367
367
  end
368
368
 
369
- # :nocov:
370
369
  if COMPILED_METHOD_SUPPORT
371
- # :nocov:
372
370
  # Compile a method in the given module with the given name that will
373
371
  # call the compiled template method, updating the compiled template method
374
372
  def define_compiled_method(roda_class, method_name, locals_keys=EMPTY_ARRAY)
@@ -412,9 +410,7 @@ class Roda
412
410
  end
413
411
 
414
412
  module ClassMethods
415
- # :nocov:
416
413
  if COMPILED_METHOD_SUPPORT
417
- # :nocov:
418
414
  # If using compiled methods and there is an optimized layout, speed up
419
415
  # access to the layout method to improve the performance of view.
420
416
  def freeze
@@ -437,9 +433,7 @@ class Roda
437
433
  def inherited(subclass)
438
434
  super
439
435
  opts = subclass.opts[:render] = subclass.opts[:render].dup
440
- # :nocov:
441
436
  if COMPILED_METHOD_SUPPORT
442
- # :nocov:
443
437
  opts[:template_method_cache] = (opts[:cache_class] || RodaCache).new
444
438
  end
445
439
  opts[:cache] = opts[:cache].dup
@@ -459,9 +453,7 @@ class Roda
459
453
  instance = allocate
460
454
  instance.send(:retrieve_template, instance.send(:view_layout_opts, OPTS))
461
455
 
462
- # :nocov:
463
456
  if COMPILED_METHOD_SUPPORT
464
- # :nocov:
465
457
  if (layout_template = render_opts[:optimize_layout]) && !opts[:render][:optimized_layout_method_created]
466
458
  instance.send(:retrieve_template, :template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
467
459
  layout_method = opts[:render][:template_method_cache][:_roda_layout]
@@ -610,7 +602,6 @@ class Roda
610
602
  end
611
603
  end
612
604
  else
613
- # :nocov:
614
605
  def _cached_template_method(_)
615
606
  nil
616
607
  end
@@ -630,7 +621,6 @@ class Roda
630
621
  def _optimized_view_content(template)
631
622
  nil
632
623
  end
633
- # :nocov:
634
624
  end
635
625
 
636
626
 
@@ -109,11 +109,9 @@ class Roda
109
109
  end.join
110
110
  end
111
111
  else
112
- # :nocov:
113
112
  def _cached_render_each_template_method(template)
114
113
  nil
115
114
  end
116
- # :nocov:
117
115
  end
118
116
  end
119
117
  end
@@ -43,9 +43,7 @@ class Roda
43
43
  module InstanceMethods
44
44
  private
45
45
 
46
- # :nocov:
47
46
  if Render::COMPILED_METHOD_SUPPORT
48
- # :nocov:
49
47
  # Disable use of cached templates, since it assumes a render/view call with no
50
48
  # options will have no locals.
51
49
  def _cached_template_method(template)
@@ -4,9 +4,7 @@ require 'rack/mime'
4
4
  begin
5
5
  require 'rack/files'
6
6
  rescue LoadError
7
- # :nocov:
8
7
  require 'rack/file'
9
- # :nocov:
10
8
  end
11
9
 
12
10
 
@@ -225,9 +223,7 @@ class Roda
225
223
  ISO88591_ENCODING = Encoding.find('ISO-8859-1')
226
224
  BINARY_ENCODING = Encoding.find('BINARY')
227
225
 
228
- # :nocov:
229
226
  RACK_FILES = defined?(Rack::Files) ? Rack::Files : Rack::File
230
- # :nocov:
231
227
 
232
228
  # Depend on the status_303 plugin.
233
229
  def self.load_dependencies(app, _opts = nil)
@@ -351,10 +347,8 @@ class Roda
351
347
  s, h, b = if Rack.release > '2'
352
348
  file.serving(self, path)
353
349
  else
354
- # :nocov:
355
350
  file.path = path
356
351
  file.serving(@env)
357
- # :nocov:
358
352
  end
359
353
 
360
354
  res.status = opts[:status] || s
@@ -45,11 +45,9 @@ class Roda
45
45
  when nil, false
46
46
  CLEAR_HEADERS
47
47
  when Array
48
- # :nocov:
49
- if Rack.release >= '2.3'
48
+ if Rack.release >= '3'
50
49
  keep_headers = keep_headers.map(&:downcase)
51
50
  end
52
- # :nocov:
53
51
  lambda{|headers| headers.delete_if{|k,_| !keep_headers.include?(k)}}
54
52
  else
55
53
  raise RodaError, "Invalid :keep_headers option"
@@ -126,9 +126,7 @@ class Roda
126
126
 
127
127
  private
128
128
 
129
- # :nocov:
130
129
  if Render::COMPILED_METHOD_SUPPORT
131
- # :nocov:
132
130
  # Return nil if using custom view or layout options.
133
131
  # If using a view subdir, prefix the template key with the subdir.
134
132
  def _cached_template_method_key(template)
data/lib/roda/request.rb CHANGED
@@ -1,18 +1,16 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- # :nocov:
4
3
  begin
5
4
  require "rack/version"
6
5
  rescue LoadError
7
6
  require "rack"
8
7
  else
9
- if Rack.release >= '2.3'
8
+ if Rack.release >= '3'
10
9
  require "rack/request"
11
10
  else
12
11
  require "rack"
13
12
  end
14
13
  end
15
- # :nocov:
16
14
 
17
15
  require_relative "cache"
18
16
 
@@ -129,8 +127,7 @@ class Roda
129
127
  "#<#{self.class.inspect} #{@env["REQUEST_METHOD"]} #{path}>"
130
128
  end
131
129
 
132
- # :nocov:
133
- if Rack.release >= '2.3'
130
+ if Rack.release >= '3'
134
131
  def http_version
135
132
  # Prefer SERVER_PROTOCOL as it is required in Rack 3.
136
133
  # Still fall back to HTTP_VERSION if SERVER_PROTOCOL
@@ -139,7 +136,6 @@ class Roda
139
136
  @env['SERVER_PROTOCOL'] || @env['HTTP_VERSION']
140
137
  end
141
138
  else
142
- # :nocov:
143
139
  # What HTTP version the request was submitted with.
144
140
  def http_version
145
141
  # Prefer HTTP_VERSION as it is backwards compatible
data/lib/roda/response.rb CHANGED
@@ -42,7 +42,6 @@ class Roda
42
42
  # code for non-empty responses and a 404 code for empty responses.
43
43
  attr_accessor :status
44
44
 
45
- # :nocov:
46
45
  if defined?(Rack::Headers) && Rack::Headers.is_a?(Class)
47
46
  # Set the default headers when creating a response.
48
47
  def initialize
@@ -51,7 +50,6 @@ class Roda
51
50
  @length = 0
52
51
  end
53
52
  else
54
- # :nocov:
55
53
  # Set the default headers when creating a response.
56
54
  def initialize
57
55
  @headers = {}
@@ -173,7 +171,6 @@ class Roda
173
171
 
174
172
  private
175
173
 
176
- # :nocov:
177
174
  if Rack.release < '2.0.2'
178
175
  # Don't use a content length for empty 205 responses on
179
176
  # rack 1, as it violates Rack::Lint in that version.
@@ -181,7 +178,6 @@ class Roda
181
178
  headers.delete("Content-Type")
182
179
  headers.delete("Content-Length")
183
180
  end
184
- # :nocov:
185
181
  else
186
182
  # Set the content length for empty 205 responses to 0
187
183
  def empty_205_headers(headers)
data/lib/roda/version.rb CHANGED
@@ -4,7 +4,7 @@ class Roda
4
4
  RodaMajorVersion = 3
5
5
 
6
6
  # The minor version of Roda, updated for new feature releases of Roda.
7
- RodaMinorVersion = 59
7
+ RodaMinorVersion = 60
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.59.0
4
+ version: 3.60.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-12 00:00:00.000000000 Z
11
+ date: 2022-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -232,6 +232,7 @@ extra_rdoc_files:
232
232
  - doc/release_notes/3.58.0.txt
233
233
  - doc/release_notes/3.59.0.txt
234
234
  - doc/release_notes/3.6.0.txt
235
+ - doc/release_notes/3.60.0.txt
235
236
  - doc/release_notes/3.7.0.txt
236
237
  - doc/release_notes/3.8.0.txt
237
238
  - doc/release_notes/3.9.0.txt
@@ -298,6 +299,7 @@ files:
298
299
  - doc/release_notes/3.58.0.txt
299
300
  - doc/release_notes/3.59.0.txt
300
301
  - doc/release_notes/3.6.0.txt
302
+ - doc/release_notes/3.60.0.txt
301
303
  - doc/release_notes/3.7.0.txt
302
304
  - doc/release_notes/3.8.0.txt
303
305
  - doc/release_notes/3.9.0.txt
@@ -359,6 +361,7 @@ files:
359
361
  - lib/roda/plugins/inject_erb.rb
360
362
  - lib/roda/plugins/json.rb
361
363
  - lib/roda/plugins/json_parser.rb
364
+ - lib/roda/plugins/link_to.rb
362
365
  - lib/roda/plugins/mail_processor.rb
363
366
  - lib/roda/plugins/mailer.rb
364
367
  - lib/roda/plugins/match_affix.rb