fbe 0.23.2 → 0.23.4
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/Gemfile.lock +2 -0
- data/fbe.gemspec +1 -0
- data/lib/fbe/middleware/trace.rb +5 -9
- data/lib/fbe/octo.rb +22 -11
- data/lib/fbe.rb +1 -1
- data/test/fbe/test_conclude.rb +6 -2
- data/test/fbe/test_octo.rb +35 -7
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebe33dc4f8380eeabe72495993dea6fe88842c8d062d7f41ce43111e664ba825
|
4
|
+
data.tar.gz: 2763f2c522defeb27a03bda9b15ec07d690721a663cb5bda91c2b07ea69b0b49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de77042cef4d5d7110fb13584e0b9765537dc156da8150c355a97f6d2b0b3212f8b46e8d20b24f96eacf3e1b93a30728e31514b731ca4fb6e92955046cc3f4b9
|
7
|
+
data.tar.gz: 5693137ce96120cad70e867b3e85655e29a4bc7d00e30435203f5c7b871e4b1248cd277190bb123dbcbe536beccbe99b72a4257da399a10f221ed0e4048e45b3
|
data/Gemfile.lock
CHANGED
@@ -13,6 +13,7 @@ PATH
|
|
13
13
|
faraday-retry (~> 2.3)
|
14
14
|
filesize (~> 0.2)
|
15
15
|
graphql-client (~> 0.26)
|
16
|
+
intercepted (~> 0.2)
|
16
17
|
judges (~> 0.46)
|
17
18
|
liquid (~> 5.5)
|
18
19
|
loog (~> 0.6)
|
@@ -115,6 +116,7 @@ GEM
|
|
115
116
|
hashdiff (1.2.0)
|
116
117
|
i18n (1.14.7)
|
117
118
|
concurrent-ruby (~> 1.0)
|
119
|
+
intercepted (0.2.0)
|
118
120
|
iri (0.11.2)
|
119
121
|
json (2.12.2)
|
120
122
|
judges (0.50.5)
|
data/fbe.gemspec
CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
|
|
33
33
|
s.add_dependency 'faraday-retry', '~>2.3'
|
34
34
|
s.add_dependency 'filesize', '~>0.2'
|
35
35
|
s.add_dependency 'graphql-client', '~>0.26'
|
36
|
+
s.add_dependency 'intercepted', '~>0.2'
|
36
37
|
s.add_dependency 'judges', '~>0.46'
|
37
38
|
s.add_dependency 'liquid', '~>5.5'
|
38
39
|
s.add_dependency 'loog', '~>0.6'
|
data/lib/fbe/middleware/trace.rb
CHANGED
@@ -31,11 +31,9 @@ class Fbe::Middleware::Trace < Faraday::Middleware
|
|
31
31
|
#
|
32
32
|
# @param [Object] app The next middleware in the stack
|
33
33
|
# @param [Array] trace The array to store trace entries
|
34
|
-
|
35
|
-
def initialize(app, trace, all: true)
|
34
|
+
def initialize(app, trace)
|
36
35
|
super(app)
|
37
36
|
@trace = trace
|
38
|
-
@all = all
|
39
37
|
end
|
40
38
|
|
41
39
|
# Processes the HTTP request and records trace information.
|
@@ -51,12 +49,10 @@ class Fbe::Middleware::Trace < Faraday::Middleware
|
|
51
49
|
@app.call(env).on_complete do |response_env|
|
52
50
|
finished = Time.now
|
53
51
|
duration = finished - entry[:started_at]
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
@trace << entry
|
59
|
-
end
|
52
|
+
entry[:status] = response_env.status
|
53
|
+
entry[:finished_at] = finished
|
54
|
+
entry[:duration] = duration
|
55
|
+
@trace << entry
|
60
56
|
end
|
61
57
|
end
|
62
58
|
end
|
data/lib/fbe/octo.rb
CHANGED
@@ -8,11 +8,13 @@ require 'ellipsized'
|
|
8
8
|
require 'faraday/http_cache'
|
9
9
|
require 'faraday/retry'
|
10
10
|
require 'filesize'
|
11
|
+
require 'intercepted'
|
11
12
|
require 'json'
|
12
13
|
require 'loog'
|
13
14
|
require 'obk'
|
14
15
|
require 'octokit'
|
15
16
|
require 'others'
|
17
|
+
require 'tago'
|
16
18
|
require 'uri'
|
17
19
|
require 'verbose'
|
18
20
|
require_relative '../fbe'
|
@@ -85,7 +87,7 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
85
87
|
)
|
86
88
|
if options.sqlite_cache
|
87
89
|
maxsize = Filesize.from(options.sqlite_cache_maxsize || '10M').to_i
|
88
|
-
maxvsize = Filesize.from(options.
|
90
|
+
maxvsize = Filesize.from(options.sqlite_cache_maxvsize || '10K').to_i
|
89
91
|
store = Fbe::Middleware::SqliteStore.new(options.sqlite_cache, Fbe::VERSION, loog:, maxsize:, maxvsize:)
|
90
92
|
loog.info(
|
91
93
|
"Using HTTP cache in SQLite file: #{store.path} (" \
|
@@ -105,7 +107,7 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
105
107
|
end
|
106
108
|
builder.use(Octokit::Response::RaiseError)
|
107
109
|
builder.use(Faraday::Response::Logger, loog, formatter: Fbe::Middleware::Formatter)
|
108
|
-
builder.use(Fbe::Middleware::Trace, trace
|
110
|
+
builder.use(Fbe::Middleware::Trace, trace)
|
109
111
|
builder.adapter(Faraday.default_adapter)
|
110
112
|
end
|
111
113
|
o.middleware = stack
|
@@ -122,12 +124,12 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
122
124
|
end
|
123
125
|
o =
|
124
126
|
decoor(o, loog:, trace:) do
|
125
|
-
def print_trace!
|
127
|
+
def print_trace!(all: false, max: 5)
|
126
128
|
if @trace.empty?
|
127
129
|
@loog.debug('GitHub API trace is empty')
|
128
130
|
else
|
129
131
|
grouped =
|
130
|
-
@trace.group_by do |entry|
|
132
|
+
@trace.select { |e| e[:duration] > 0.05 || all }.group_by do |entry|
|
131
133
|
uri = URI.parse(entry[:url])
|
132
134
|
query = uri.query
|
133
135
|
query = "?#{query.ellipsized(40)}" if query
|
@@ -135,18 +137,27 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
135
137
|
end
|
136
138
|
message = grouped
|
137
139
|
.sort_by { |_path, entries| -entries.count }
|
138
|
-
.map
|
140
|
+
.map do |path, entries|
|
141
|
+
[
|
142
|
+
' ',
|
143
|
+
path.gsub(%r{^https://api.github.com/}, '/'),
|
144
|
+
': ',
|
145
|
+
entries.count,
|
146
|
+
" (#{entries.sum { |e| e[:duration] }.seconds})"
|
147
|
+
].join
|
148
|
+
end
|
149
|
+
.take(max)
|
139
150
|
.join("\n")
|
140
151
|
@loog.info(
|
141
152
|
"GitHub API trace (#{grouped.count} URLs vs #{@trace.count} requests, " \
|
142
|
-
"#{@origin.rate_limit
|
153
|
+
"#{@origin.rate_limit!.remaining} quota left):\n#{message}"
|
143
154
|
)
|
144
155
|
@trace.clear
|
145
156
|
end
|
146
157
|
end
|
147
158
|
|
148
159
|
def off_quota?(threshold: 50)
|
149
|
-
left = @origin.rate_limit
|
160
|
+
left = @origin.rate_limit!.remaining
|
150
161
|
if left < threshold
|
151
162
|
@loog.info("Too much GitHub API quota consumed already (#{left} < #{threshold}), stopping")
|
152
163
|
true
|
@@ -183,11 +194,10 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
183
194
|
end
|
184
195
|
end
|
185
196
|
o =
|
186
|
-
|
187
|
-
if
|
188
|
-
raise "We are off-quota (remaining: #{
|
197
|
+
intercepted(o) do |e, m, _args, _r|
|
198
|
+
if e == :before && m != :off_quota? && m != :print_trace! && m != :rate_limit && o.off_quota?
|
199
|
+
raise "We are off-quota (remaining: #{o.rate_limit.remaining}), can't do #{name}()"
|
189
200
|
end
|
190
|
-
@o.__send__(*args)
|
191
201
|
end
|
192
202
|
o
|
193
203
|
end
|
@@ -248,6 +258,7 @@ class Fbe::FakeOctokit
|
|
248
258
|
end
|
249
259
|
o
|
250
260
|
end
|
261
|
+
alias rate_limit! rate_limit
|
251
262
|
|
252
263
|
# Lists repositories for a user or organization.
|
253
264
|
#
|
data/lib/fbe.rb
CHANGED
data/test/fbe/test_conclude.rb
CHANGED
@@ -79,8 +79,12 @@ class TestConclude < Fbe::Test
|
|
79
79
|
}
|
80
80
|
)
|
81
81
|
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
82
|
-
body: 'hm...', headers: { 'X-RateLimit-Remaining' => '777' }
|
83
|
-
|
82
|
+
{ body: 'hm...', headers: { 'X-RateLimit-Remaining' => '777' } },
|
83
|
+
{ body: 'hm...', headers: { 'X-RateLimit-Remaining' => '777' } },
|
84
|
+
{ body: 'hm...', headers: { 'X-RateLimit-Remaining' => '777' } },
|
85
|
+
{ body: 'hm...', headers: { 'X-RateLimit-Remaining' => '999' } },
|
86
|
+
{ body: 'hm...', headers: { 'X-RateLimit-Remaining' => '9' } }
|
87
|
+
)
|
84
88
|
global = {}
|
85
89
|
o = Fbe.octo(loog: Loog::NULL, options:, global:)
|
86
90
|
Fbe.conclude(fb:, judge: 'boom', loog: Loog::NULL, options:, global:) do
|
data/test/fbe/test_octo.rb
CHANGED
@@ -133,7 +133,9 @@ class TestOcto < Fbe::Test
|
|
133
133
|
def test_off_quota?
|
134
134
|
WebMock.disable_net_connect!
|
135
135
|
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
136
|
-
body: '{}', headers: { 'X-RateLimit-Remaining' => '333' }
|
136
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '333' } },
|
137
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '333' } },
|
138
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '3' } }
|
137
139
|
)
|
138
140
|
stub_request(:get, 'https://api.github.com/user/42').to_return(
|
139
141
|
body: '', headers: { 'X-RateLimit-Remaining' => '3' }
|
@@ -147,7 +149,11 @@ class TestOcto < Fbe::Test
|
|
147
149
|
def test_off_quota_twice
|
148
150
|
WebMock.disable_net_connect!
|
149
151
|
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
150
|
-
body: '{}', headers: { 'X-RateLimit-Remaining' => '333' }
|
152
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '333' } },
|
153
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '333' } },
|
154
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '333' } },
|
155
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '5555' } },
|
156
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '5' } }
|
151
157
|
)
|
152
158
|
stub_request(:get, 'https://api.github.com/user/42').to_return(
|
153
159
|
{ body: '', headers: { 'X-RateLimit-Remaining' => '5555' } },
|
@@ -239,7 +245,9 @@ class TestOcto < Fbe::Test
|
|
239
245
|
def test_pauses_when_quota_is_exceeded
|
240
246
|
WebMock.disable_net_connect!
|
241
247
|
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
242
|
-
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
248
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } },
|
249
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '1' } },
|
250
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '10000' } }
|
243
251
|
)
|
244
252
|
o = Fbe.octo(loog: Loog::NULL, global: {}, options: Judges::Options.new({ 'github_api_pause' => 0.01 }))
|
245
253
|
stub_request(:get, 'https://api.github.com/users/foo')
|
@@ -364,10 +372,11 @@ class TestOcto < Fbe::Test
|
|
364
372
|
loog = Loog::Buffer.new
|
365
373
|
WebMock.disable_net_connect!
|
366
374
|
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
375
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } },
|
376
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } },
|
367
377
|
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
368
378
|
)
|
369
379
|
stub_request(:get, 'https://api.github.com/user/123').to_return do
|
370
|
-
sleep(0.02)
|
371
380
|
{
|
372
381
|
status: 200,
|
373
382
|
body: '{"id":123,"login":"test"}',
|
@@ -375,7 +384,6 @@ class TestOcto < Fbe::Test
|
|
375
384
|
}
|
376
385
|
end
|
377
386
|
stub_request(:get, 'https://api.github.com/repos/foo/bar').to_return do
|
378
|
-
sleep(0.02)
|
379
387
|
{
|
380
388
|
status: 200,
|
381
389
|
body: '{"id":456,"full_name":"foo/bar"}',
|
@@ -386,10 +394,11 @@ class TestOcto < Fbe::Test
|
|
386
394
|
octo.user(123)
|
387
395
|
octo.repository('foo/bar')
|
388
396
|
octo.repository('foo/bar')
|
389
|
-
octo.print_trace!
|
397
|
+
octo.print_trace!(all: true, max: 9_999)
|
390
398
|
output = loog.to_s
|
391
|
-
assert_includes output, '
|
399
|
+
assert_includes output, '3 URLs vs 6 requests'
|
392
400
|
assert_includes output, '222 quota left'
|
401
|
+
assert_includes output, '/rate_limit: 3'
|
393
402
|
assert_includes output, '/user/123: 1'
|
394
403
|
assert_includes output, '/repos/foo/bar: 2'
|
395
404
|
repo_index = output.index('/repos/foo/bar: 2')
|
@@ -526,4 +535,23 @@ class TestOcto < Fbe::Test
|
|
526
535
|
end
|
527
536
|
end
|
528
537
|
end
|
538
|
+
|
539
|
+
def test_fetch_rate_limit_by_making_new_request
|
540
|
+
WebMock.disable_net_connect!
|
541
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
542
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '321' } }
|
543
|
+
).to_return(
|
544
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '123' } }
|
545
|
+
).to_return(
|
546
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '1' } }
|
547
|
+
).to_raise(StandardError.new('no more requests to https://api.github.com/rate_limit'))
|
548
|
+
loog = Loog::Buffer.new
|
549
|
+
o = Fbe.octo(loog:, global: {}, options: Judges::Options.new)
|
550
|
+
refute_predicate(o, :off_quota?)
|
551
|
+
assert_match(/321 GitHub API quota left/, loog.to_s)
|
552
|
+
o.print_trace!(all: true)
|
553
|
+
assert_match(/123 quota left/, loog.to_s)
|
554
|
+
assert_predicate(o, :off_quota?)
|
555
|
+
assert_match(/1 GitHub API quota left/, loog.to_s)
|
556
|
+
end
|
529
557
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fbe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
@@ -163,6 +163,20 @@ dependencies:
|
|
163
163
|
- - "~>"
|
164
164
|
- !ruby/object:Gem::Version
|
165
165
|
version: '0.26'
|
166
|
+
- !ruby/object:Gem::Dependency
|
167
|
+
name: intercepted
|
168
|
+
requirement: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - "~>"
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0.2'
|
173
|
+
type: :runtime
|
174
|
+
prerelease: false
|
175
|
+
version_requirements: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - "~>"
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0.2'
|
166
180
|
- !ruby/object:Gem::Dependency
|
167
181
|
name: judges
|
168
182
|
requirement: !ruby/object:Gem::Requirement
|