functions_framework 0.6.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +5 -5
- data/bin/functions-framework +3 -0
- data/docs/deploying-functions.md +7 -11
- data/docs/overview.md +4 -4
- data/docs/testing-functions.md +50 -0
- data/docs/writing-functions.md +245 -68
- data/lib/functions_framework.rb +11 -8
- data/lib/functions_framework/cli.rb +1 -1
- data/lib/functions_framework/function.rb +190 -48
- data/lib/functions_framework/legacy_event_converter.rb +83 -24
- data/lib/functions_framework/registry.rb +10 -20
- data/lib/functions_framework/server.rb +34 -22
- data/lib/functions_framework/testing.rb +117 -22
- data/lib/functions_framework/version.rb +1 -1
- metadata +28 -16
@@ -12,20 +12,16 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
require "monitor"
|
16
|
-
|
17
15
|
module FunctionsFramework
|
18
16
|
##
|
19
17
|
# Registry providing lookup of functions by name.
|
20
18
|
#
|
21
19
|
class Registry
|
22
|
-
include ::MonitorMixin
|
23
|
-
|
24
20
|
##
|
25
21
|
# Create a new empty registry.
|
26
22
|
#
|
27
23
|
def initialize
|
28
|
-
@mutex = ::
|
24
|
+
@mutex = ::Mutex.new
|
29
25
|
@functions = {}
|
30
26
|
@start_tasks = []
|
31
27
|
end
|
@@ -51,17 +47,12 @@ module FunctionsFramework
|
|
51
47
|
end
|
52
48
|
|
53
49
|
##
|
54
|
-
#
|
50
|
+
# Return an array of startup tasks.
|
55
51
|
#
|
56
|
-
# @
|
57
|
-
# @return [self]
|
52
|
+
# @return [Array<FunctionsFramework::Function>]
|
58
53
|
#
|
59
|
-
def
|
60
|
-
|
61
|
-
tasks.each do |task|
|
62
|
-
task.call server.function, server.config
|
63
|
-
end
|
64
|
-
self
|
54
|
+
def startup_tasks
|
55
|
+
@mutex.synchronize { @start_tasks.dup }
|
65
56
|
end
|
66
57
|
|
67
58
|
##
|
@@ -85,7 +76,7 @@ module FunctionsFramework
|
|
85
76
|
name = name.to_s
|
86
77
|
@mutex.synchronize do
|
87
78
|
raise ::ArgumentError, "Function already defined: #{name}" if @functions.key? name
|
88
|
-
@functions[name] = Function.
|
79
|
+
@functions[name] = Function.http name, &block
|
89
80
|
end
|
90
81
|
self
|
91
82
|
end
|
@@ -106,7 +97,7 @@ module FunctionsFramework
|
|
106
97
|
name = name.to_s
|
107
98
|
@mutex.synchronize do
|
108
99
|
raise ::ArgumentError, "Function already defined: #{name}" if @functions.key? name
|
109
|
-
@functions[name] = Function.
|
100
|
+
@functions[name] = Function.cloud_event name, &block
|
110
101
|
end
|
111
102
|
self
|
112
103
|
end
|
@@ -115,16 +106,15 @@ module FunctionsFramework
|
|
115
106
|
# Add a startup task.
|
116
107
|
#
|
117
108
|
# Startup tasks are generally run just before a server starts. They are
|
118
|
-
# passed
|
119
|
-
#
|
120
|
-
# specifying the (frozen) server configuration. Tasks have no return value.
|
109
|
+
# passed the {FunctionsFramework::Function} identifying the function to
|
110
|
+
# execute, and have no return value.
|
121
111
|
#
|
122
112
|
# @param block [Proc] The startup task
|
123
113
|
# @return [self]
|
124
114
|
#
|
125
115
|
def add_startup_task &block
|
126
116
|
@mutex.synchronize do
|
127
|
-
@start_tasks << block
|
117
|
+
@start_tasks << Function.startup_task(&block)
|
128
118
|
end
|
129
119
|
self
|
130
120
|
end
|
@@ -27,17 +27,22 @@ module FunctionsFramework
|
|
27
27
|
include ::MonitorMixin
|
28
28
|
|
29
29
|
##
|
30
|
-
# Create a new web server given a function
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
30
|
+
# Create a new web server given a function definition, a set of application
|
31
|
+
# globals, and server configuration.
|
32
|
+
#
|
33
|
+
# To configure the server, pass a block that takes a
|
34
|
+
# {FunctionsFramework::Server::Config} object as the parameter. This block
|
35
|
+
# is the only opportunity to modify the configuration; once the server is
|
36
|
+
# initialized, configuration is frozen.
|
35
37
|
#
|
36
38
|
# @param function [FunctionsFramework::Function] The function to execute.
|
39
|
+
# @param globals [Hash] Globals to pass to invocations. This hash should
|
40
|
+
# normally be frozen so separate function invocations cannot interfere
|
41
|
+
# with one another's globals.
|
37
42
|
# @yield [FunctionsFramework::Server::Config] A config object that can be
|
38
43
|
# manipulated to configure this server.
|
39
44
|
#
|
40
|
-
def initialize function
|
45
|
+
def initialize function, globals
|
41
46
|
super()
|
42
47
|
@config = Config.new
|
43
48
|
yield @config if block_given?
|
@@ -46,9 +51,9 @@ module FunctionsFramework
|
|
46
51
|
@app =
|
47
52
|
case function.type
|
48
53
|
when :http
|
49
|
-
HttpApp.new function, @config
|
54
|
+
HttpApp.new function, globals, @config
|
50
55
|
when :cloud_event
|
51
|
-
EventApp.new function, @config
|
56
|
+
EventApp.new function, globals, @config
|
52
57
|
else
|
53
58
|
raise "Unrecognized function type: #{function.type}"
|
54
59
|
end
|
@@ -153,7 +158,7 @@ module FunctionsFramework
|
|
153
158
|
::Signal.trap "SIGHUP" do
|
154
159
|
Server.signal_enqueue "SIGHUP", @config.logger, @server
|
155
160
|
end
|
156
|
-
rescue ::ArgumentError
|
161
|
+
rescue ::ArgumentError
|
157
162
|
# Not available on all systems
|
158
163
|
end
|
159
164
|
@signals_installed = true
|
@@ -301,7 +306,7 @@ module FunctionsFramework
|
|
301
306
|
# @return [Integer]
|
302
307
|
#
|
303
308
|
def max_threads
|
304
|
-
@max_threads ||
|
309
|
+
@max_threads || 1
|
305
310
|
end
|
306
311
|
|
307
312
|
##
|
@@ -341,9 +346,9 @@ module FunctionsFramework
|
|
341
346
|
when ::Rack::Response
|
342
347
|
response.finish
|
343
348
|
when ::String
|
344
|
-
string_response response,
|
349
|
+
string_response response, 200
|
345
350
|
when ::Hash
|
346
|
-
string_response ::JSON.dump(response), "application/json"
|
351
|
+
string_response ::JSON.dump(response), 200, content_type: "application/json"
|
347
352
|
when ::CloudEvents::CloudEventsError
|
348
353
|
cloud_events_error_response response
|
349
354
|
when ::StandardError
|
@@ -354,10 +359,17 @@ module FunctionsFramework
|
|
354
359
|
end
|
355
360
|
|
356
361
|
def notfound_response
|
357
|
-
string_response "Not found",
|
362
|
+
string_response "Not found", 404
|
358
363
|
end
|
359
364
|
|
360
|
-
def string_response string,
|
365
|
+
def string_response string, status, content_type: nil
|
366
|
+
string.force_encoding ::Encoding::ASCII_8BIT unless string.valid_encoding?
|
367
|
+
if string.encoding == ::Encoding::ASCII_8BIT
|
368
|
+
content_type ||= "application/octet-stream"
|
369
|
+
else
|
370
|
+
content_type ||= "text/plain"
|
371
|
+
content_type = "#{content_type}; charset=#{string.encoding.name.downcase}"
|
372
|
+
end
|
361
373
|
headers = {
|
362
374
|
"Content-Type" => content_type,
|
363
375
|
"Content-Length" => string.bytesize
|
@@ -367,21 +379,22 @@ module FunctionsFramework
|
|
367
379
|
|
368
380
|
def cloud_events_error_response error
|
369
381
|
@config.logger.warn error
|
370
|
-
string_response "#{error.class}: #{error.message}",
|
382
|
+
string_response "#{error.class}: #{error.message}", 400
|
371
383
|
end
|
372
384
|
|
373
385
|
def error_response message
|
374
386
|
@config.logger.error message
|
375
387
|
message = "Unexpected internal error" unless @config.show_error_details?
|
376
|
-
string_response message,
|
388
|
+
string_response message, 500
|
377
389
|
end
|
378
390
|
end
|
379
391
|
|
380
392
|
## @private
|
381
393
|
class HttpApp < AppBase
|
382
|
-
def initialize function, config
|
394
|
+
def initialize function, globals, config
|
383
395
|
super config
|
384
396
|
@function = function
|
397
|
+
@globals = globals
|
385
398
|
end
|
386
399
|
|
387
400
|
def call env
|
@@ -391,8 +404,7 @@ module FunctionsFramework
|
|
391
404
|
logger = env["rack.logger"] ||= @config.logger
|
392
405
|
request = ::Rack::Request.new env
|
393
406
|
logger.info "FunctionsFramework: Handling HTTP #{request.request_method} request"
|
394
|
-
|
395
|
-
calling_context.call request
|
407
|
+
@function.call request, globals: @globals, logger: logger
|
396
408
|
rescue ::StandardError => e
|
397
409
|
e
|
398
410
|
end
|
@@ -402,9 +414,10 @@ module FunctionsFramework
|
|
402
414
|
|
403
415
|
## @private
|
404
416
|
class EventApp < AppBase
|
405
|
-
def initialize function, config
|
417
|
+
def initialize function, globals, config
|
406
418
|
super config
|
407
419
|
@function = function
|
420
|
+
@globals = globals
|
408
421
|
@cloud_events = ::CloudEvents::HttpBinding.default
|
409
422
|
@legacy_events = LegacyEventConverter.new
|
410
423
|
end
|
@@ -439,8 +452,7 @@ module FunctionsFramework
|
|
439
452
|
|
440
453
|
def handle_cloud_event event, logger
|
441
454
|
logger.info "FunctionsFramework: Handling CloudEvent"
|
442
|
-
|
443
|
-
calling_context.call event
|
455
|
+
@function.call event, globals: @globals, logger: logger
|
444
456
|
"ok"
|
445
457
|
rescue ::StandardError => e
|
446
458
|
e
|
@@ -75,19 +75,71 @@ module FunctionsFramework
|
|
75
75
|
Testing.load_for_testing path, &block
|
76
76
|
end
|
77
77
|
|
78
|
+
##
|
79
|
+
# Run startup tasks for the given function name and return the initialized
|
80
|
+
# globals hash.
|
81
|
+
#
|
82
|
+
# Normally, this will be run automatically prior to the first call to the
|
83
|
+
# function using {call_http} or {call_event}, if it has not already been
|
84
|
+
# run. However, you can call it explicitly to test its behavior. It cannot
|
85
|
+
# be called more than once for any given function.
|
86
|
+
#
|
87
|
+
# By default, the {FunctionsFramework.logger} will be used, but you can
|
88
|
+
# override that by providing your own logger. In particular, to disable
|
89
|
+
# logging, you can pass `Logger.new(nil)`.
|
90
|
+
#
|
91
|
+
# @param name [String] The name of the function to start up.
|
92
|
+
# @param logger [Logger] Use the given logger instead of the Functions
|
93
|
+
# Framework's global logger. Optional.
|
94
|
+
# @param lenient [Boolean] If false (the default), raise an error if the
|
95
|
+
# given function has already had its startup tasks run. If true,
|
96
|
+
# duplicate requests to run startup tasks are ignored.
|
97
|
+
# @return [Hash] The initialized globals.
|
98
|
+
#
|
99
|
+
def run_startup_tasks name, logger: nil, lenient: false
|
100
|
+
function = Testing.current_registry[name]
|
101
|
+
raise "Unknown function name #{name}" unless function
|
102
|
+
globals = Testing.current_globals name
|
103
|
+
if globals
|
104
|
+
raise "Function #{name} has already been started up" unless lenient
|
105
|
+
else
|
106
|
+
globals = function.populate_globals
|
107
|
+
Testing.current_registry.startup_tasks.each do |task|
|
108
|
+
task.call function, globals: globals, logger: logger
|
109
|
+
end
|
110
|
+
Testing.current_globals name, globals
|
111
|
+
end
|
112
|
+
globals.freeze
|
113
|
+
end
|
114
|
+
|
78
115
|
##
|
79
116
|
# Call the given HTTP function for testing. The underlying function must
|
80
|
-
# be of type `:http`.
|
117
|
+
# be of type `:http`. Returns the Rack response.
|
118
|
+
#
|
119
|
+
# By default, the startup tasks will be run for the given function if they
|
120
|
+
# have not already been run. You can, however, disable running startup
|
121
|
+
# tasks by providing an explicit globals hash.
|
122
|
+
#
|
123
|
+
# By default, the {FunctionsFramework.logger} will be used, but you can
|
124
|
+
# override that by providing your own logger. In particular, to disable
|
125
|
+
# logging, you can pass `Logger.new(nil)`.
|
81
126
|
#
|
82
127
|
# @param name [String] The name of the function to call
|
83
128
|
# @param request [Rack::Request] The Rack request to send
|
129
|
+
# @param globals [Hash] Do not run startup tasks, and instead provide the
|
130
|
+
# globals directly. Optional.
|
131
|
+
# @param logger [Logger] Use the given logger instead of the Functions
|
132
|
+
# Framework's global logger. Optional.
|
84
133
|
# @return [Rack::Response]
|
85
134
|
#
|
86
|
-
def call_http name, request
|
87
|
-
|
135
|
+
def call_http name, request, globals: nil, logger: nil
|
136
|
+
globals ||= run_startup_tasks name, logger: logger, lenient: true
|
137
|
+
function = Testing.current_registry[name]
|
88
138
|
case function&.type
|
89
139
|
when :http
|
90
|
-
Testing.interpret_response
|
140
|
+
Testing.interpret_response do
|
141
|
+
function.call request, globals: globals, logger: logger
|
142
|
+
end
|
91
143
|
when nil
|
92
144
|
raise "Unknown function name #{name}"
|
93
145
|
else
|
@@ -99,15 +151,28 @@ module FunctionsFramework
|
|
99
151
|
# Call the given event function for testing. The underlying function must
|
100
152
|
# be of type :cloud_event`.
|
101
153
|
#
|
154
|
+
# By default, the startup tasks will be run for the given function if they
|
155
|
+
# have not already been run. You can, however, disable running startup
|
156
|
+
# tasks by providing an explicit globals hash.
|
157
|
+
#
|
158
|
+
# By default, the {FunctionsFramework.logger} will be used, but you can
|
159
|
+
# override that by providing your own logger. In particular, to disable
|
160
|
+
# logging, you can pass `Logger.new(nil)`.
|
161
|
+
#
|
102
162
|
# @param name [String] The name of the function to call
|
103
163
|
# @param event [::CloudEvents::Event] The event to send
|
164
|
+
# @param globals [Hash] Do not run startup tasks, and instead provide the
|
165
|
+
# globals directly. Optional.
|
166
|
+
# @param logger [Logger] Use the given logger instead of the Functions
|
167
|
+
# Framework's global logger. Optional.
|
104
168
|
# @return [nil]
|
105
169
|
#
|
106
|
-
def call_event name, event
|
107
|
-
|
170
|
+
def call_event name, event, globals: nil, logger: nil
|
171
|
+
globals ||= run_startup_tasks name, logger: logger, lenient: true
|
172
|
+
function = Testing.current_registry[name]
|
108
173
|
case function&.type
|
109
174
|
when :cloud_event
|
110
|
-
function.
|
175
|
+
function.call event, globals: globals, logger: logger
|
111
176
|
nil
|
112
177
|
when nil
|
113
178
|
raise "Unknown function name #{name}"
|
@@ -208,27 +273,49 @@ module FunctionsFramework
|
|
208
273
|
extend self
|
209
274
|
|
210
275
|
@testing_registries = {}
|
276
|
+
@main_globals = {}
|
211
277
|
@mutex = ::Mutex.new
|
212
278
|
|
213
279
|
class << self
|
214
280
|
## @private
|
215
281
|
def load_for_testing path
|
216
282
|
old_registry = ::FunctionsFramework.global_registry
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
283
|
+
::Thread.current[:functions_framework_testing_registry] =
|
284
|
+
@mutex.synchronize do
|
285
|
+
if @testing_registries.key? path
|
286
|
+
::FunctionsFramework.global_registry = @testing_registries[path]
|
287
|
+
else
|
288
|
+
new_registry = ::FunctionsFramework::Registry.new
|
289
|
+
::FunctionsFramework.global_registry = new_registry
|
290
|
+
::Kernel.load path
|
291
|
+
@testing_registries[path] = new_registry
|
292
|
+
end
|
225
293
|
end
|
226
|
-
|
294
|
+
::Thread.current[:functions_framework_testing_globals] = {}
|
227
295
|
yield
|
228
296
|
ensure
|
297
|
+
::Thread.current[:functions_framework_testing_registry] = nil
|
298
|
+
::Thread.current[:functions_framework_testing_globals] = nil
|
229
299
|
::FunctionsFramework.global_registry = old_registry
|
230
300
|
end
|
231
301
|
|
302
|
+
## @private
|
303
|
+
def current_registry
|
304
|
+
::Thread.current[:functions_framework_testing_registry] ||
|
305
|
+
::FunctionsFramework.global_registry
|
306
|
+
end
|
307
|
+
|
308
|
+
## @private
|
309
|
+
def current_globals name, globals = nil
|
310
|
+
name = name.to_s
|
311
|
+
globals_by_name = ::Thread.current[:functions_framework_testing_globals] || @main_globals
|
312
|
+
if globals
|
313
|
+
globals_by_name[name] = globals
|
314
|
+
else
|
315
|
+
globals_by_name[name]
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
232
319
|
## @private
|
233
320
|
def interpret_response
|
234
321
|
response =
|
@@ -243,20 +330,27 @@ module FunctionsFramework
|
|
243
330
|
when ::Array
|
244
331
|
::Rack::Response.new response[2], response[0], response[1]
|
245
332
|
when ::String
|
246
|
-
string_response response,
|
333
|
+
string_response response, 200
|
247
334
|
when ::Hash
|
248
335
|
json = ::JSON.dump response
|
249
|
-
string_response json, "application/json"
|
336
|
+
string_response json, 200, content_type: "application/json"
|
250
337
|
when ::StandardError
|
251
338
|
message = "#{response.class}: #{response.message}\n#{response.backtrace}\n"
|
252
|
-
string_response message,
|
339
|
+
string_response message, 500
|
253
340
|
else
|
254
341
|
raise "Unexpected response type: #{response.inspect}"
|
255
342
|
end
|
256
343
|
end
|
257
344
|
|
258
345
|
## @private
|
259
|
-
def string_response string,
|
346
|
+
def string_response string, status, content_type: nil
|
347
|
+
string.force_encoding ::Encoding::ASCII_8BIT unless string.valid_encoding?
|
348
|
+
if string.encoding == ::Encoding::ASCII_8BIT
|
349
|
+
content_type ||= "application/octet-stream"
|
350
|
+
else
|
351
|
+
content_type ||= "text/plain"
|
352
|
+
content_type = "#{content_type}; charset=#{string.encoding.name.downcase}"
|
353
|
+
end
|
260
354
|
headers = {
|
261
355
|
"Content-Type" => content_type,
|
262
356
|
"Content-Length" => string.bytesize
|
@@ -279,9 +373,10 @@ module FunctionsFramework
|
|
279
373
|
::Rack::RACK_ERRORS => ::StringIO.new
|
280
374
|
}
|
281
375
|
headers.each do |header|
|
282
|
-
|
376
|
+
case header
|
377
|
+
when String
|
283
378
|
name, value = header.split ":"
|
284
|
-
|
379
|
+
when ::Array
|
285
380
|
name, value = header
|
286
381
|
end
|
287
382
|
next unless name && value
|
metadata
CHANGED
@@ -1,43 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: functions_framework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cloud_events
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.4'
|
20
|
+
- - "<"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
22
|
+
version: 2.a
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.4'
|
30
|
+
- - "<"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
32
|
+
version: 2.a
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: puma
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 4.3.0
|
40
|
+
- - "<"
|
32
41
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
42
|
+
version: 6.a
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
38
|
-
- - "
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 4.3.0
|
50
|
+
- - "<"
|
39
51
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
52
|
+
version: 6.a
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: rack
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,8 +66,8 @@ dependencies:
|
|
54
66
|
version: '2.1'
|
55
67
|
description: The Functions Framework is an open source framework for writing lightweight,
|
56
68
|
portable Ruby functions that run in a serverless environment. Functions written
|
57
|
-
to this Framework will run
|
58
|
-
|
69
|
+
to this Framework will run on Google Cloud Functions, Google Cloud Run, or any other
|
70
|
+
Knative-based environment.
|
59
71
|
email:
|
60
72
|
- dazuma@google.com
|
61
73
|
executables:
|
@@ -87,10 +99,10 @@ homepage: https://github.com/GoogleCloudPlatform/functions-framework-ruby
|
|
87
99
|
licenses:
|
88
100
|
- Apache-2.0
|
89
101
|
metadata:
|
90
|
-
changelog_uri: https://googlecloudplatform.github.io/functions-framework-ruby/v0.
|
102
|
+
changelog_uri: https://googlecloudplatform.github.io/functions-framework-ruby/v0.10.0/file.CHANGELOG.html
|
91
103
|
source_code_uri: https://github.com/GoogleCloudPlatform/functions-framework-ruby
|
92
104
|
bug_tracker_uri: https://github.com/GoogleCloudPlatform/functions-framework-ruby/issues
|
93
|
-
documentation_uri: https://googlecloudplatform.github.io/functions-framework-ruby/v0.
|
105
|
+
documentation_uri: https://googlecloudplatform.github.io/functions-framework-ruby/v0.10.0
|
94
106
|
post_install_message:
|
95
107
|
rdoc_options: []
|
96
108
|
require_paths:
|
@@ -99,14 +111,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
111
|
requirements:
|
100
112
|
- - ">="
|
101
113
|
- !ruby/object:Gem::Version
|
102
|
-
version: 2.
|
114
|
+
version: 2.5.0
|
103
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
116
|
requirements:
|
105
117
|
- - ">="
|
106
118
|
- !ruby/object:Gem::Version
|
107
119
|
version: '0'
|
108
120
|
requirements: []
|
109
|
-
rubygems_version: 3.
|
121
|
+
rubygems_version: 3.1.6
|
110
122
|
signing_key:
|
111
123
|
specification_version: 4
|
112
124
|
summary: Functions Framework for Ruby
|