cloudenvoy 0.4.2 → 0.6.rc1
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 +4 -4
- data/.github/workflows/lint_rubocop.yml +20 -0
- data/.github/workflows/{test.yml → test_ruby_2.5_2.6.yml} +8 -13
- data/.github/workflows/test_ruby_2.7.yml +36 -0
- data/.github/workflows/test_ruby_3.x.yml +35 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +17 -16
- data/Appraisals +24 -4
- data/CHANGELOG.md +18 -0
- data/README.md +39 -2
- data/cloudenvoy.gemspec +2 -6
- data/examples/rails/.ruby-version +1 -1
- data/examples/rails/Gemfile +4 -1
- data/examples/rails/Gemfile.lock +92 -85
- data/examples/rails/README.md +5 -1
- data/examples/rails/app/subscribers/hello_subscriber.rb +1 -1
- data/examples/rails/config/environments/production.rb +1 -1
- data/examples/rails/config/puma.rb +3 -3
- data/examples/sinatra/Gemfile +4 -1
- data/examples/sinatra/Gemfile.lock +40 -28
- data/examples/sinatra/README.md +4 -0
- data/examples/sinatra/app/subscribers/hello_subscriber.rb +1 -1
- data/examples/sinatra/app.rb +4 -4
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_5.2.gemfile +1 -0
- data/gemfiles/rails_6.0.gemfile +1 -0
- data/gemfiles/rails_6.1.gemfile +8 -0
- data/gemfiles/rails_7.0.gemfile +8 -0
- data/gemfiles/semantic_logger_3.4.gemfile +1 -0
- data/gemfiles/semantic_logger_4.6.gemfile +1 -0
- data/gemfiles/semantic_logger_4.7.0.gemfile +1 -0
- data/gemfiles/semantic_logger_4.7.2.gemfile +1 -0
- data/lib/cloudenvoy/backend/google_pub_sub.rb +37 -5
- data/lib/cloudenvoy/backend/memory_pub_sub.rb +25 -1
- data/lib/cloudenvoy/config.rb +1 -1
- data/lib/cloudenvoy/message.rb +2 -2
- data/lib/cloudenvoy/pub_sub_client.rb +13 -1
- data/lib/cloudenvoy/publisher.rb +39 -5
- data/lib/cloudenvoy/publisher_logger.rb +1 -1
- data/lib/cloudenvoy/version.rb +1 -1
- data/lib/cloudenvoy.rb +13 -0
- metadata +15 -57
- data/gemfiles/rails_5.2.gemfile.lock +0 -264
- data/gemfiles/rails_6.0.gemfile.lock +0 -280
- data/gemfiles/semantic_logger_3.4.gemfile.lock +0 -279
- data/gemfiles/semantic_logger_4.6.gemfile.lock +0 -279
- data/gemfiles/semantic_logger_4.7.0.gemfile.lock +0 -279
- data/gemfiles/semantic_logger_4.7.2.gemfile.lock +0 -279
@@ -32,7 +32,7 @@ module Cloudenvoy
|
|
32
32
|
# @return [Google::Cloud::Pub] The low level client instance.
|
33
33
|
#
|
34
34
|
def backend
|
35
|
-
@backend ||= Google::Cloud::PubSub.new({
|
35
|
+
@backend ||= Google::Cloud::PubSub.new(**{
|
36
36
|
project_id: config.gcp_project_id,
|
37
37
|
emulator_host: development? ? Cloudenvoy::Config::EMULATOR_HOST : nil
|
38
38
|
}.compact)
|
@@ -54,7 +54,7 @@ module Cloudenvoy
|
|
54
54
|
# @param [Hash, String] payload The message content.
|
55
55
|
# @param [Hash] metadata The message attributes.
|
56
56
|
#
|
57
|
-
# @return [Cloudenvoy::Message] The
|
57
|
+
# @return [Cloudenvoy::Message] The published message.
|
58
58
|
#
|
59
59
|
def publish(topic, payload, metadata = {})
|
60
60
|
# Retrieve the topic
|
@@ -72,6 +72,38 @@ module Cloudenvoy
|
|
72
72
|
)
|
73
73
|
end
|
74
74
|
|
75
|
+
#
|
76
|
+
# Publish multiple messages to a topic.
|
77
|
+
#
|
78
|
+
# @param [String] topic The name of the topic
|
79
|
+
# @param [Array<Array<[Hash, String]>>] msg_args A list of message [payload, metadata].
|
80
|
+
#
|
81
|
+
# @return [Array<Cloudenvoy::Message>] The published messages.
|
82
|
+
#
|
83
|
+
def publish_all(topic, msg_args)
|
84
|
+
# Retrieve the topic
|
85
|
+
ps_topic = backend.topic(topic, skip_lookup: true)
|
86
|
+
|
87
|
+
# Publish the message
|
88
|
+
ps_msgs = ps_topic.publish do |batch|
|
89
|
+
msg_args.each do |(payload, metadata)|
|
90
|
+
batch.publish(payload.to_json, metadata.to_h)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return the formatted messages
|
95
|
+
ps_msgs.each_with_index.map do |ps_msg, index|
|
96
|
+
payload, metadata = msg_args[index]
|
97
|
+
|
98
|
+
Message.new(
|
99
|
+
id: ps_msg.message_id,
|
100
|
+
payload: payload,
|
101
|
+
metadata: metadata,
|
102
|
+
topic: topic
|
103
|
+
)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
75
107
|
#
|
76
108
|
# Create or update a subscription for a specific topic.
|
77
109
|
#
|
@@ -109,7 +141,7 @@ module Cloudenvoy
|
|
109
141
|
ps_topic = backend.topic(topic, skip_lookup: true)
|
110
142
|
|
111
143
|
# Attempt to create the subscription
|
112
|
-
ps_topic.subscribe(name, sub_config)
|
144
|
+
ps_topic.subscribe(name, **sub_config)
|
113
145
|
rescue Google::Cloud::AlreadyExistsError
|
114
146
|
# Update endpoint on subscription
|
115
147
|
# Topic is not updated as it is name-dependent
|
@@ -134,8 +166,8 @@ module Cloudenvoy
|
|
134
166
|
def upsert_topic(topic)
|
135
167
|
ps_topic = begin
|
136
168
|
backend.create_topic(topic)
|
137
|
-
|
138
|
-
|
169
|
+
rescue Google::Cloud::AlreadyExistsError
|
170
|
+
backend.topic(topic)
|
139
171
|
end
|
140
172
|
|
141
173
|
# Return formatted subscription
|
@@ -47,7 +47,7 @@ module Cloudenvoy
|
|
47
47
|
# @param [Hash, String] payload The message content.
|
48
48
|
# @param [Hash] attrs The message attributes.
|
49
49
|
#
|
50
|
-
# @return [Cloudenvoy::Message] The
|
50
|
+
# @return [Cloudenvoy::Message] The published message.
|
51
51
|
#
|
52
52
|
def publish(topic, payload, metadata = {})
|
53
53
|
msg = Message.new(
|
@@ -61,6 +61,30 @@ module Cloudenvoy
|
|
61
61
|
msg
|
62
62
|
end
|
63
63
|
|
64
|
+
#
|
65
|
+
# Publish multiple messages to a topic.
|
66
|
+
#
|
67
|
+
# @param [String] topic The name of the topic
|
68
|
+
# @param [Array<Array<[Hash, String]>>] msg_args A list of message [payload, metadata].
|
69
|
+
#
|
70
|
+
# @return [Array<Cloudenvoy::Message>] The published messages.
|
71
|
+
#
|
72
|
+
def publish_all(topic, msg_args)
|
73
|
+
# Build the messages
|
74
|
+
msgs = msg_args.map do |(payload, metadata)|
|
75
|
+
Message.new(
|
76
|
+
id: SecureRandom.uuid,
|
77
|
+
payload: payload,
|
78
|
+
metadata: metadata,
|
79
|
+
topic: topic
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Push all the messages and return them
|
84
|
+
queue(topic).push(*msgs)
|
85
|
+
msgs
|
86
|
+
end
|
87
|
+
|
64
88
|
#
|
65
89
|
# Create or update a subscription for a specific topic.
|
66
90
|
#
|
data/lib/cloudenvoy/config.rb
CHANGED
data/lib/cloudenvoy/message.rb
CHANGED
@@ -30,12 +30,24 @@ module Cloudenvoy
|
|
30
30
|
# @param [Hash, String] payload The message content.
|
31
31
|
# @param [Hash] attrs The message attributes.
|
32
32
|
#
|
33
|
-
# @return [Cloudenvoy::Message] The
|
33
|
+
# @return [Cloudenvoy::Message] The published message.
|
34
34
|
#
|
35
35
|
def self.publish(topic, payload, attrs = {})
|
36
36
|
backend.publish(topic, payload, attrs)
|
37
37
|
end
|
38
38
|
|
39
|
+
#
|
40
|
+
# Publish multiple messages to a topic.
|
41
|
+
#
|
42
|
+
# @param [String] topic The name of the topic
|
43
|
+
# @param [Array<Array<[Hash, String]>>] msg_args A list of message [payload, metadata].
|
44
|
+
#
|
45
|
+
# @return [Array<Cloudenvoy::Message>] The published messages.
|
46
|
+
#
|
47
|
+
def self.publish_all(topic, msg_args)
|
48
|
+
backend.publish_all(topic, msg_args)
|
49
|
+
end
|
50
|
+
|
39
51
|
#
|
40
52
|
# Create or update a subscription for a specific topic.
|
41
53
|
#
|
data/lib/cloudenvoy/publisher.rb
CHANGED
@@ -89,6 +89,40 @@ module Cloudenvoy
|
|
89
89
|
|
90
90
|
PubSubClient.upsert_topic(default_topic)
|
91
91
|
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Publish all messages in one batch.
|
95
|
+
#
|
96
|
+
# @param [Array<Any>] The list of publisher arguments.
|
97
|
+
#
|
98
|
+
# @return [Array<Cloudenvoy::Message>] The published messages.
|
99
|
+
#
|
100
|
+
def publish_all(arg_list)
|
101
|
+
# Build the list of publishers
|
102
|
+
publishers = arg_list.map { |e| new(msg_args: [e].flatten(1)) }
|
103
|
+
|
104
|
+
# Batches are topic specific. We must send one batch of messages per topic.
|
105
|
+
publishers.group_by { |e| e.topic(*e.msg_args) }.map do |topic, topic_publishers|
|
106
|
+
# Chain publish calls. The very last call (when the chain becomes empty)
|
107
|
+
# is the actual batch publishing of messages to pub/sub
|
108
|
+
chain = topic_publishers.dup
|
109
|
+
traverse_chain = lambda do
|
110
|
+
if chain.empty?
|
111
|
+
# Send the messages in one batch and retrospectively attach them
|
112
|
+
# to each publisher
|
113
|
+
arg_list = topic_publishers.map { |e| [e.payload(*e.msg_args), e.metadata(*e.msg_args)] }
|
114
|
+
PubSubClient.publish_all(topic, arg_list).each_with_index do |msg, pub_index|
|
115
|
+
topic_publishers[pub_index].message = msg
|
116
|
+
end
|
117
|
+
else
|
118
|
+
# Defer message publishing to the next element
|
119
|
+
# in the chain until the chain is empty
|
120
|
+
chain.shift.publish(&traverse_chain)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
traverse_chain.call
|
124
|
+
end.flatten
|
125
|
+
end
|
92
126
|
end
|
93
127
|
|
94
128
|
#
|
@@ -155,9 +189,9 @@ module Cloudenvoy
|
|
155
189
|
#
|
156
190
|
# @return [Cloudenvoy::Message] The created message.
|
157
191
|
#
|
158
|
-
def publish
|
192
|
+
def publish(&block)
|
159
193
|
# Format and publish message
|
160
|
-
resp = execute_middleware_chain
|
194
|
+
resp = execute_middleware_chain(&block)
|
161
195
|
|
162
196
|
# Log job completion and return result
|
163
197
|
logger.info("Published message in #{publishing_duration}s") { { duration: publishing_duration } }
|
@@ -191,14 +225,14 @@ module Cloudenvoy
|
|
191
225
|
#
|
192
226
|
# Execute the subscriber process method through the middleware chain.
|
193
227
|
#
|
194
|
-
# @return [
|
228
|
+
# @return [Cloudenvoy::Message] The published message.
|
195
229
|
#
|
196
|
-
def execute_middleware_chain
|
230
|
+
def execute_middleware_chain(&block)
|
197
231
|
self.publishing_started_at = Time.now
|
198
232
|
|
199
233
|
Cloudenvoy.config.publisher_middleware.invoke(self) do
|
200
234
|
begin
|
201
|
-
publish_message
|
235
|
+
block_given? ? block.call : publish_message
|
202
236
|
rescue StandardError => e
|
203
237
|
logger.error([e, e.backtrace.join("\n")].join("\n"))
|
204
238
|
try(:on_error, e)
|
@@ -9,7 +9,7 @@ module Cloudenvoy
|
|
9
9
|
# @return [Proc] The context processor proc.
|
10
10
|
#
|
11
11
|
def self.default_context_processor
|
12
|
-
@default_context_processor ||= ->(loggable) { loggable.message
|
12
|
+
@default_context_processor ||= ->(loggable) { loggable.message.to_h&.slice(:id, :metadata, :topic) || {} }
|
13
13
|
end
|
14
14
|
|
15
15
|
#
|
data/lib/cloudenvoy/version.rb
CHANGED
data/lib/cloudenvoy.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support/core_ext/string/inflections'
|
4
|
+
require 'active_support/core_ext/object/try'
|
4
5
|
|
5
6
|
require 'cloudenvoy/version'
|
6
7
|
require 'cloudenvoy/config'
|
@@ -62,6 +63,18 @@ module Cloudenvoy
|
|
62
63
|
PubSubClient.publish(topic, payload, attrs)
|
63
64
|
end
|
64
65
|
|
66
|
+
#
|
67
|
+
# Publish multiple messages to a topic. Shorthand method to Cloudenvoy::PubSubClient#publish_all.
|
68
|
+
#
|
69
|
+
# @param [String] topic The name of the topic
|
70
|
+
# @param [Array<Array<[Hash, String]>>] msg_args A list of message [payload, metadata].
|
71
|
+
#
|
72
|
+
# @return [Array<Cloudenvoy::Message>] The published messages.
|
73
|
+
#
|
74
|
+
def self.publish_all(topic, msg_args)
|
75
|
+
PubSubClient.publish_all(topic, msg_args)
|
76
|
+
end
|
77
|
+
|
65
78
|
#
|
66
79
|
# Return the list of registered publishers.
|
67
80
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudenvoy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arnaud Lachaume
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - '='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
117
|
+
version: 0.93.0
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - '='
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0.
|
124
|
+
version: 0.93.0
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: rubocop-rspec
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,48 +178,6 @@ dependencies:
|
|
178
178
|
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
|
-
- !ruby/object:Gem::Dependency
|
182
|
-
name: rails
|
183
|
-
requirement: !ruby/object:Gem::Requirement
|
184
|
-
requirements:
|
185
|
-
- - ">="
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: '0'
|
188
|
-
type: :development
|
189
|
-
prerelease: false
|
190
|
-
version_requirements: !ruby/object:Gem::Requirement
|
191
|
-
requirements:
|
192
|
-
- - ">="
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: '0'
|
195
|
-
- !ruby/object:Gem::Dependency
|
196
|
-
name: rspec-rails
|
197
|
-
requirement: !ruby/object:Gem::Requirement
|
198
|
-
requirements:
|
199
|
-
- - ">="
|
200
|
-
- !ruby/object:Gem::Version
|
201
|
-
version: '0'
|
202
|
-
type: :development
|
203
|
-
prerelease: false
|
204
|
-
version_requirements: !ruby/object:Gem::Requirement
|
205
|
-
requirements:
|
206
|
-
- - ">="
|
207
|
-
- !ruby/object:Gem::Version
|
208
|
-
version: '0'
|
209
|
-
- !ruby/object:Gem::Dependency
|
210
|
-
name: sqlite3
|
211
|
-
requirement: !ruby/object:Gem::Requirement
|
212
|
-
requirements:
|
213
|
-
- - ">="
|
214
|
-
- !ruby/object:Gem::Version
|
215
|
-
version: '0'
|
216
|
-
type: :development
|
217
|
-
prerelease: false
|
218
|
-
version_requirements: !ruby/object:Gem::Requirement
|
219
|
-
requirements:
|
220
|
-
- - ">="
|
221
|
-
- !ruby/object:Gem::Version
|
222
|
-
version: '0'
|
223
181
|
description: Cross-application messaging using GCP Pub/Sub (alpha)
|
224
182
|
email:
|
225
183
|
- arnaud.lachaume@keypup.io
|
@@ -227,7 +185,10 @@ executables: []
|
|
227
185
|
extensions: []
|
228
186
|
extra_rdoc_files: []
|
229
187
|
files:
|
230
|
-
- ".github/workflows/
|
188
|
+
- ".github/workflows/lint_rubocop.yml"
|
189
|
+
- ".github/workflows/test_ruby_2.5_2.6.yml"
|
190
|
+
- ".github/workflows/test_ruby_2.7.yml"
|
191
|
+
- ".github/workflows/test_ruby_3.x.yml"
|
231
192
|
- ".gitignore"
|
232
193
|
- ".rspec"
|
233
194
|
- ".rubocop.yml"
|
@@ -318,18 +279,15 @@ files:
|
|
318
279
|
- examples/sinatra/app/subscribers/hello_subscriber.rb
|
319
280
|
- examples/sinatra/bin/console
|
320
281
|
- examples/sinatra/config/initializers/cloudenvoy.rb
|
282
|
+
- gemfiles/.bundle/config
|
321
283
|
- gemfiles/rails_5.2.gemfile
|
322
|
-
- gemfiles/rails_5.2.gemfile.lock
|
323
284
|
- gemfiles/rails_6.0.gemfile
|
324
|
-
- gemfiles/rails_6.
|
285
|
+
- gemfiles/rails_6.1.gemfile
|
286
|
+
- gemfiles/rails_7.0.gemfile
|
325
287
|
- gemfiles/semantic_logger_3.4.gemfile
|
326
|
-
- gemfiles/semantic_logger_3.4.gemfile.lock
|
327
288
|
- gemfiles/semantic_logger_4.6.gemfile
|
328
|
-
- gemfiles/semantic_logger_4.6.gemfile.lock
|
329
289
|
- gemfiles/semantic_logger_4.7.0.gemfile
|
330
|
-
- gemfiles/semantic_logger_4.7.0.gemfile.lock
|
331
290
|
- gemfiles/semantic_logger_4.7.2.gemfile
|
332
|
-
- gemfiles/semantic_logger_4.7.2.gemfile.lock
|
333
291
|
- lib/cloudenvoy.rb
|
334
292
|
- lib/cloudenvoy/authentication_error.rb
|
335
293
|
- lib/cloudenvoy/authenticator.rb
|
@@ -372,14 +330,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
372
330
|
requirements:
|
373
331
|
- - ">="
|
374
332
|
- !ruby/object:Gem::Version
|
375
|
-
version: 2.
|
333
|
+
version: 2.4.0
|
376
334
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
377
335
|
requirements:
|
378
|
-
- - "
|
336
|
+
- - ">"
|
379
337
|
- !ruby/object:Gem::Version
|
380
|
-
version:
|
338
|
+
version: 1.3.1
|
381
339
|
requirements: []
|
382
|
-
rubygems_version: 3.
|
340
|
+
rubygems_version: 3.2.3
|
383
341
|
signing_key:
|
384
342
|
specification_version: 4
|
385
343
|
summary: Cross-application messaging using GCP Pub/Sub (alpha)
|
@@ -1,264 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: ..
|
3
|
-
specs:
|
4
|
-
cloudenvoy (0.4.1)
|
5
|
-
activesupport
|
6
|
-
google-cloud-pubsub (~> 2.0)
|
7
|
-
jwt
|
8
|
-
retriable
|
9
|
-
|
10
|
-
GEM
|
11
|
-
remote: https://rubygems.org/
|
12
|
-
specs:
|
13
|
-
actioncable (5.2.0)
|
14
|
-
actionpack (= 5.2.0)
|
15
|
-
nio4r (~> 2.0)
|
16
|
-
websocket-driver (>= 0.6.1)
|
17
|
-
actionmailer (5.2.0)
|
18
|
-
actionpack (= 5.2.0)
|
19
|
-
actionview (= 5.2.0)
|
20
|
-
activejob (= 5.2.0)
|
21
|
-
mail (~> 2.5, >= 2.5.4)
|
22
|
-
rails-dom-testing (~> 2.0)
|
23
|
-
actionpack (5.2.0)
|
24
|
-
actionview (= 5.2.0)
|
25
|
-
activesupport (= 5.2.0)
|
26
|
-
rack (~> 2.0)
|
27
|
-
rack-test (>= 0.6.3)
|
28
|
-
rails-dom-testing (~> 2.0)
|
29
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
30
|
-
actionview (5.2.0)
|
31
|
-
activesupport (= 5.2.0)
|
32
|
-
builder (~> 3.1)
|
33
|
-
erubi (~> 1.4)
|
34
|
-
rails-dom-testing (~> 2.0)
|
35
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
36
|
-
activejob (5.2.0)
|
37
|
-
activesupport (= 5.2.0)
|
38
|
-
globalid (>= 0.3.6)
|
39
|
-
activemodel (5.2.0)
|
40
|
-
activesupport (= 5.2.0)
|
41
|
-
activerecord (5.2.0)
|
42
|
-
activemodel (= 5.2.0)
|
43
|
-
activesupport (= 5.2.0)
|
44
|
-
arel (>= 9.0)
|
45
|
-
activestorage (5.2.0)
|
46
|
-
actionpack (= 5.2.0)
|
47
|
-
activerecord (= 5.2.0)
|
48
|
-
marcel (~> 0.3.1)
|
49
|
-
activesupport (5.2.0)
|
50
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
51
|
-
i18n (>= 0.7, < 2)
|
52
|
-
minitest (~> 5.1)
|
53
|
-
tzinfo (~> 1.1)
|
54
|
-
addressable (2.7.0)
|
55
|
-
public_suffix (>= 2.0.2, < 5.0)
|
56
|
-
appraisal (2.4.0)
|
57
|
-
bundler
|
58
|
-
rake
|
59
|
-
thor (>= 0.14.0)
|
60
|
-
arel (9.0.0)
|
61
|
-
ast (2.4.2)
|
62
|
-
builder (3.2.4)
|
63
|
-
concurrent-ruby (1.1.8)
|
64
|
-
crack (0.4.5)
|
65
|
-
rexml
|
66
|
-
crass (1.0.6)
|
67
|
-
diff-lcs (1.4.4)
|
68
|
-
erubi (1.10.0)
|
69
|
-
faraday (1.4.1)
|
70
|
-
faraday-excon (~> 1.1)
|
71
|
-
faraday-net_http (~> 1.0)
|
72
|
-
faraday-net_http_persistent (~> 1.1)
|
73
|
-
multipart-post (>= 1.2, < 3)
|
74
|
-
ruby2_keywords (>= 0.0.4)
|
75
|
-
faraday-excon (1.1.0)
|
76
|
-
faraday-net_http (1.0.1)
|
77
|
-
faraday-net_http_persistent (1.1.0)
|
78
|
-
gapic-common (0.4.1)
|
79
|
-
faraday (~> 1.3)
|
80
|
-
google-protobuf (~> 3.15, >= 3.15.2)
|
81
|
-
googleapis-common-protos (>= 1.3.11, < 2.0)
|
82
|
-
googleapis-common-protos-types (>= 1.0.6, < 2.0)
|
83
|
-
googleauth (~> 0.15, >= 0.15.1)
|
84
|
-
grpc (~> 1.36)
|
85
|
-
globalid (0.4.2)
|
86
|
-
activesupport (>= 4.2.0)
|
87
|
-
google-cloud-core (1.6.0)
|
88
|
-
google-cloud-env (~> 1.0)
|
89
|
-
google-cloud-errors (~> 1.0)
|
90
|
-
google-cloud-env (1.5.0)
|
91
|
-
faraday (>= 0.17.3, < 2.0)
|
92
|
-
google-cloud-errors (1.1.0)
|
93
|
-
google-cloud-pubsub (2.5.0)
|
94
|
-
concurrent-ruby (~> 1.1)
|
95
|
-
google-cloud-core (~> 1.5)
|
96
|
-
google-cloud-pubsub-v1 (~> 0.0)
|
97
|
-
google-cloud-pubsub-v1 (0.4.0)
|
98
|
-
gapic-common (~> 0.3)
|
99
|
-
google-cloud-errors (~> 1.0)
|
100
|
-
grpc-google-iam-v1 (>= 0.6.10, < 2.0)
|
101
|
-
google-protobuf (3.15.8)
|
102
|
-
googleapis-common-protos (1.3.11)
|
103
|
-
google-protobuf (~> 3.14)
|
104
|
-
googleapis-common-protos-types (>= 1.0.6, < 2.0)
|
105
|
-
grpc (~> 1.27)
|
106
|
-
googleapis-common-protos-types (1.0.6)
|
107
|
-
google-protobuf (~> 3.14)
|
108
|
-
googleauth (0.16.1)
|
109
|
-
faraday (>= 0.17.3, < 2.0)
|
110
|
-
jwt (>= 1.4, < 3.0)
|
111
|
-
memoist (~> 0.16)
|
112
|
-
multi_json (~> 1.11)
|
113
|
-
os (>= 0.9, < 2.0)
|
114
|
-
signet (~> 0.14)
|
115
|
-
grpc (1.37.0)
|
116
|
-
google-protobuf (~> 3.15)
|
117
|
-
googleapis-common-protos-types (~> 1.0)
|
118
|
-
grpc-google-iam-v1 (0.6.11)
|
119
|
-
google-protobuf (~> 3.14)
|
120
|
-
googleapis-common-protos (>= 1.3.11, < 2.0)
|
121
|
-
grpc (~> 1.27)
|
122
|
-
hashdiff (1.0.1)
|
123
|
-
i18n (1.8.10)
|
124
|
-
concurrent-ruby (~> 1.0)
|
125
|
-
jaro_winkler (1.5.4)
|
126
|
-
jwt (2.2.2)
|
127
|
-
loofah (2.9.1)
|
128
|
-
crass (~> 1.0.2)
|
129
|
-
nokogiri (>= 1.5.9)
|
130
|
-
mail (2.7.1)
|
131
|
-
mini_mime (>= 0.1.1)
|
132
|
-
marcel (0.3.3)
|
133
|
-
mimemagic (~> 0.3.2)
|
134
|
-
memoist (0.16.2)
|
135
|
-
method_source (1.0.0)
|
136
|
-
mimemagic (0.3.10)
|
137
|
-
nokogiri (~> 1)
|
138
|
-
rake
|
139
|
-
mini_mime (1.1.0)
|
140
|
-
mini_portile2 (2.5.0)
|
141
|
-
minitest (5.14.4)
|
142
|
-
multi_json (1.15.0)
|
143
|
-
multipart-post (2.1.1)
|
144
|
-
nio4r (2.5.7)
|
145
|
-
nokogiri (1.11.3)
|
146
|
-
mini_portile2 (~> 2.5.0)
|
147
|
-
racc (~> 1.4)
|
148
|
-
os (1.1.1)
|
149
|
-
parallel (1.20.1)
|
150
|
-
parser (3.0.1.0)
|
151
|
-
ast (~> 2.4.1)
|
152
|
-
public_suffix (4.0.6)
|
153
|
-
racc (1.5.2)
|
154
|
-
rack (2.2.3)
|
155
|
-
rack-test (1.1.0)
|
156
|
-
rack (>= 1.0, < 3)
|
157
|
-
rails (5.2.0)
|
158
|
-
actioncable (= 5.2.0)
|
159
|
-
actionmailer (= 5.2.0)
|
160
|
-
actionpack (= 5.2.0)
|
161
|
-
actionview (= 5.2.0)
|
162
|
-
activejob (= 5.2.0)
|
163
|
-
activemodel (= 5.2.0)
|
164
|
-
activerecord (= 5.2.0)
|
165
|
-
activestorage (= 5.2.0)
|
166
|
-
activesupport (= 5.2.0)
|
167
|
-
bundler (>= 1.3.0)
|
168
|
-
railties (= 5.2.0)
|
169
|
-
sprockets-rails (>= 2.0.0)
|
170
|
-
rails-dom-testing (2.0.3)
|
171
|
-
activesupport (>= 4.2.0)
|
172
|
-
nokogiri (>= 1.6)
|
173
|
-
rails-html-sanitizer (1.3.0)
|
174
|
-
loofah (~> 2.3)
|
175
|
-
railties (5.2.0)
|
176
|
-
actionpack (= 5.2.0)
|
177
|
-
activesupport (= 5.2.0)
|
178
|
-
method_source
|
179
|
-
rake (>= 0.8.7)
|
180
|
-
thor (>= 0.18.1, < 2.0)
|
181
|
-
rainbow (3.0.0)
|
182
|
-
rake (13.0.3)
|
183
|
-
retriable (3.1.2)
|
184
|
-
rexml (3.2.5)
|
185
|
-
rspec (3.10.0)
|
186
|
-
rspec-core (~> 3.10.0)
|
187
|
-
rspec-expectations (~> 3.10.0)
|
188
|
-
rspec-mocks (~> 3.10.0)
|
189
|
-
rspec-core (3.10.1)
|
190
|
-
rspec-support (~> 3.10.0)
|
191
|
-
rspec-expectations (3.10.1)
|
192
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
193
|
-
rspec-support (~> 3.10.0)
|
194
|
-
rspec-mocks (3.10.2)
|
195
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
196
|
-
rspec-support (~> 3.10.0)
|
197
|
-
rspec-rails (5.0.1)
|
198
|
-
actionpack (>= 5.2)
|
199
|
-
activesupport (>= 5.2)
|
200
|
-
railties (>= 5.2)
|
201
|
-
rspec-core (~> 3.10)
|
202
|
-
rspec-expectations (~> 3.10)
|
203
|
-
rspec-mocks (~> 3.10)
|
204
|
-
rspec-support (~> 3.10)
|
205
|
-
rspec-support (3.10.2)
|
206
|
-
rubocop (0.76.0)
|
207
|
-
jaro_winkler (~> 1.5.1)
|
208
|
-
parallel (~> 1.10)
|
209
|
-
parser (>= 2.6)
|
210
|
-
rainbow (>= 2.2.2, < 4.0)
|
211
|
-
ruby-progressbar (~> 1.7)
|
212
|
-
unicode-display_width (>= 1.4.0, < 1.7)
|
213
|
-
rubocop-rspec (1.37.0)
|
214
|
-
rubocop (>= 0.68.1)
|
215
|
-
ruby-progressbar (1.11.0)
|
216
|
-
ruby2_keywords (0.0.4)
|
217
|
-
semantic_logger (4.7.4)
|
218
|
-
concurrent-ruby (~> 1.0)
|
219
|
-
signet (0.15.0)
|
220
|
-
addressable (~> 2.3)
|
221
|
-
faraday (>= 0.17.3, < 2.0)
|
222
|
-
jwt (>= 1.5, < 3.0)
|
223
|
-
multi_json (~> 1.10)
|
224
|
-
sprockets (4.0.2)
|
225
|
-
concurrent-ruby (~> 1.0)
|
226
|
-
rack (> 1, < 3)
|
227
|
-
sprockets-rails (3.2.2)
|
228
|
-
actionpack (>= 4.0)
|
229
|
-
activesupport (>= 4.0)
|
230
|
-
sprockets (>= 3.0.0)
|
231
|
-
sqlite3 (1.4.2)
|
232
|
-
thor (1.1.0)
|
233
|
-
thread_safe (0.3.6)
|
234
|
-
timecop (0.9.4)
|
235
|
-
tzinfo (1.2.9)
|
236
|
-
thread_safe (~> 0.1)
|
237
|
-
unicode-display_width (1.6.1)
|
238
|
-
webmock (3.12.2)
|
239
|
-
addressable (>= 2.3.6)
|
240
|
-
crack (>= 0.3.2)
|
241
|
-
hashdiff (>= 0.4.0, < 2.0.0)
|
242
|
-
websocket-driver (0.7.3)
|
243
|
-
websocket-extensions (>= 0.1.0)
|
244
|
-
websocket-extensions (0.1.5)
|
245
|
-
|
246
|
-
PLATFORMS
|
247
|
-
ruby
|
248
|
-
|
249
|
-
DEPENDENCIES
|
250
|
-
appraisal
|
251
|
-
cloudenvoy!
|
252
|
-
rails (= 5.2)
|
253
|
-
rake (>= 12.3.3)
|
254
|
-
rspec (~> 3.0)
|
255
|
-
rspec-rails
|
256
|
-
rubocop (= 0.76.0)
|
257
|
-
rubocop-rspec (= 1.37.0)
|
258
|
-
semantic_logger
|
259
|
-
sqlite3
|
260
|
-
timecop
|
261
|
-
webmock
|
262
|
-
|
263
|
-
BUNDLED WITH
|
264
|
-
2.2.9
|