roda 3.67.0 → 3.68.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: 0ea9212a800294ebf286d593e230ac925aced0d5e7c118fa7541b3fd6a5cc983
4
- data.tar.gz: 9a591fdf0b2b481f71cbf871a70b3f83a8cac4bca4c3fe399348dfeee2447a13
3
+ metadata.gz: faad040bd1e251d705afbfe6ced40794aa2f135658168c85603a6c8a83a497be
4
+ data.tar.gz: 6e1d78ffdf0442835a754e54fc6216d8f668f3d0cb8e9c5635c1a582b17d5746
5
5
  SHA512:
6
- metadata.gz: 7f5887a701034ac935d6bb1f14a454f6dfe03751ec7842e383f401555f46d021d8bb502658959a5edae9d4199d8e8bfc785721d3386b76f0b6b280c7731fad3d
7
- data.tar.gz: eb7de74ded26221a86664644ceddda6428e877bdf158acd988319c56bdc335955b506623cc9d8fb3c71376c877d4e00254c018c4341debd221a6439d9557e6ed
6
+ metadata.gz: a663960b5f5c5391a44102b1b255fbb5546f241c2386b6fdbe8a5050f434407332f239eb0c862ab877de239ec1b4ea39c4f9202c488672a846c5f8eabaef6379
7
+ data.tar.gz: 508fa08ad66e1b11b5abc552345067fc2517aeb10ea060c6298a337b44db453c5daf35a0bbafe399dd9167286fd9ea35c07d75c340f640a6198beb52367352d5
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ = 3.68.0 (2023-05-11)
2
+
3
+ * Make Roda.run in multi_run plugin accept blocks to allow autoloading the apps to dispatch to (jeremyevans)
4
+
1
5
  = 3.67.0 (2023-04-12)
2
6
 
3
7
  * Add custom_block_results plugin for registering custom block result handlers (jeremyevans)
@@ -0,0 +1,21 @@
1
+ = New Feature
2
+
3
+ * Roda.run in the multi_run plugin now accepts blocks, to allow
4
+ autoloading of apps to dispatch to:
5
+
6
+ class App < Roda
7
+ plugin :multi_run
8
+
9
+ run("other_app"){OtherApp}
10
+
11
+ route do |r|
12
+ r.multi_run
13
+ end
14
+ end
15
+
16
+ With the above example, the block is not evaluated until a
17
+ request for the /other_app branch is received. If OtherApp is
18
+ autoloaded, this can speed up application startup and partial
19
+ testing. When freezing the application (for production use),
20
+ the block is eagerly loaded, so that requests to the
21
+ /other_app branch do not call the block on every request.
@@ -17,7 +17,7 @@ class Roda
17
17
  # App.run "ro", OtherRodaApp
18
18
  # App.run "si", SinatraApp
19
19
  #
20
- # Inside your route block, you can call r.multi_run to dispatch to all
20
+ # Inside your route block, you can call +r.multi_run+ to dispatch to all
21
21
  # three rack applications based on the prefix:
22
22
  #
23
23
  # App.route do |r|
@@ -28,7 +28,7 @@ class Roda
28
28
  # starting with +/ro+ to +OtherRodaApp+, and routes starting with +/si+ to
29
29
  # SinatraApp.
30
30
  #
31
- # You can pass a block to +multi_run+ that will be called with the prefix,
31
+ # You can pass a block to +r.multi_run+ that will be called with the prefix,
32
32
  # before dispatching to the rack app:
33
33
  #
34
34
  # App.route do |r|
@@ -39,12 +39,26 @@ class Roda
39
39
  #
40
40
  # This is useful for modifying the environment before passing it to the rack app.
41
41
  #
42
- # The multi_run plugin is similar to the multi_route plugin, with the difference
43
- # being the multi_route plugin keeps all routing subtrees in the same Roda app/class,
44
- # while multi_run dispatches to other rack apps. If you want to isolate your routing
45
- # subtrees, multi_run is a better approach, but it does not let you set instance
46
- # variables in the main Roda app and have those instance variables usable in
47
- # the routing subtrees.
42
+ # You can also call +Roda.run+ with a block:
43
+ #
44
+ # App.run("ra"){PlainRackApp}
45
+ # App.run("ro"){OtherRodaApp}
46
+ # App.run("si"){SinatraApp}
47
+ #
48
+ # When called with a block, Roda will call the block to get the app to dispatch to
49
+ # every time the block is called. The expected usage is with autoloaded classes,
50
+ # so that the related classes are not loaded until there is a request for the
51
+ # related route. This can sigficantly speedup startup or testing a subset of the
52
+ # application. When freezing an application, the blocks are called once to get the
53
+ # app to dispatch to, and that is cached, to ensure the any autoloads are completed
54
+ # before the application is frozen.
55
+ #
56
+ # The multi_run plugin is similar to the hash_branches and multi_route plugins, with
57
+ # the difference being the hash_branches and multi_route plugins keep all routing
58
+ # subtrees in the same Roda app/class, while multi_run dispatches to other rack apps.
59
+ # If you want to isolate your routing subtrees, multi_run is a better approach, but
60
+ # it does not let you set instance variables in the main Roda app and have those
61
+ # instance variables usable in the routing subtrees.
48
62
  #
49
63
  # To handle development environments that reload code, you can call the
50
64
  # +run+ class method without an app to remove dispatching for the prefix.
@@ -52,12 +66,21 @@ class Roda
52
66
  # Initialize the storage for the dispatched applications
53
67
  def self.configure(app)
54
68
  app.opts[:multi_run_apps] ||= {}
69
+ app.opts[:multi_run_app_blocks] ||= {}
55
70
  end
56
71
 
57
72
  module ClassMethods
73
+ # Convert app blocks into apps by calling them, in order to force autoloads
74
+ # and to speed up subsequent calls.
58
75
  # Freeze the multi_run apps so that there can be no thread safety issues at runtime.
59
76
  def freeze
60
- opts[:multi_run_apps].freeze
77
+ app_blocks = opts[:multi_run_app_blocks]
78
+ apps = opts[:multi_run_apps]
79
+ app_blocks.each do |prefix, block|
80
+ apps[prefix] = block.call
81
+ end
82
+ app_blocks.clear.freeze
83
+ apps.freeze
61
84
  self::RodaRequest.refresh_multi_run_regexp!
62
85
  super
63
86
  end
@@ -69,12 +92,22 @@ class Roda
69
92
  end
70
93
 
71
94
  # Add a rack application to dispatch to for the given prefix when
72
- # r.multi_run is called.
73
- def run(prefix, app=nil)
74
- if app
75
- multi_run_apps[prefix.to_s] = app
95
+ # r.multi_run is called. If a block is given, it is called every time
96
+ # there is a request for the route to get the app to call. If neither
97
+ # a block or an app is provided, any stored route for the prefix is
98
+ # removed. It is an error to provide both an app and block in the same call.
99
+ def run(prefix, app=nil, &block)
100
+ prefix = prefix.to_s
101
+ if app
102
+ raise Roda::RodaError, "cannot provide both app and block to Roda.run" if block
103
+ opts[:multi_run_apps][prefix] = app
104
+ opts[:multi_run_app_blocks].delete(prefix)
105
+ elsif block
106
+ opts[:multi_run_apps].delete(prefix)
107
+ opts[:multi_run_app_blocks][prefix] = block
76
108
  else
77
- multi_run_apps.delete(prefix.to_s)
109
+ opts[:multi_run_apps].delete(prefix)
110
+ opts[:multi_run_app_blocks].delete(prefix)
78
111
  end
79
112
  self::RodaRequest.refresh_multi_run_regexp!
80
113
  end
@@ -84,7 +117,7 @@ class Roda
84
117
  # Refresh the multi_run_regexp, using the stored route prefixes,
85
118
  # preferring longer routes before shorter routes.
86
119
  def refresh_multi_run_regexp!
87
- @multi_run_regexp = /(#{Regexp.union(roda_class.multi_run_apps.keys.sort.reverse)})/
120
+ @multi_run_regexp = /(#{Regexp.union((roda_class.opts[:multi_run_apps].keys + roda_class.opts[:multi_run_app_blocks].keys).sort.reverse)})/
88
121
  end
89
122
 
90
123
  # Refresh the multi_run_regexp if it hasn't been loaded yet.
@@ -95,11 +128,12 @@ class Roda
95
128
 
96
129
  module RequestMethods
97
130
  # If one of the stored route prefixes match the current request,
98
- # dispatch the request to the stored rack application.
131
+ # dispatch the request to the appropriate rack application.
99
132
  def multi_run
100
133
  on self.class.multi_run_regexp do |prefix|
101
134
  yield prefix if defined?(yield)
102
- run scope.class.multi_run_apps[prefix]
135
+ opts = scope.opts
136
+ run(opts[:multi_run_apps][prefix] || opts[:multi_run_app_blocks][prefix].call)
103
137
  end
104
138
  end
105
139
  end
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 = 67
7
+ RodaMinorVersion = 68
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.67.0
4
+ version: 3.68.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-04-12 00:00:00.000000000 Z
11
+ date: 2023-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -240,6 +240,7 @@ extra_rdoc_files:
240
240
  - doc/release_notes/3.65.0.txt
241
241
  - doc/release_notes/3.66.0.txt
242
242
  - doc/release_notes/3.67.0.txt
243
+ - doc/release_notes/3.68.0.txt
243
244
  - doc/release_notes/3.7.0.txt
244
245
  - doc/release_notes/3.8.0.txt
245
246
  - doc/release_notes/3.9.0.txt
@@ -314,6 +315,7 @@ files:
314
315
  - doc/release_notes/3.65.0.txt
315
316
  - doc/release_notes/3.66.0.txt
316
317
  - doc/release_notes/3.67.0.txt
318
+ - doc/release_notes/3.68.0.txt
317
319
  - doc/release_notes/3.7.0.txt
318
320
  - doc/release_notes/3.8.0.txt
319
321
  - doc/release_notes/3.9.0.txt