roda 3.64.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: 715e94da6acab0fa1c5e8409051f3faf0800ca56874d8640fa8f00c2ac432322
4
- data.tar.gz: 79d9f75da1af54c8288918f722dff874433c7935a996180311344a24acc751ec
3
+ metadata.gz: d1c9c4301b4c90cb2f2c7a2d190986b4b6c68c4e1eb4b0be59bdba2aebdf6780
4
+ data.tar.gz: 576b15ba70cdab634638bce683ba8ee8ac93feb9fe5f3ae8982cf6ae07c6d686
5
5
  SHA512:
6
- metadata.gz: 507d5395d337ae4e6c13a3ace905a605ecad5690bf8ceabd8d40bf3c9e2b162649a2a6cb79d1422c8c560396f4abdf891d8f3543b9866cd4f20e944acb4b6347
7
- data.tar.gz: 37cdd77e3b2894ca55370d638e411e3bf10005101d83939a970b242a4750aa2df929994343c20546cdd6046553897e4d7cde19788f10c2406eb5b446d31e97d5
6
+ metadata.gz: 91b24c2bbcb2d2c27c14f242d620fab9d5e838f68bc102887018e41e4e05f5eb93718ab312c727a32ac4ab6df0dbcf4d0bb134499674dee71e991e953ecac85b
7
+ data.tar.gz: 9fe4592c67425c171926368d1121841dcafae686eb6822439536c24040788049041f34dffae22fde1ba2905f63c0e3abd13a5938ea263f4b143fdb94219e66f1
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
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
+
1
9
  = 3.64.0 (2023-01-12)
2
10
 
3
11
  * Automatically expand paths for autoload_hash_branches files, so that relative paths work (jeremyevans)
@@ -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.
@@ -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
@@ -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 = 64
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.64.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: 2023-01-12 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
@@ -237,6 +237,7 @@ extra_rdoc_files:
237
237
  - doc/release_notes/3.62.0.txt
238
238
  - doc/release_notes/3.63.0.txt
239
239
  - doc/release_notes/3.64.0.txt
240
+ - doc/release_notes/3.65.0.txt
240
241
  - doc/release_notes/3.7.0.txt
241
242
  - doc/release_notes/3.8.0.txt
242
243
  - doc/release_notes/3.9.0.txt
@@ -308,6 +309,7 @@ files:
308
309
  - doc/release_notes/3.62.0.txt
309
310
  - doc/release_notes/3.63.0.txt
310
311
  - doc/release_notes/3.64.0.txt
312
+ - doc/release_notes/3.65.0.txt
311
313
  - doc/release_notes/3.7.0.txt
312
314
  - doc/release_notes/3.8.0.txt
313
315
  - doc/release_notes/3.9.0.txt
@@ -325,6 +327,7 @@ files:
325
327
  - lib/roda/plugins/assets.rb
326
328
  - lib/roda/plugins/assets_preloading.rb
327
329
  - lib/roda/plugins/autoload_hash_branches.rb
330
+ - lib/roda/plugins/autoload_named_routes.rb
328
331
  - lib/roda/plugins/backtracking_array.rb
329
332
  - lib/roda/plugins/branch_locals.rb
330
333
  - lib/roda/plugins/caching.rb
@@ -463,7 +466,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
463
466
  - !ruby/object:Gem::Version
464
467
  version: '0'
465
468
  requirements: []
466
- rubygems_version: 3.4.1
469
+ rubygems_version: 3.4.6
467
470
  signing_key:
468
471
  specification_version: 4
469
472
  summary: Routing tree web toolkit