roda 3.63.0 → 3.65.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: 6e19674abcd02c79572ada44fe13fc8188a4cc91b780a3fbaa39da206cf7457f
4
- data.tar.gz: ffd0e850b4aab5e82b3f5cf307145853df9d420389ff8eb6170ec53d3e29ca57
3
+ metadata.gz: d1c9c4301b4c90cb2f2c7a2d190986b4b6c68c4e1eb4b0be59bdba2aebdf6780
4
+ data.tar.gz: 576b15ba70cdab634638bce683ba8ee8ac93feb9fe5f3ae8982cf6ae07c6d686
5
5
  SHA512:
6
- metadata.gz: d91087a996b037de3c0ecc3ca5e029f6b4bb40c5da1618048d70c0aa42ac5dcc581b6ed67e55cd9236da5463c3c224c62b09f85797daeffcb9a8fb98a16bca03
7
- data.tar.gz: 62d2e2fdb0efa867299a764d4f7b36fc1a1e680147d32703d29451e29d2e3090a0f337c2c87ac46929a5a504b6461f92d18b50a14c62f422de4c114e43892c91
6
+ metadata.gz: 91b24c2bbcb2d2c27c14f242d620fab9d5e838f68bc102887018e41e4e05f5eb93718ab312c727a32ac4ab6df0dbcf4d0bb134499674dee71e991e953ecac85b
7
+ data.tar.gz: 9fe4592c67425c171926368d1121841dcafae686eb6822439536c24040788049041f34dffae22fde1ba2905f63c0e3abd13a5938ea263f4b143fdb94219e66f1
data/CHANGELOG CHANGED
@@ -1,3 +1,19 @@
1
+ = 3.65.0 (2023-02-13)
2
+
3
+ * Make indifferent_params plugin work with changes in rack main branch (jeremyevans)
4
+
5
+ * Add autoload_named_routes plugin for autoloading file for a named route when there is a request for that route (jeremyevans)
6
+
7
+ * Make path method in path plugin accept class name string/symbol with :class_name option to register classes without forcing autoloads (jeremyevans)
8
+
9
+ = 3.64.0 (2023-01-12)
10
+
11
+ * Automatically expand paths for autoload_hash_branches files, so that relative paths work (jeremyevans)
12
+
13
+ * Make autoload_hash_branches plugin eagerly load the branches when freezing the application (jeremyevans)
14
+
15
+ * Add erb_h plugin for faster (if slightly less safe) html escaping using erb/escape (jeremyevans)
16
+
1
17
  = 3.63.0 (2022-12-16)
2
18
 
3
19
  * Make mailer plugin set configured content type for body part for emails with attachments when using mail 2.8+ (jeremyevans)
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2022 Jeremy Evans
1
+ Copyright (c) 2014-2023 Jeremy Evans
2
2
  Copyright (c) 2010-2014 Michel Martens, Damian Janowski and Cyril David
3
3
  Copyright (c) 2008-2009 Christian Neukirchen
4
4
 
@@ -0,0 +1,26 @@
1
+ = New Features
2
+
3
+ * An erb_h plugin has been added for faster HTML escaping using
4
+ erb/escape. erb 4 added erb/escape and it is included in Ruby 3.2.
5
+
6
+ The erb_h plugin is added as a separate plugin because it changes
7
+ the behavior of the h method. The h method added by the h plugin
8
+ will always return a new string, but the h method added by the
9
+ erb_h plugin will return the argument if the argument is a
10
+ string that does not need escaping. By avoiding unnecessary
11
+ string allocations, use of the erb_h plugin can speed up HTML
12
+ escaping.
13
+
14
+ = Other Improvements
15
+
16
+ * The autoload_hash_branches plugin added in Roda 3.63.0 will now
17
+ eagerly load the hash branches when freezing the application,
18
+ allowing the application to continue to work after being frozen.
19
+ Additionally, file paths for the hash branches will now be
20
+ automatically expanded, allowing the use of relative file paths.
21
+
22
+ = Backwards Compatibility
23
+
24
+ * The expanding of file paths in the autoload_hash_branches plugin
25
+ can break applications that were providing relative paths and
26
+ expecting them to be looked up using the Ruby load path.
@@ -0,0 +1,12 @@
1
+ = New Features
2
+
3
+ * An autoload_named_routes plugin has been added for autoloading files
4
+ for a named route setup by the named_routes plugin when there is a
5
+ request for that route.
6
+
7
+ = Other Improvements
8
+
9
+ * The path method in the path plugin now supports a :class_name option.
10
+ You can set this option to true and use a class name String/Symbol
11
+ to register paths for classes without referencing the related class,
12
+ useful when autoloading the class.
@@ -13,8 +13,8 @@ class Roda
13
13
  # You can specify a single hash branch for autoloading:
14
14
  #
15
15
  # plugin :autoload_hash_branches
16
- # autoload_hash_branch('branch_name', '/path/to/file')
17
- # autoload_hash_branch('namespace', 'branch_name', '/path/to/file')
16
+ # autoload_hash_branch('branch_name', '/absolute/path/to/file')
17
+ # autoload_hash_branch('namespace', 'branch_name', 'relative/path/to/file')
18
18
  #
19
19
  # You can also set the plugin to autoload load all hash branch files in a given directory.
20
20
  # This will look at each .rb file in the directory, and add an autoload for it, using the
@@ -26,18 +26,24 @@ class Roda
26
26
  # In both cases, when the autoloaded file is required, it should redefine the same
27
27
  # hash branch. If it does not, requests to the hash branch will result in a 404 error.
28
28
  #
29
- # This plugin will not work correctly when freezing applications, because it requires
30
- # modifying the class at runtime as hash branches are autoloaded.
29
+ # When freezing an application, all hash branches are automatically loaded, because
30
+ # autoloading hash branches does not work for frozen applications.
31
31
  module AutoloadHashBranches
32
32
  def self.load_dependencies(app)
33
33
  app.plugin :hash_branches
34
34
  end
35
35
 
36
+ def self.configure(app)
37
+ app.opts[:autoload_hash_branch_files] ||= []
38
+ end
39
+
36
40
  module ClassMethods
37
41
  # Autoload the given file when there is request for the hash branch.
38
42
  # The given file should configure the hash branch specified.
39
43
  def autoload_hash_branch(namespace='', segment, file)
40
44
  segment = "/#{segment}"
45
+ file = File.expand_path(file)
46
+ opts[:autoload_hash_branch_files] << file
41
47
  routes = opts[:hash_branches][namespace] ||= {}
42
48
  meth = routes[segment] = define_roda_method(routes[segment] || "hash_branch_#{namespace}_#{segment}", 1) do |r|
43
49
  loc = method(routes[segment]).source_location
@@ -59,6 +65,12 @@ class Roda
59
65
  end
60
66
  end
61
67
  end
68
+
69
+ # Eagerly load all hash branches when freezing the application.
70
+ def freeze
71
+ opts.delete(:autoload_hash_branch_files).each{|file| require file}
72
+ super
73
+ end
62
74
  end
63
75
  end
64
76
 
@@ -0,0 +1,65 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The autoload_named_routes plugin builds on the named_routes plugin and allows for
7
+ # delaying loading of a file containing a named route for an application until there
8
+ # is a request that uses the named route. This can be useful in development
9
+ # to improvement startup time by not loading all named routes up front. It can also be
10
+ # useful in testing subsets of an application by only loading the named routes being
11
+ # tested.
12
+ #
13
+ # You can specify a single hash branch for autoloading:
14
+ #
15
+ # plugin :autoload_named_route
16
+ # autoload_named_route(:route_name, '/absolute/path/to/file')
17
+ # autoload_named_route(:namespace, :route_name, 'relative/path/to/file')
18
+ #
19
+ # Note that unlike the +route+ method defined by the named_routes plugin, when providing
20
+ # a namespace, the namespace comes before the route name and not after.
21
+ #
22
+ # When the autoloaded file is required, it should redefine the same
23
+ # named route. If it does not, requests to the named route will be ignored (as if the
24
+ # related named route block was empty).
25
+ #
26
+ # When freezing an application, all named routes are automatically loaded, because
27
+ # autoloading named routes does not work for frozen applications.
28
+ module AutoloadNamedRoutes
29
+ def self.load_dependencies(app)
30
+ app.plugin :named_routes
31
+ end
32
+
33
+ def self.configure(app)
34
+ app.opts[:autoload_named_route_files] ||= []
35
+ end
36
+
37
+ module ClassMethods
38
+ # Autoload the given file when there is request for the named route.
39
+ # The given file should configure the named route specified.
40
+ def autoload_named_route(namespace=nil, name, file)
41
+ file = File.expand_path(file)
42
+ opts[:autoload_named_route_files] << file
43
+ routes = opts[:namespaced_routes][namespace] ||= {}
44
+ meth = routes[name] = define_roda_method(routes[name] || "named_routes_#{namespace}_#{name}", 1) do |r|
45
+ loc = method(routes[name]).source_location
46
+ require file
47
+ # Avoid infinite loop in case method is not overridden
48
+ if method(meth).source_location != loc
49
+ send(meth, r)
50
+ end
51
+ end
52
+ nil
53
+ end
54
+
55
+ # Eagerly load all autoloaded named routes when freezing the application.
56
+ def freeze
57
+ opts.delete(:autoload_named_route_files).each{|file| require file}
58
+ super
59
+ end
60
+ end
61
+ end
62
+
63
+ register_plugin(:autoload_named_routes, AutoloadNamedRoutes)
64
+ end
65
+ end
@@ -0,0 +1,43 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'erb/escape'
4
+
5
+ #
6
+ class Roda
7
+ module RodaPlugins
8
+ # The erb_h plugin adds an +h+ instance method that will HTML
9
+ # escape the input and return it. This is similar to the h
10
+ # plugin, but it uses erb/escape to implement the HTML escaping,
11
+ # which offers faster performance.
12
+ #
13
+ # To make sure that this speeds up applications using the h
14
+ # plugin, this depends on the h plugin, and overrides the
15
+ # h method.
16
+ #
17
+ # The following example will return "&lt;foo&gt;" as the body.
18
+ #
19
+ # plugin :erb_h
20
+ #
21
+ # route do |r|
22
+ # h('<foo>')
23
+ # end
24
+ #
25
+ # The faster performance offered by the erb_h plugin is due
26
+ # to erb/escape avoiding allocations if not needed (returning the
27
+ # input object if no escaping is needed). That behavior change
28
+ # can cause problems if you mutate the result of the h method
29
+ # (which can mutate the input), or mutate the input of the h
30
+ # method after calling it (which can mutate the result).
31
+ module ErbH
32
+ def self.load_dependencies(app)
33
+ app.plugin :h
34
+ end
35
+
36
+ module InstanceMethods
37
+ define_method(:h, ERB::Escape.instance_method(:html_escape))
38
+ end
39
+ end
40
+
41
+ register_plugin(:erb_h, ErbH)
42
+ end
43
+ end
@@ -401,7 +401,6 @@ END
401
401
 
402
402
  private
403
403
 
404
- # :nocov:
405
404
  if RUBY_VERSION >= '3.2'
406
405
  def exception_page_exception_message(exception)
407
406
  exception.detailed_message(highlight: false).to_s
@@ -413,6 +412,7 @@ END
413
412
  exception.message.to_s
414
413
  end
415
414
  end
415
+ # :nocov:
416
416
  end
417
417
 
418
418
  module RequestMethods
@@ -53,9 +53,18 @@ class Roda
53
53
 
54
54
  class Params < Rack::QueryParser::Params
55
55
  if Rack.release >= '3'
56
- def initialize
57
- @size = 0
58
- @params = Hash.new(&INDIFFERENT_PROC)
56
+ # rack main branch compatibility
57
+ # :nocov:
58
+ if Params < Hash
59
+ def initialize
60
+ super(&INDIFFERENT_PROC)
61
+ end
62
+ # :nocov:
63
+ else
64
+ def initialize
65
+ @size = 0
66
+ @params = Hash.new(&INDIFFERENT_PROC)
67
+ end
59
68
  end
60
69
  else
61
70
  def initialize(limit = Rack::Utils.key_space_limit)
@@ -26,6 +26,9 @@ class Roda
26
26
  # path Quux do |quux, path|
27
27
  # "/quux/#{quux.id}/#{path}"
28
28
  # end
29
+ # path 'FooBar', class_name: true do |foobar|
30
+ # "/foobar/#{foobar.id}"
31
+ # end
29
32
  #
30
33
  # route do |r|
31
34
  # r.post 'foo' do
@@ -65,9 +68,18 @@ class Roda
65
68
  #
66
69
  # Note that if :add_script_name, :relative, :url, or :url_only is used, the path method will also create a
67
70
  # <tt>_*_path</tt> private method.
71
+ #
72
+ # If the path class method is passed a string or symbol as the first argument, and the second argument
73
+ # is a hash with the :class_name option passed, the symbol/string is treated as a class name.
74
+ # This enables the use of class-based paths without forcing autoloads for the related
75
+ # classes. If the plugin is not registering classes by name, this will use the symbol or
76
+ # string to find the related class.
68
77
  module Path
69
78
  DEFAULT_PORTS = {'http' => 80, 'https' => 443}.freeze
70
79
 
80
+ # Regexp for valid constant names, to prevent code execution.
81
+ VALID_CONSTANT_NAME_REGEXP = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.freeze
82
+
71
83
  # Initialize the path classes when loading the plugin. Options:
72
84
  # :by_name :: Register classes by name, which is friendlier when reloading code (defaults to
73
85
  # true in development mode)
@@ -97,11 +109,20 @@ class Roda
97
109
 
98
110
  # Create a new instance method for the named path. See plugin module documentation for options.
99
111
  def path(name, path=nil, opts=OPTS, &block)
100
- if name.is_a?(Class)
101
- raise RodaError, "can't provide path or options when calling path with a class" unless path.nil? && opts.empty?
112
+ if name.is_a?(Class) || (path.is_a?(Hash) && (class_name = path[:class_name]))
113
+ raise RodaError, "can't provide path when calling path with a class" if path && !class_name
114
+ raise RodaError, "can't provide options when calling path with a class" unless opts.empty?
102
115
  raise RodaError, "must provide a block when calling path with a class" unless block
103
116
  if self.opts[:path_class_by_name]
104
- name = name.name
117
+ if class_name
118
+ name = name.to_s
119
+ else
120
+ name = name.name
121
+ end
122
+ elsif class_name
123
+ name = name.to_s
124
+ raise RodaError, "invalid class name passed when using class_name option" unless VALID_CONSTANT_NAME_REGEXP =~ name
125
+ name = Object.class_eval(name, __FILE__, __LINE__)
105
126
  end
106
127
  path_classes[name] = block
107
128
  self.opts[:path_class_methods][name] = define_roda_method("path_#{name}", :any, &block)
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 = 63
7
+ RodaMinorVersion = 65
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.63.0
4
+ version: 3.65.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-12-16 00:00:00.000000000 Z
11
+ date: 2023-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -236,6 +236,8 @@ extra_rdoc_files:
236
236
  - doc/release_notes/3.61.0.txt
237
237
  - doc/release_notes/3.62.0.txt
238
238
  - doc/release_notes/3.63.0.txt
239
+ - doc/release_notes/3.64.0.txt
240
+ - doc/release_notes/3.65.0.txt
239
241
  - doc/release_notes/3.7.0.txt
240
242
  - doc/release_notes/3.8.0.txt
241
243
  - doc/release_notes/3.9.0.txt
@@ -306,6 +308,8 @@ files:
306
308
  - doc/release_notes/3.61.0.txt
307
309
  - doc/release_notes/3.62.0.txt
308
310
  - doc/release_notes/3.63.0.txt
311
+ - doc/release_notes/3.64.0.txt
312
+ - doc/release_notes/3.65.0.txt
309
313
  - doc/release_notes/3.7.0.txt
310
314
  - doc/release_notes/3.8.0.txt
311
315
  - doc/release_notes/3.9.0.txt
@@ -323,6 +327,7 @@ files:
323
327
  - lib/roda/plugins/assets.rb
324
328
  - lib/roda/plugins/assets_preloading.rb
325
329
  - lib/roda/plugins/autoload_hash_branches.rb
330
+ - lib/roda/plugins/autoload_named_routes.rb
326
331
  - lib/roda/plugins/backtracking_array.rb
327
332
  - lib/roda/plugins/branch_locals.rb
328
333
  - lib/roda/plugins/caching.rb
@@ -347,6 +352,7 @@ files:
347
352
  - lib/roda/plugins/early_hints.rb
348
353
  - lib/roda/plugins/empty_root.rb
349
354
  - lib/roda/plugins/environments.rb
355
+ - lib/roda/plugins/erb_h.rb
350
356
  - lib/roda/plugins/error_email.rb
351
357
  - lib/roda/plugins/error_handler.rb
352
358
  - lib/roda/plugins/error_mail.rb
@@ -460,7 +466,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
460
466
  - !ruby/object:Gem::Version
461
467
  version: '0'
462
468
  requirements: []
463
- rubygems_version: 3.3.26
469
+ rubygems_version: 3.4.6
464
470
  signing_key:
465
471
  specification_version: 4
466
472
  summary: Routing tree web toolkit