fbe 0.21.1 → 0.21.2
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 +23 -23
- data/lib/fbe/if_absent.rb +5 -1
- data/lib/fbe/octo.rb +57 -49
- data/lib/fbe.rb +1 -1
- data/test/fbe/test_if_absent.rb +18 -0
- data/test/fbe/test_octo.rb +44 -12
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6593e4483941c4ff99de6f85aab33f62832d4293b1efb2a8e84d0b78ad79147
|
4
|
+
data.tar.gz: 134ceee60e4eb50c33b8c71194ffa0464c822e07884bd230776e5c59f025e2f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a43a4fb0ef720d9e459d348437c7d3824625fae9aad064c768885fc945d25e0ba68b0034132c97dd0835bf93edbcd960d64d4aa9f9bbd31af5c5589f2121ef44
|
7
|
+
data.tar.gz: 5f76047d167636f220b5bcab707b2f69bbe47a471b5954a4dbe324055fb08556cec5470ac7d1d9bb22da436b91d69056b5205bf485b4ca3b63ea212eb0f649ad
|
data/Gemfile.lock
CHANGED
@@ -43,18 +43,18 @@ GEM
|
|
43
43
|
ast (2.4.3)
|
44
44
|
backtrace (0.4.1)
|
45
45
|
base64 (0.3.0)
|
46
|
-
baza.rb (0.5
|
47
|
-
backtrace (
|
48
|
-
elapsed (
|
49
|
-
faraday (
|
50
|
-
faraday-http-cache (
|
51
|
-
faraday-multipart (
|
52
|
-
faraday-retry (
|
53
|
-
iri (
|
54
|
-
loog (
|
55
|
-
retries (~> 0)
|
56
|
-
tago (~> 0)
|
57
|
-
typhoeus (~> 1.
|
46
|
+
baza.rb (0.9.5)
|
47
|
+
backtrace (~> 0.4)
|
48
|
+
elapsed (~> 0.0)
|
49
|
+
faraday (~> 2.13)
|
50
|
+
faraday-http-cache (~> 2.5)
|
51
|
+
faraday-multipart (~> 1.1)
|
52
|
+
faraday-retry (~> 2.3)
|
53
|
+
iri (~> 0.11)
|
54
|
+
loog (~> 0.6)
|
55
|
+
retries (~> 0.0)
|
56
|
+
tago (~> 0.0)
|
57
|
+
typhoeus (~> 1.4)
|
58
58
|
benchmark (0.4.1)
|
59
59
|
bigdecimal (3.2.2)
|
60
60
|
builder (3.3.0)
|
@@ -87,11 +87,11 @@ GEM
|
|
87
87
|
logger
|
88
88
|
faraday-http-cache (2.5.1)
|
89
89
|
faraday (>= 0.8)
|
90
|
-
faraday-multipart (1.1.
|
90
|
+
faraday-multipart (1.1.1)
|
91
91
|
multipart-post (~> 2.0)
|
92
|
-
faraday-net_http (3.4.
|
92
|
+
faraday-net_http (3.4.1)
|
93
93
|
net-http (>= 0.5.0)
|
94
|
-
faraday-retry (2.3.
|
94
|
+
faraday-retry (2.3.2)
|
95
95
|
faraday (~> 2.0)
|
96
96
|
ffi (1.17.2-arm64-darwin)
|
97
97
|
ffi (1.17.2-x64-mingw-ucrt)
|
@@ -112,7 +112,7 @@ GEM
|
|
112
112
|
concurrent-ruby (~> 1.0)
|
113
113
|
iri (0.11.2)
|
114
114
|
json (2.12.2)
|
115
|
-
judges (0.
|
115
|
+
judges (0.50.3)
|
116
116
|
backtrace (~> 0.4)
|
117
117
|
baza.rb (~> 0.5)
|
118
118
|
concurrent-ruby (~> 1.2)
|
@@ -131,7 +131,7 @@ GEM
|
|
131
131
|
typhoeus (~> 1.3)
|
132
132
|
language_server-protocol (3.17.0.5)
|
133
133
|
lint_roller (1.1.0)
|
134
|
-
liquid (5.8.
|
134
|
+
liquid (5.8.7)
|
135
135
|
bigdecimal
|
136
136
|
strscan (>= 3.1.1)
|
137
137
|
logger (1.7.0)
|
@@ -161,8 +161,8 @@ GEM
|
|
161
161
|
faraday (>= 1, < 3)
|
162
162
|
sawyer (~> 0.9)
|
163
163
|
os (1.1.4)
|
164
|
-
ostruct (0.6.
|
165
|
-
others (0.
|
164
|
+
ostruct (0.6.2)
|
165
|
+
others (0.1.1)
|
166
166
|
parallel (1.27.0)
|
167
167
|
parser (3.3.8.0)
|
168
168
|
ast (~> 2.4.1)
|
@@ -219,10 +219,10 @@ GEM
|
|
219
219
|
simplecov (~> 0.19)
|
220
220
|
simplecov-html (0.13.1)
|
221
221
|
simplecov_json_formatter (0.1.4)
|
222
|
-
sqlite3 (2.
|
223
|
-
sqlite3 (2.
|
224
|
-
sqlite3 (2.
|
225
|
-
sqlite3 (2.
|
222
|
+
sqlite3 (2.7.0-arm64-darwin)
|
223
|
+
sqlite3 (2.7.0-x64-mingw-ucrt)
|
224
|
+
sqlite3 (2.7.0-x86_64-darwin)
|
225
|
+
sqlite3 (2.7.0-x86_64-linux-gnu)
|
226
226
|
strscan (3.1.5)
|
227
227
|
tago (0.1.0)
|
228
228
|
timeout (0.4.3)
|
data/lib/fbe/if_absent.rb
CHANGED
@@ -51,7 +51,11 @@ def Fbe.if_absent(fb: Fbe.fb)
|
|
51
51
|
others(map: attrs) do |*args|
|
52
52
|
k = args[0]
|
53
53
|
if k.end_with?('=')
|
54
|
-
|
54
|
+
k = k[0..-2].to_sym
|
55
|
+
v = args[1]
|
56
|
+
raise "Can't set #{k} to nil" if v.nil?
|
57
|
+
raise "Can't set #{k} to empty string" if v.is_a?(String) && v.empty?
|
58
|
+
@map[k] = v
|
55
59
|
else
|
56
60
|
@map[k.to_sym]
|
57
61
|
end
|
data/lib/fbe/octo.rb
CHANGED
@@ -10,6 +10,7 @@ require 'faraday/retry'
|
|
10
10
|
require 'loog'
|
11
11
|
require 'obk'
|
12
12
|
require 'octokit'
|
13
|
+
require 'others'
|
13
14
|
require 'uri'
|
14
15
|
require 'verbose'
|
15
16
|
require_relative '../fbe'
|
@@ -116,62 +117,69 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
116
117
|
loog.debug('The connection to GitHub API is mocked')
|
117
118
|
o = Fbe::FakeOctokit.new
|
118
119
|
end
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
@
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
120
|
+
o =
|
121
|
+
decoor(o, loog:, trace:) do
|
122
|
+
def print_trace!
|
123
|
+
if @trace.empty?
|
124
|
+
@loog.debug('GitHub API trace is empty')
|
125
|
+
else
|
126
|
+
grouped =
|
127
|
+
@trace.group_by do |entry|
|
128
|
+
uri = URI.parse(entry[:url])
|
129
|
+
"#{uri.scheme}://#{uri.host}#{uri.path}"
|
130
|
+
end
|
131
|
+
message = grouped
|
132
|
+
.sort_by { |_path, entries| -entries.count }
|
133
|
+
.map { |path, entries| " #{path}: #{entries.count}" }
|
134
|
+
.join("\n")
|
135
|
+
@loog.info("GitHub API trace (#{grouped.count} URLs vs #{@trace.count} requests):\n#{message}")
|
136
|
+
@trace.clear
|
137
|
+
end
|
135
138
|
end
|
136
|
-
end
|
137
139
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
140
|
+
def off_quota?(threshold: 50)
|
141
|
+
left = @origin.rate_limit.remaining
|
142
|
+
if left < threshold
|
143
|
+
@loog.info("Too much GitHub API quota consumed already (#{left} < #{threshold}), stopping")
|
144
|
+
true
|
145
|
+
else
|
146
|
+
@loog.debug("Still #{left} GitHub API quota left (>#{threshold})")
|
147
|
+
false
|
148
|
+
end
|
146
149
|
end
|
147
|
-
end
|
148
150
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
151
|
+
def user_name_by_id(id)
|
152
|
+
raise 'The ID of the user is nil' if id.nil?
|
153
|
+
raise 'The ID of the user must be an Integer' unless id.is_a?(Integer)
|
154
|
+
json = @origin.user(id)
|
155
|
+
name = json[:login].downcase
|
156
|
+
@loog.debug("GitHub user ##{id} has a name: @#{name}")
|
157
|
+
name
|
158
|
+
end
|
157
159
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
160
|
+
def repo_id_by_name(name)
|
161
|
+
raise 'The name of the repo is nil' if name.nil?
|
162
|
+
json = @origin.repository(name)
|
163
|
+
id = json[:id]
|
164
|
+
@loog.debug("GitHub repository #{name.inspect} has an ID: ##{id}")
|
165
|
+
id
|
166
|
+
end
|
165
167
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
168
|
+
def repo_name_by_id(id)
|
169
|
+
raise 'The ID of the repo is nil' if id.nil?
|
170
|
+
raise 'The ID of the repo must be an Integer' unless id.is_a?(Integer)
|
171
|
+
json = @origin.repository(id)
|
172
|
+
name = json[:full_name].downcase
|
173
|
+
@loog.debug("GitHub repository ##{id} has a name: #{name}")
|
174
|
+
name
|
175
|
+
end
|
173
176
|
end
|
174
|
-
|
177
|
+
o =
|
178
|
+
others(o:) do |*args|
|
179
|
+
raise "We are off-quota (remaining: #{@o.rate_limit.remaining})" if args.first != :off_quota? && @o.off_quota?
|
180
|
+
@o.__send__(*args)
|
181
|
+
end
|
182
|
+
o
|
175
183
|
end
|
176
184
|
end
|
177
185
|
|
data/lib/fbe.rb
CHANGED
data/test/fbe/test_if_absent.rb
CHANGED
@@ -24,6 +24,24 @@ class TestIfAbsent < Fbe::Test
|
|
24
24
|
assert_nil(n)
|
25
25
|
end
|
26
26
|
|
27
|
+
def test_raises_on_empty_value
|
28
|
+
assert_raises(StandardError) do
|
29
|
+
Fbe.if_absent(fb: Factbase.new) do |f|
|
30
|
+
f.foo = ''
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_raises_on_nil
|
36
|
+
fb = Factbase.new
|
37
|
+
fb.insert.foo = 42
|
38
|
+
assert_raises(StandardError) do
|
39
|
+
Fbe.if_absent(fb: Factbase.new) do |f|
|
40
|
+
f.foo = nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
27
45
|
def test_ignores_with_time
|
28
46
|
fb = Factbase.new
|
29
47
|
t = Time.now
|
data/test/fbe/test_octo.rb
CHANGED
@@ -53,6 +53,9 @@ class TestOcto < Fbe::Test
|
|
53
53
|
|
54
54
|
def test_reads_nickname_by_id
|
55
55
|
WebMock.disable_net_connect!
|
56
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
57
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
58
|
+
)
|
56
59
|
global = {}
|
57
60
|
o = Fbe.octo(loog: Loog::NULL, global:, options: Judges::Options.new)
|
58
61
|
stub_request(:get, 'https://api.github.com/user/42').to_return(
|
@@ -64,6 +67,9 @@ class TestOcto < Fbe::Test
|
|
64
67
|
|
65
68
|
def test_reads_repo_name_by_id
|
66
69
|
WebMock.disable_net_connect!
|
70
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
71
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
72
|
+
)
|
67
73
|
global = {}
|
68
74
|
o = Fbe.octo(loog: Loog::NULL, global:, options: Judges::Options.new)
|
69
75
|
stub_request(:get, 'https://api.github.com/repositories/42').to_return(
|
@@ -75,10 +81,16 @@ class TestOcto < Fbe::Test
|
|
75
81
|
|
76
82
|
def test_caching
|
77
83
|
WebMock.disable_net_connect!
|
84
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
85
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
86
|
+
)
|
78
87
|
global = {}
|
79
88
|
o = Fbe.octo(loog: Loog::NULL, global:, options: Judges::Options.new)
|
80
89
|
stub_request(:get, 'https://api.github.com/users/yegor256')
|
81
|
-
.to_return(
|
90
|
+
.to_return(
|
91
|
+
body: '{}',
|
92
|
+
headers: { 'Cache-Control' => 'public, max-age=60', 'etag' => 'abc', 'x-ratelimit-remaining' => '10000' }
|
93
|
+
)
|
82
94
|
.times(1)
|
83
95
|
.then
|
84
96
|
.to_raise('second request should be cached, not passed to GitHub API!')
|
@@ -144,6 +156,9 @@ class TestOcto < Fbe::Test
|
|
144
156
|
|
145
157
|
def test_retrying
|
146
158
|
WebMock.disable_net_connect!
|
159
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
160
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
161
|
+
)
|
147
162
|
global = {}
|
148
163
|
o = Fbe.octo(loog: Loog::NULL, global:, options: Judges::Options.new)
|
149
164
|
stub_request(:get, 'https://api.github.com/users/yegor256')
|
@@ -156,6 +171,9 @@ class TestOcto < Fbe::Test
|
|
156
171
|
|
157
172
|
def test_retrying_on_error_response
|
158
173
|
WebMock.disable_net_connect!
|
174
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
175
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
176
|
+
)
|
159
177
|
global = {}
|
160
178
|
o = Fbe.octo(loog: Loog::NULL, global:, options: Judges::Options.new)
|
161
179
|
stub_request(:get, 'https://api.github.com/users/yegor256')
|
@@ -203,6 +221,9 @@ class TestOcto < Fbe::Test
|
|
203
221
|
|
204
222
|
def test_pauses_when_quota_is_exceeded
|
205
223
|
WebMock.disable_net_connect!
|
224
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
225
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
226
|
+
)
|
206
227
|
o = Fbe.octo(loog: Loog::NULL, global: {}, options: Judges::Options.new({ 'github_api_pause' => 0.01 }))
|
207
228
|
stub_request(:get, 'https://api.github.com/users/foo')
|
208
229
|
.to_return(
|
@@ -215,8 +236,6 @@ class TestOcto < Fbe::Test
|
|
215
236
|
)
|
216
237
|
o.user('foo')
|
217
238
|
assert_predicate(o, :off_quota?)
|
218
|
-
o.user('foo')
|
219
|
-
refute_predicate(o, :off_quota?)
|
220
239
|
end
|
221
240
|
|
222
241
|
def test_fetches_fake_check_runs_for_ref
|
@@ -327,13 +346,18 @@ class TestOcto < Fbe::Test
|
|
327
346
|
def test_print_trace
|
328
347
|
loog = Loog::Buffer.new
|
329
348
|
WebMock.disable_net_connect!
|
349
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
350
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
351
|
+
)
|
330
352
|
stub_request(:get, 'https://api.github.com/user/123').to_return(
|
331
353
|
status: 200,
|
332
|
-
body: '{"id":123,"login":"test"}'
|
354
|
+
body: '{"id":123,"login":"test"}',
|
355
|
+
headers: { 'X-RateLimit-Remaining' => '222' }
|
333
356
|
)
|
334
357
|
stub_request(:get, 'https://api.github.com/repos/foo/bar').to_return(
|
335
358
|
status: 200,
|
336
|
-
body: '{"id":456,"full_name":"foo/bar"}'
|
359
|
+
body: '{"id":456,"full_name":"foo/bar"}',
|
360
|
+
headers: { 'X-RateLimit-Remaining' => '222' }
|
337
361
|
)
|
338
362
|
octo = Fbe.octo(loog:, global: {}, options: Judges::Options.new)
|
339
363
|
octo.user(123)
|
@@ -341,7 +365,7 @@ class TestOcto < Fbe::Test
|
|
341
365
|
octo.repository('foo/bar')
|
342
366
|
octo.print_trace!
|
343
367
|
output = loog.to_s
|
344
|
-
assert_includes output, 'GitHub API trace (
|
368
|
+
assert_includes output, 'GitHub API trace (3 URLs vs 4 requests)'
|
345
369
|
assert_includes output, 'https://api.github.com/user/123: 1'
|
346
370
|
assert_includes output, 'https://api.github.com/repos/foo/bar: 2'
|
347
371
|
repo_index = output.index('https://api.github.com/repos/foo/bar: 2')
|
@@ -351,9 +375,13 @@ class TestOcto < Fbe::Test
|
|
351
375
|
|
352
376
|
def test_trace_gets_cleared_after_print
|
353
377
|
WebMock.disable_net_connect!
|
378
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
379
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
380
|
+
)
|
354
381
|
stub_request(:get, 'https://api.github.com/user/456').to_return(
|
355
382
|
status: 200,
|
356
|
-
body: '{"id":456,"login":"testuser"}'
|
383
|
+
body: '{"id":456,"login":"testuser"}',
|
384
|
+
headers: { 'X-RateLimit-Remaining' => '222' }
|
357
385
|
)
|
358
386
|
first_loog = Loog::Buffer.new
|
359
387
|
octo = Fbe.octo(loog: first_loog, global: {}, options: Judges::Options.new)
|
@@ -361,15 +389,13 @@ class TestOcto < Fbe::Test
|
|
361
389
|
octo.print_trace!
|
362
390
|
first_output = first_loog.to_s
|
363
391
|
assert_includes first_output, 'GitHub API trace'
|
364
|
-
second_loog = Loog::Buffer.new
|
365
|
-
octo.instance_variable_set(:@loog, second_loog)
|
366
|
-
octo.print_trace!
|
367
|
-
second_output = second_loog.to_s
|
368
|
-
assert_includes second_output, 'GitHub API trace is empty'
|
369
392
|
end
|
370
393
|
|
371
394
|
def test_works_via_sqlite_store
|
372
395
|
WebMock.disable_net_connect!
|
396
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
397
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
398
|
+
)
|
373
399
|
Dir.mktmpdir do |dir|
|
374
400
|
global = {}
|
375
401
|
sqlite_cache = File.expand_path('test.db', dir)
|
@@ -394,6 +420,9 @@ class TestOcto < Fbe::Test
|
|
394
420
|
|
395
421
|
def test_through_sqlite_store_when_broken_token
|
396
422
|
WebMock.disable_net_connect!
|
423
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
424
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
425
|
+
)
|
397
426
|
Dir.mktmpdir do |dir|
|
398
427
|
global = {}
|
399
428
|
file = File.expand_path('test.db', dir)
|
@@ -408,6 +437,9 @@ class TestOcto < Fbe::Test
|
|
408
437
|
|
409
438
|
def test_sqlite_store_for_use_in_different_versions
|
410
439
|
WebMock.disable_net_connect!
|
440
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
441
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
442
|
+
)
|
411
443
|
Dir.mktmpdir do |dir|
|
412
444
|
global = {}
|
413
445
|
stub =
|