fbe 0.30.0 → 0.31.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 +4 -4
- data/fbe.gemspec +1 -1
- data/lib/fbe/conclude.rb +27 -10
- data/lib/fbe.rb +1 -1
- metadata +1 -31
- data/renovate.json +0 -6
- data/test/fbe/middleware/test_formatter.rb +0 -104
- data/test/fbe/middleware/test_rate_limit.rb +0 -152
- data/test/fbe/middleware/test_sqlite_store.rb +0 -446
- data/test/fbe/middleware/test_trace.rb +0 -168
- data/test/fbe/test_award.rb +0 -126
- data/test/fbe/test_bylaws.rb +0 -111
- data/test/fbe/test_conclude.rb +0 -172
- data/test/fbe/test_copy.rb +0 -39
- data/test/fbe/test_delete.rb +0 -117
- data/test/fbe/test_delete_one.rb +0 -56
- data/test/fbe/test_enter.rb +0 -35
- data/test/fbe/test_fb.rb +0 -102
- data/test/fbe/test_github_graph.rb +0 -169
- data/test/fbe/test_if_absent.rb +0 -107
- data/test/fbe/test_issue.rb +0 -26
- data/test/fbe/test_iterate.rb +0 -253
- data/test/fbe/test_just_one.rb +0 -33
- data/test/fbe/test_kill_if.rb +0 -39
- data/test/fbe/test_octo.rb +0 -791
- data/test/fbe/test_overwrite.rb +0 -103
- data/test/fbe/test_pmp.rb +0 -34
- data/test/fbe/test_regularly.rb +0 -27
- data/test/fbe/test_repeatedly.rb +0 -31
- data/test/fbe/test_sec.rb +0 -21
- data/test/fbe/test_tombstone.rb +0 -56
- data/test/fbe/test_unmask_repos.rb +0 -66
- data/test/fbe/test_who.rb +0 -25
- data/test/test__helper.rb +0 -45
- data/test/test_fbe.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2621af2f5ed4213f7137482238a6c1fc2af0f534a88b196e277cdf17bb9d27de
|
4
|
+
data.tar.gz: 65bfa710cd5680c579207ea1ce650c25ed743b39b835ce1500cd1b62d7d57fd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0d04610b4d6bd1bf32587b73baade530e6b22aead4fffe69f0bd6067f254d4f0899701ed84bf8a38f2fc9798ab39708d71a05d0a9681d001da5d12e8c4d47e5
|
7
|
+
data.tar.gz: dc62b030009940330564967622a9e0c16f16bce715d0fcd9e00cb54a7e617a24bfd68e70409b98fcc7cfbcc70c1ff356286b4047530ebcf808fe2f20c68b1f55
|
data/fbe.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.authors = ['Yegor Bugayenko']
|
20
20
|
s.email = 'yegor256@gmail.com'
|
21
21
|
s.homepage = 'https://github.com/zerocracy/fbe'
|
22
|
-
s.files = `git ls-files`.split($RS)
|
22
|
+
s.files = `git ls-files | grep -v -E '^(test/|renovate|coverage)'`.split($RS)
|
23
23
|
s.rdoc_options = ['--charset=UTF-8']
|
24
24
|
s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
|
25
25
|
s.add_dependency 'backtrace', '~>0.4'
|
data/lib/fbe/conclude.rb
CHANGED
@@ -17,13 +17,16 @@ require_relative 'octo'
|
|
17
17
|
# @param [Judges::Options] options The options coming from the +judges+ tool
|
18
18
|
# @param [Loog] loog The logging facility
|
19
19
|
# @yield [Factbase::Fact] The fact
|
20
|
-
def Fbe.conclude(
|
20
|
+
def Fbe.conclude(
|
21
|
+
fb: Fbe.fb, judge: $judge, loog: $loog, options: $options, global: $global,
|
22
|
+
start: $start, time: Time, &
|
23
|
+
)
|
21
24
|
raise 'The fb is nil' if fb.nil?
|
22
25
|
raise 'The $judge is not set' if judge.nil?
|
23
26
|
raise 'The $global is not set' if global.nil?
|
24
27
|
raise 'The $options is not set' if options.nil?
|
25
28
|
raise 'The $loog is not set' if loog.nil?
|
26
|
-
c = Fbe::Conclude.new(fb:, judge:, loog:, options:, global:, time:)
|
29
|
+
c = Fbe::Conclude.new(fb:, judge:, loog:, options:, global:, start:, time:)
|
27
30
|
c.instance_eval(&)
|
28
31
|
end
|
29
32
|
|
@@ -59,28 +62,38 @@ class Fbe::Conclude
|
|
59
62
|
# @param [Judges::Options] options The options coming from the +judges+ tool
|
60
63
|
# @param [Loog] loog The logging facility
|
61
64
|
# @param [Time] time The time
|
62
|
-
def initialize(fb:, judge:, global:, options:, loog:, time: Time)
|
65
|
+
def initialize(fb:, judge:, global:, options:, loog:, start:, time: Time)
|
63
66
|
@fb = fb
|
64
67
|
@judge = judge
|
65
68
|
@loog = loog
|
66
69
|
@options = options
|
67
70
|
@global = global
|
71
|
+
@start = start
|
68
72
|
@query = nil
|
69
73
|
@follows = []
|
70
|
-
@
|
74
|
+
@lifetime_aware = true
|
75
|
+
@quota_aware = true
|
71
76
|
@timeout = 60
|
72
77
|
@time = time
|
73
78
|
end
|
74
79
|
|
75
|
-
# Make this block aware of GitHub API quota.
|
80
|
+
# Make this block not aware of GitHub API quota.
|
76
81
|
#
|
77
|
-
# When the quota is reached, the loop will gracefully stop to avoid
|
78
|
-
# hitting GitHub API rate limits.
|
79
|
-
# in long-running operations.
|
82
|
+
# When the quota is reached, the loop will NOT gracefully stop to avoid
|
83
|
+
# hitting GitHub API rate limits.
|
80
84
|
#
|
81
85
|
# @return [nil] Nothing is returned
|
82
|
-
def
|
83
|
-
@quota_aware =
|
86
|
+
def quota_unaware
|
87
|
+
@quota_aware = false
|
88
|
+
end
|
89
|
+
|
90
|
+
# Make this block NOT aware of lifetime limitations.
|
91
|
+
#
|
92
|
+
# When the lifetime is over, the loop will NOT gracefully stop.
|
93
|
+
#
|
94
|
+
# @return [nil] Nothing is returned
|
95
|
+
def lifetime_aware
|
96
|
+
@lifetime_aware = false
|
84
97
|
end
|
85
98
|
|
86
99
|
# Make sure this block runs for less than allowed amount of seconds.
|
@@ -189,6 +202,10 @@ class Fbe::Conclude
|
|
189
202
|
@loog.debug('We ran out of GitHub quota, must stop here')
|
190
203
|
break
|
191
204
|
end
|
205
|
+
if @lifetime_aware && @options.lifetime && Time.now - @start > @options.lifetime - 10
|
206
|
+
@loog.debug('We ran out of lifetime, must stop here')
|
207
|
+
break
|
208
|
+
end
|
192
209
|
now = @time.now
|
193
210
|
if now > start + @timeout
|
194
211
|
@loog.debug("We've spent more than #{start.ago}, must stop here")
|
data/lib/fbe.rb
CHANGED
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.
|
4
|
+
version: 0.31.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
@@ -391,37 +391,7 @@ files:
|
|
391
391
|
- lib/fbe/tombstone.rb
|
392
392
|
- lib/fbe/unmask_repos.rb
|
393
393
|
- lib/fbe/who.rb
|
394
|
-
- renovate.json
|
395
394
|
- rules/basic.fe
|
396
|
-
- test/fbe/middleware/test_formatter.rb
|
397
|
-
- test/fbe/middleware/test_rate_limit.rb
|
398
|
-
- test/fbe/middleware/test_sqlite_store.rb
|
399
|
-
- test/fbe/middleware/test_trace.rb
|
400
|
-
- test/fbe/test_award.rb
|
401
|
-
- test/fbe/test_bylaws.rb
|
402
|
-
- test/fbe/test_conclude.rb
|
403
|
-
- test/fbe/test_copy.rb
|
404
|
-
- test/fbe/test_delete.rb
|
405
|
-
- test/fbe/test_delete_one.rb
|
406
|
-
- test/fbe/test_enter.rb
|
407
|
-
- test/fbe/test_fb.rb
|
408
|
-
- test/fbe/test_github_graph.rb
|
409
|
-
- test/fbe/test_if_absent.rb
|
410
|
-
- test/fbe/test_issue.rb
|
411
|
-
- test/fbe/test_iterate.rb
|
412
|
-
- test/fbe/test_just_one.rb
|
413
|
-
- test/fbe/test_kill_if.rb
|
414
|
-
- test/fbe/test_octo.rb
|
415
|
-
- test/fbe/test_overwrite.rb
|
416
|
-
- test/fbe/test_pmp.rb
|
417
|
-
- test/fbe/test_regularly.rb
|
418
|
-
- test/fbe/test_repeatedly.rb
|
419
|
-
- test/fbe/test_sec.rb
|
420
|
-
- test/fbe/test_tombstone.rb
|
421
|
-
- test/fbe/test_unmask_repos.rb
|
422
|
-
- test/fbe/test_who.rb
|
423
|
-
- test/test__helper.rb
|
424
|
-
- test/test_fbe.rb
|
425
395
|
homepage: https://github.com/zerocracy/fbe
|
426
396
|
licenses:
|
427
397
|
- MIT
|
data/renovate.json
DELETED
@@ -1,104 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
|
-
# SPDX-License-Identifier: MIT
|
5
|
-
|
6
|
-
require 'faraday'
|
7
|
-
require 'loog'
|
8
|
-
require 'securerandom'
|
9
|
-
require_relative '../../../lib/fbe'
|
10
|
-
require_relative '../../../lib/fbe/middleware'
|
11
|
-
require_relative '../../../lib/fbe/middleware/formatter'
|
12
|
-
require_relative '../../test__helper'
|
13
|
-
|
14
|
-
# Test.
|
15
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
16
|
-
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
17
|
-
# License:: MIT
|
18
|
-
class LoggingFormatterTest < Fbe::Test
|
19
|
-
def test_success_response
|
20
|
-
log_it(status: 200) do |loog|
|
21
|
-
assert_empty(loog.to_s)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_forward_response
|
26
|
-
log_it(status: 303) do |loog|
|
27
|
-
assert_empty(loog.to_s)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_error_response
|
32
|
-
log_it(status: 401) do |loog|
|
33
|
-
str = loog.to_s
|
34
|
-
refute_empty(str)
|
35
|
-
[
|
36
|
-
%r{http://example.com},
|
37
|
-
/Authorization:/,
|
38
|
-
%r{HTTP/1.1 401},
|
39
|
-
/x-github-api-version-selected: "2022-11-28"/,
|
40
|
-
/hello, world!/,
|
41
|
-
/request body/
|
42
|
-
].each { |ptn| assert_match(ptn, str) }
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_limit_response
|
47
|
-
log_it(status: 403) do |loog|
|
48
|
-
str = loog.to_s
|
49
|
-
refute_empty(str)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_truncate_body_for_error_text_response
|
54
|
-
body = SecureRandom.alphanumeric(120)
|
55
|
-
log_it(
|
56
|
-
status: 502,
|
57
|
-
response_body: body,
|
58
|
-
response_headers: {
|
59
|
-
'content-type' => 'text/html; charset=utf-8',
|
60
|
-
'x-github-api-version-selected' => '2022-11-28'
|
61
|
-
}
|
62
|
-
) do |loog|
|
63
|
-
str = loog.to_s
|
64
|
-
refute_empty(str)
|
65
|
-
[
|
66
|
-
%r{http://example.com},
|
67
|
-
/Authorization:/,
|
68
|
-
/some request body/,
|
69
|
-
%r{HTTP/1.1 502},
|
70
|
-
/x-github-api-version-selected: "2022-11-28"/,
|
71
|
-
%r{content-type: "text/html; charset=utf-8"},
|
72
|
-
"#{body.slice(0, 97)}..."
|
73
|
-
].each { |ptn| assert_match(ptn, str) }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def log_it(
|
80
|
-
status:,
|
81
|
-
method: :get,
|
82
|
-
response_body: '{"message": "hello, world!"}',
|
83
|
-
response_headers: { 'content-type' => 'application/json', 'x-github-api-version-selected' => '2022-11-28' }
|
84
|
-
)
|
85
|
-
loog = Loog::Buffer.new
|
86
|
-
formatter = Fbe::Middleware::Formatter.new(logger: loog, options: {})
|
87
|
-
formatter.request(
|
88
|
-
Faraday::Env.from(
|
89
|
-
{
|
90
|
-
method:,
|
91
|
-
request_body: 'some request body',
|
92
|
-
url: URI('http://example.com'),
|
93
|
-
request_headers: {
|
94
|
-
'Authorization' => 'Bearer github_pat_11AAsecret'
|
95
|
-
}
|
96
|
-
}
|
97
|
-
)
|
98
|
-
)
|
99
|
-
formatter.response(
|
100
|
-
Faraday::Env.from({ status:, response_body:, response_headers: })
|
101
|
-
)
|
102
|
-
yield loog
|
103
|
-
end
|
104
|
-
end
|
@@ -1,152 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
|
-
# SPDX-License-Identifier: MIT
|
5
|
-
|
6
|
-
require 'faraday'
|
7
|
-
require 'webmock'
|
8
|
-
require_relative '../../../lib/fbe'
|
9
|
-
require_relative '../../../lib/fbe/middleware'
|
10
|
-
require_relative '../../../lib/fbe/middleware/rate_limit'
|
11
|
-
require_relative '../../test__helper'
|
12
|
-
|
13
|
-
# Test.
|
14
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
15
|
-
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
16
|
-
# License:: MIT
|
17
|
-
class RateLimitTest < Fbe::Test
|
18
|
-
def test_caches_rate_limit_response_on_first_call
|
19
|
-
rate_limit_response = {
|
20
|
-
'rate' => {
|
21
|
-
'limit' => 5000,
|
22
|
-
'remaining' => 4999,
|
23
|
-
'reset' => 1_672_531_200
|
24
|
-
}
|
25
|
-
}
|
26
|
-
stub_request(:get, 'https://api.github.com/rate_limit')
|
27
|
-
.to_return(status: 200, body: rate_limit_response.to_json, headers: { 'Content-Type' => 'application/json' })
|
28
|
-
conn = create_connection
|
29
|
-
response = conn.get('/rate_limit')
|
30
|
-
assert_equal 200, response.status
|
31
|
-
assert_equal 4999, response.body['rate']['remaining']
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_returns_cached_response_on_subsequent_calls
|
35
|
-
rate_limit_response = {
|
36
|
-
'rate' => {
|
37
|
-
'limit' => 5000,
|
38
|
-
'remaining' => 4999,
|
39
|
-
'reset' => 1_672_531_200
|
40
|
-
}
|
41
|
-
}
|
42
|
-
stub_request(:get, 'https://api.github.com/rate_limit')
|
43
|
-
.to_return(status: 200, body: rate_limit_response.to_json, headers: { 'Content-Type' => 'application/json' })
|
44
|
-
.times(1)
|
45
|
-
conn = create_connection
|
46
|
-
conn.get('/rate_limit')
|
47
|
-
response = conn.get('/rate_limit')
|
48
|
-
assert_equal 200, response.status
|
49
|
-
assert_equal 4999, response.body['rate']['remaining']
|
50
|
-
assert_requested :get, 'https://api.github.com/rate_limit', times: 1
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_decrements_remaining_count_for_non_rate_limit_requests
|
54
|
-
rate_limit_response = {
|
55
|
-
'rate' => {
|
56
|
-
'limit' => 5000,
|
57
|
-
'remaining' => 4999,
|
58
|
-
'reset' => 1_672_531_200
|
59
|
-
}
|
60
|
-
}
|
61
|
-
stub_request(:get, 'https://api.github.com/rate_limit')
|
62
|
-
.to_return(status: 200, body: rate_limit_response.to_json, headers: { 'Content-Type' => 'application/json',
|
63
|
-
'X-RateLimit-Remaining' => '4999' })
|
64
|
-
stub_request(:get, 'https://api.github.com/user')
|
65
|
-
.to_return(status: 200, body: '{"login": "test"}', headers: { 'Content-Type' => 'application/json' })
|
66
|
-
conn = create_connection
|
67
|
-
conn.get('/rate_limit')
|
68
|
-
conn.get('/user')
|
69
|
-
response = conn.get('/rate_limit')
|
70
|
-
assert_equal 4998, response.body['rate']['remaining']
|
71
|
-
assert_equal '4998', response.headers['x-ratelimit-remaining']
|
72
|
-
end
|
73
|
-
|
74
|
-
def test_refreshes_cache_after_hundred_requests
|
75
|
-
rate_limit_response = {
|
76
|
-
'rate' => {
|
77
|
-
'limit' => 5000,
|
78
|
-
'remaining' => 4999,
|
79
|
-
'reset' => 1_672_531_200
|
80
|
-
}
|
81
|
-
}
|
82
|
-
refreshed_response = {
|
83
|
-
'rate' => {
|
84
|
-
'limit' => 5000,
|
85
|
-
'remaining' => 4950,
|
86
|
-
'reset' => 1_672_531_200
|
87
|
-
}
|
88
|
-
}
|
89
|
-
stub_request(:get, 'https://api.github.com/rate_limit')
|
90
|
-
.to_return(status: 200, body: rate_limit_response.to_json, headers: { 'Content-Type' => 'application/json' })
|
91
|
-
.then
|
92
|
-
.to_return(status: 200, body: refreshed_response.to_json, headers: { 'Content-Type' => 'application/json' })
|
93
|
-
stub_request(:get, 'https://api.github.com/user')
|
94
|
-
.to_return(status: 200, body: '{"login": "test"}', headers: { 'Content-Type' => 'application/json' })
|
95
|
-
.times(100)
|
96
|
-
conn = create_connection
|
97
|
-
conn.get('/rate_limit')
|
98
|
-
100.times { conn.get('/user') }
|
99
|
-
response = conn.get('/rate_limit')
|
100
|
-
assert_equal 4950, response.body['rate']['remaining']
|
101
|
-
assert_requested :get, 'https://api.github.com/rate_limit', times: 2
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_handles_response_without_rate_data
|
105
|
-
stub_request(:get, 'https://api.github.com/rate_limit')
|
106
|
-
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
107
|
-
conn = create_connection
|
108
|
-
response = conn.get('/rate_limit')
|
109
|
-
assert_equal 200, response.status
|
110
|
-
assert_empty(response.body)
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_ignores_non_hash_response_body
|
114
|
-
stub_request(:get, 'https://api.github.com/rate_limit')
|
115
|
-
.to_return(status: 200, body: 'invalid json', headers: { 'Content-Type' => 'text/plain' })
|
116
|
-
conn = create_connection
|
117
|
-
response = conn.get('/rate_limit')
|
118
|
-
assert_equal 200, response.status
|
119
|
-
assert_equal 'invalid json', response.body
|
120
|
-
end
|
121
|
-
|
122
|
-
def test_handles_zero_remaining_count
|
123
|
-
rate_limit_response = {
|
124
|
-
'rate' => {
|
125
|
-
'limit' => 5000,
|
126
|
-
'remaining' => 1,
|
127
|
-
'reset' => 1_672_531_200
|
128
|
-
}
|
129
|
-
}
|
130
|
-
stub_request(:get, 'https://api.github.com/rate_limit')
|
131
|
-
.to_return(status: 200, body: rate_limit_response.to_json, headers: { 'Content-Type' => 'application/json' })
|
132
|
-
stub_request(:get, 'https://api.github.com/user')
|
133
|
-
.to_return(status: 200, body: '{"login": "test"}', headers: { 'Content-Type' => 'application/json' })
|
134
|
-
.times(2)
|
135
|
-
conn = create_connection
|
136
|
-
conn.get('/rate_limit')
|
137
|
-
conn.get('/user')
|
138
|
-
conn.get('/user')
|
139
|
-
response = conn.get('/rate_limit')
|
140
|
-
assert_equal 0, response.body['rate']['remaining']
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
|
145
|
-
def create_connection
|
146
|
-
Faraday.new(url: 'https://api.github.com') do |f|
|
147
|
-
f.use Fbe::Middleware::RateLimit
|
148
|
-
f.response :json
|
149
|
-
f.adapter :net_http
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|