roda 3.59.0 → 3.60.0

Sign up to get free protection for your applications and to get access to all the features.
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