fbe 0.7.0 → 0.8.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/Gemfile.lock +6 -6
- data/assets/bylaws/code-contribution-was-rewarded.liquid +0 -13
- data/lib/fbe/conclude.rb +18 -14
- data/lib/fbe/enter.rb +4 -0
- data/lib/fbe/fb.rb +4 -0
- data/lib/fbe/issue.rb +4 -0
- data/lib/fbe/iterate.rb +4 -0
- data/lib/fbe/octo.rb +8 -4
- data/lib/fbe/overwrite.rb +1 -0
- data/lib/fbe/regularly.rb +5 -0
- data/lib/fbe/repeatedly.rb +5 -0
- data/lib/fbe.rb +1 -1
- data/test/fbe/test_bylaws.rb +1 -1
- data/test/fbe/test_conclude.rb +32 -0
- data/test/fbe/test_octo.rb +45 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 485d65ab1a72472bc118062f665516e8092e0f35b6b566acf567cad26259944c
|
4
|
+
data.tar.gz: c558708f7897da86b6c2133154cfb5861aa6fd1aeef8686eb109290de43b7b03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 684d4072dbe3ae3fc6043abbeddf6e0cce131948516df23a64b784777fa6a9a63e11e9eb09880116a4376be7d5292b2df983d472ae8d12bed00ea75c434a7c62
|
7
|
+
data.tar.gz: 56469e2fa299e1b411415b787b2edd3d19e75a7850a7a737dfb427505e8ec1c924a9e7935709d6bb05d13247e453eec25a5c5da84b7df15e9a5f4f29bf6f2dbf
|
data/Gemfile.lock
CHANGED
@@ -70,7 +70,7 @@ GEM
|
|
70
70
|
tago (> 0)
|
71
71
|
ethon (0.16.0)
|
72
72
|
ffi (>= 1.15.0)
|
73
|
-
factbase (0.
|
73
|
+
factbase (0.10.0)
|
74
74
|
backtrace (~> 0.4)
|
75
75
|
decoor (~> 0.0)
|
76
76
|
json (~> 2.7)
|
@@ -92,11 +92,11 @@ GEM
|
|
92
92
|
net-http (>= 0.5.0)
|
93
93
|
faraday-retry (2.3.1)
|
94
94
|
faraday (~> 2.0)
|
95
|
-
ffi (1.17.
|
96
|
-
ffi (1.17.
|
97
|
-
ffi (1.17.
|
98
|
-
ffi (1.17.
|
99
|
-
fiber-storage (1.0.
|
95
|
+
ffi (1.17.2-arm64-darwin)
|
96
|
+
ffi (1.17.2-x64-mingw-ucrt)
|
97
|
+
ffi (1.17.2-x86_64-darwin)
|
98
|
+
ffi (1.17.2-x86_64-linux-gnu)
|
99
|
+
fiber-storage (1.0.1)
|
100
100
|
gli (2.22.2)
|
101
101
|
ostruct
|
102
102
|
graphql (2.5.3)
|
@@ -51,19 +51,6 @@
|
|
51
51
|
(give bonus_for_comments "for too many (${comments}) comments that were made during review")
|
52
52
|
"deduct ${comments_k} points for every comment made during review, but not more than ${comments_max} points")
|
53
53
|
|
54
|
-
(aka
|
55
|
-
(let few_comments_fee {{ 2 | times: anger }})
|
56
|
-
(let comments_needed {{ 3 | times: paranoia }})
|
57
|
-
(set penalty_for_few_comments (if (and (lt comments comments_needed) (not (eq comments 0))) (times -1 few_comments_fee) 0))
|
58
|
-
(give penalty_for_few_comments "for very few (${comments}) comments")
|
59
|
-
"deduct ${few_comments_fee} points if there were less than ${comments_needed} comments made during review")
|
60
|
-
|
61
|
-
(aka
|
62
|
-
(let silence_fee {{ 8 | times: anger }})
|
63
|
-
(set penalty_for_silence (if (eq comments 0) (times -1 silence_fee) 0))
|
64
|
-
(give penalty_for_silence "for absolutely no comments posted by reviewers")
|
65
|
-
"deduct ${silence_fee} points if there were absolutely no comments made by reviewers during the review")
|
66
|
-
|
67
54
|
(aka
|
68
55
|
(let few_hoc_fee {{ 4 | times: anger }})
|
69
56
|
(let hoc_needed {{ 10 | times: paranoia }})
|
data/lib/fbe/conclude.rb
CHANGED
@@ -18,6 +18,11 @@ require_relative 'if_absent'
|
|
18
18
|
# @param [Loog] loog The logging facility
|
19
19
|
# @yield [Factbase::Fact] The fact
|
20
20
|
def Fbe.conclude(fb: Fbe.fb, judge: $judge, loog: $loog, options: $options, global: $global, &)
|
21
|
+
raise 'The fb is nil' if fb.nil?
|
22
|
+
raise 'The $judge is not set' if judge.nil?
|
23
|
+
raise 'The $global is not set' if global.nil?
|
24
|
+
raise 'The $options is not set' if options.nil?
|
25
|
+
raise 'The $loog is not set' if loog.nil?
|
21
26
|
c = Fbe::Conclude.new(fb:, judge:, loog:, options:, global:)
|
22
27
|
c.instance_eval(&)
|
23
28
|
end
|
@@ -160,21 +165,20 @@ class Fbe::Conclude
|
|
160
165
|
def roll(&)
|
161
166
|
passed = 0
|
162
167
|
start = Time.now
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
end
|
170
|
-
if Time.now > start + @timeout
|
171
|
-
@loog.debug("We've spent more than #{start.ago}, must stop here")
|
172
|
-
throw :stop
|
173
|
-
end
|
174
|
-
n = yield fbt, a
|
175
|
-
@loog.info("#{n.what}: #{n.details}") unless n.nil?
|
176
|
-
passed += 1
|
168
|
+
oct = Fbe.octo(loog: @loog, options: @options, global: @global)
|
169
|
+
@fb.txn do |fbt|
|
170
|
+
fbt.query(@query).each do |a|
|
171
|
+
if @quota_aware && oct.off_quota
|
172
|
+
@loog.debug('We ran out of GitHub quota, must stop here')
|
173
|
+
throw :commit
|
177
174
|
end
|
175
|
+
if Time.now > start + @timeout
|
176
|
+
@loog.debug("We've spent more than #{start.ago}, must stop here")
|
177
|
+
throw :commit
|
178
|
+
end
|
179
|
+
n = yield fbt, a
|
180
|
+
@loog.info("#{n.what}: #{n.details}") unless n.nil?
|
181
|
+
passed += 1
|
178
182
|
end
|
179
183
|
end
|
180
184
|
@loog.debug("Found and processed #{passed} facts by: #{@query}")
|
data/lib/fbe/enter.rb
CHANGED
@@ -14,6 +14,10 @@ require_relative '../fbe'
|
|
14
14
|
# @param [Loog] loog The logging facility
|
15
15
|
# @return [String] Full name of the user
|
16
16
|
def Fbe.enter(badge, why, options: $options, loog: $loog, &)
|
17
|
+
raise 'The badge is nil' if badge.nil?
|
18
|
+
raise 'The why is nil' if why.nil?
|
19
|
+
raise 'The $options is not set' if options.nil?
|
20
|
+
raise 'The $loog is not set' if loog.nil?
|
17
21
|
return yield unless options.testing.nil?
|
18
22
|
baza = BazaRb.new('api.zerocracy.com', 443, options.zerocracy_token, loog:)
|
19
23
|
baza.enter(options.job_name, badge, why, options.job_id.to_i, &)
|
data/lib/fbe/fb.rb
CHANGED
@@ -26,6 +26,10 @@ require_relative '../fbe'
|
|
26
26
|
# @param [Loog] loog The logging facility
|
27
27
|
# @return [Factbase] The global factbase
|
28
28
|
def Fbe.fb(fb: $fb, global: $global, options: $options, loog: $loog)
|
29
|
+
raise 'The fb is nil' if fb.nil?
|
30
|
+
raise 'The $global is not set' if global.nil?
|
31
|
+
raise 'The $options is not set' if options.nil?
|
32
|
+
raise 'The $loog is not set' if loog.nil?
|
29
33
|
global[:fb] ||=
|
30
34
|
begin
|
31
35
|
rules = Dir.glob(File.join('rules', '*.fe')).map { |f| File.read(f) }
|
data/lib/fbe/issue.rb
CHANGED
@@ -19,6 +19,10 @@ require_relative 'octo'
|
|
19
19
|
# @param [Loog] loog The logging facility
|
20
20
|
# @return [String] Textual representation of GitHub issue number
|
21
21
|
def Fbe.issue(fact, options: $options, global: $global, loog: $loog)
|
22
|
+
raise 'The fact is nil' if fact.nil?
|
23
|
+
raise 'The $global is not set' if global.nil?
|
24
|
+
raise 'The $options is not set' if options.nil?
|
25
|
+
raise 'The $loog is not set' if loog.nil?
|
22
26
|
rid = fact['repository']
|
23
27
|
raise "There is no 'repository' property" if rid.nil?
|
24
28
|
rid = rid.first.to_i
|
data/lib/fbe/iterate.rb
CHANGED
@@ -18,6 +18,10 @@ require_relative 'unmask_repos'
|
|
18
18
|
# @param [Loog] loog The logging facility
|
19
19
|
# @yield [Factbase::Fact] The fact
|
20
20
|
def Fbe.iterate(fb: Fbe.fb, loog: $loog, options: $options, global: $global, &)
|
21
|
+
raise 'The fb is nil' if fb.nil?
|
22
|
+
raise 'The $global is not set' if global.nil?
|
23
|
+
raise 'The $options is not set' if options.nil?
|
24
|
+
raise 'The $loog is not set' if loog.nil?
|
21
25
|
c = Fbe::Iterate.new(fb:, loog:, options:, global:)
|
22
26
|
c.instance_eval(&)
|
23
27
|
end
|
data/lib/fbe/octo.rb
CHANGED
@@ -26,6 +26,8 @@ require_relative 'middleware/formatter'
|
|
26
26
|
# @return [Hash] Usually returns a JSON, as it comes from the GitHub API
|
27
27
|
def Fbe.octo(options: $options, global: $global, loog: $loog)
|
28
28
|
raise 'The $global is not set' if global.nil?
|
29
|
+
raise 'The $options is not set' if options.nil?
|
30
|
+
raise 'The $loog is not set' if loog.nil?
|
29
31
|
global[:octo] ||=
|
30
32
|
begin
|
31
33
|
if options.testing.nil?
|
@@ -88,6 +90,7 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
88
90
|
@loog.info("Too much GitHub API quota consumed already (#{left} < #{threshold}), stopping")
|
89
91
|
true
|
90
92
|
else
|
93
|
+
@loog.debug("Still #{left} GitHub API quota left (>#{threshold})")
|
91
94
|
false
|
92
95
|
end
|
93
96
|
end
|
@@ -147,13 +150,14 @@ class Fbe::FakeOctokit
|
|
147
150
|
true
|
148
151
|
end
|
149
152
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
+
# Get details of the user.
|
154
|
+
# @param [String|Integer] uid The login of the user or its ID
|
155
|
+
def user(uid)
|
156
|
+
login = (uid == 526_301 ? 'yegor256' : 'torvalds') if uid.is_a?(Integer)
|
153
157
|
{
|
154
158
|
id: 444,
|
155
159
|
login:,
|
156
|
-
type:
|
160
|
+
type: uid == 29_139_614 ? 'Bot' : 'User'
|
157
161
|
}
|
158
162
|
end
|
159
163
|
|
data/lib/fbe/overwrite.rb
CHANGED
@@ -21,6 +21,7 @@ require_relative 'fb'
|
|
21
21
|
# @return [Factbase::Fact] Returns new fact or previous one
|
22
22
|
def Fbe.overwrite(fact, property, value, fb: Fbe.fb)
|
23
23
|
raise 'The fact is nil' if fact.nil?
|
24
|
+
raise 'The fb is nil' if fb.nil?
|
24
25
|
raise "The property is not a String but #{property.class} (#{property})" unless property.is_a?(String)
|
25
26
|
return fact if !fact[property].nil? && fact[property].size == 1 && fact[property].first == value
|
26
27
|
before = {}
|
data/lib/fbe/regularly.rb
CHANGED
@@ -16,6 +16,11 @@ require_relative 'fb'
|
|
16
16
|
# @param [Loog] loog The logging facility
|
17
17
|
# @return [nil] Nothing
|
18
18
|
def Fbe.regularly(area, p_every_days, p_since_days = nil, fb: Fbe.fb, judge: $judge, loog: $loog, &)
|
19
|
+
raise 'The area is nil' if area.nil?
|
20
|
+
raise 'The p_every_days is nil' if p_every_days.nil?
|
21
|
+
raise 'The fb is nil' if fb.nil?
|
22
|
+
raise 'The $judge is not set' if judge.nil?
|
23
|
+
raise 'The $loog is not set' if loog.nil?
|
19
24
|
pmp = fb.query("(and (eq what 'pmp') (eq area '#{area}') (exists #{p_every_days}))").each.to_a.first
|
20
25
|
interval = pmp.nil? ? 7 : pmp[p_every_days].first
|
21
26
|
unless fb.query(
|
data/lib/fbe/repeatedly.rb
CHANGED
@@ -16,6 +16,11 @@ require_relative 'overwrite'
|
|
16
16
|
# @param [Loog] loog The logging facility
|
17
17
|
# @return [nil] Nothing
|
18
18
|
def Fbe.repeatedly(area, p_every_hours, fb: Fbe.fb, judge: $judge, loog: $loog, &)
|
19
|
+
raise 'The area is nil' if area.nil?
|
20
|
+
raise 'The p_every_hours is nil' if p_every_hours.nil?
|
21
|
+
raise 'The fb is nil' if fb.nil?
|
22
|
+
raise 'The $judge is not set' if judge.nil?
|
23
|
+
raise 'The $loog is not set' if loog.nil?
|
19
24
|
pmp = fb.query("(and (eq what 'pmp') (eq area '#{area}') (exists #{p_every_hours}))").each.to_a.first
|
20
25
|
hours = pmp.nil? ? 24 : pmp[p_every_hours].first
|
21
26
|
unless fb.query(
|
data/lib/fbe.rb
CHANGED
data/test/fbe/test_bylaws.rb
CHANGED
@@ -61,7 +61,7 @@ class TestBylaws < Fbe::Test
|
|
61
61
|
{ hoc: 50, comments: 25, reviews: 0 } => 4,
|
62
62
|
{ hoc: 180, comments: 7, reviews: 2 } => 13,
|
63
63
|
{ hoc: 199, comments: 8, reviews: 3 } => 14,
|
64
|
-
{ hoc: 150, comments: 5, reviews: 1 } =>
|
64
|
+
{ hoc: 150, comments: 5, reviews: 1 } => 12,
|
65
65
|
{ hoc: 500, comments: 25, reviews: 2 } => 4,
|
66
66
|
{ hoc: 99, comments: 6, reviews: 1 } => 4,
|
67
67
|
{ hoc: 1_500, comments: 3, reviews: 0 } => 4,
|
data/test/fbe/test_conclude.rb
CHANGED
@@ -61,6 +61,38 @@ class TestConclude < Fbe::Test
|
|
61
61
|
assert_equal(42, f.bar)
|
62
62
|
end
|
63
63
|
|
64
|
+
def test_considers_until_quota
|
65
|
+
WebMock.disable_net_connect!
|
66
|
+
fb = Factbase.new
|
67
|
+
5.times do
|
68
|
+
fb.insert.foo = 1
|
69
|
+
end
|
70
|
+
options = Judges::Options.new
|
71
|
+
stub_request(:get, %r{https://api.github.com/users/.*}).to_return(
|
72
|
+
{
|
73
|
+
body: { id: rand(100) }.to_json,
|
74
|
+
headers: { 'Content-Type' => 'application/json', 'X-RateLimit-Remaining' => '999' }
|
75
|
+
},
|
76
|
+
{
|
77
|
+
body: { id: rand(100) }.to_json,
|
78
|
+
headers: { 'Content-Type' => 'application/json', 'X-RateLimit-Remaining' => '9' }
|
79
|
+
}
|
80
|
+
)
|
81
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
82
|
+
body: 'hm...', headers: { 'X-RateLimit-Remaining' => '777' }
|
83
|
+
).times(1)
|
84
|
+
global = {}
|
85
|
+
o = Fbe.octo(loog: Loog::NULL, options:, global:)
|
86
|
+
Fbe.conclude(fb:, judge: 'boom', loog: Loog::NULL, options:, global:) do
|
87
|
+
quota_aware
|
88
|
+
on '(exists foo)'
|
89
|
+
consider do |f|
|
90
|
+
f.bar = o.user("user-#{rand(100)}")[:id]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
assert_equal(2, fb.query('(exists bar)').each.to_a.size)
|
94
|
+
end
|
95
|
+
|
64
96
|
def test_ignores_globals
|
65
97
|
$fb = nil
|
66
98
|
$loog = nil
|
data/test/fbe/test_octo.rb
CHANGED
@@ -56,7 +56,7 @@ class TestOcto < Fbe::Test
|
|
56
56
|
global = {}
|
57
57
|
o = Fbe.octo(loog: Loog::NULL, global:, options: Judges::Options.new)
|
58
58
|
stub_request(:get, 'https://api.github.com/users/yegor256')
|
59
|
-
.to_return(
|
59
|
+
.to_return(body: '{}', headers: { 'Cache-Control' => 'public, max-age=60', 'etag' => 'abc' })
|
60
60
|
.times(1)
|
61
61
|
.then
|
62
62
|
.to_raise('second request should be cached, not passed to GitHub API!')
|
@@ -64,12 +64,50 @@ class TestOcto < Fbe::Test
|
|
64
64
|
o.user('yegor256')
|
65
65
|
end
|
66
66
|
|
67
|
+
def test_rate_limit_remaining
|
68
|
+
WebMock.disable_net_connect!
|
69
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
70
|
+
{ body: '{}', headers: { 'X-RateLimit-Remaining' => '222' } }
|
71
|
+
)
|
72
|
+
stub_request(:get, 'https://api.github.com/user/42').to_return(
|
73
|
+
body: '', headers: { 'X-RateLimit-Remaining' => '4' }
|
74
|
+
)
|
75
|
+
o = Octokit::Client.new
|
76
|
+
assert_equal(222, o.rate_limit.remaining)
|
77
|
+
o.user(42)
|
78
|
+
assert_equal(4, o.rate_limit.remaining)
|
79
|
+
assert_equal(4, o.rate_limit.remaining)
|
80
|
+
end
|
81
|
+
|
67
82
|
def test_off_quota
|
68
83
|
WebMock.disable_net_connect!
|
69
|
-
stub_request(:get, 'https://api.github.com/rate_limit')
|
70
|
-
|
84
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
85
|
+
body: '{}', headers: { 'X-RateLimit-Remaining' => '333' }
|
86
|
+
)
|
87
|
+
stub_request(:get, 'https://api.github.com/user/42').to_return(
|
88
|
+
body: '', headers: { 'X-RateLimit-Remaining' => '3' }
|
89
|
+
)
|
71
90
|
o = Fbe.octo(loog: Loog::NULL, global: {}, options: Judges::Options.new)
|
72
91
|
refute(o.off_quota)
|
92
|
+
o.user(42)
|
93
|
+
assert(o.off_quota)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_off_quota_twice
|
97
|
+
WebMock.disable_net_connect!
|
98
|
+
stub_request(:get, 'https://api.github.com/rate_limit').to_return(
|
99
|
+
body: '{}', headers: { 'X-RateLimit-Remaining' => '333' }
|
100
|
+
)
|
101
|
+
stub_request(:get, 'https://api.github.com/user/42').to_return(
|
102
|
+
{ body: '', headers: { 'X-RateLimit-Remaining' => '5555' } },
|
103
|
+
{ body: '', headers: { 'X-RateLimit-Remaining' => '5' } }
|
104
|
+
)
|
105
|
+
o = Fbe.octo(loog: Loog::VERBOSE, global: {}, options: Judges::Options.new)
|
106
|
+
refute(o.off_quota)
|
107
|
+
o.user(42)
|
108
|
+
refute(o.off_quota)
|
109
|
+
o.user(42)
|
110
|
+
assert(o.off_quota)
|
73
111
|
end
|
74
112
|
|
75
113
|
def test_retrying
|
@@ -80,7 +118,7 @@ class TestOcto < Fbe::Test
|
|
80
118
|
.to_raise(Octokit::TooManyRequests.new)
|
81
119
|
.times(1)
|
82
120
|
.then
|
83
|
-
.to_return(
|
121
|
+
.to_return(body: '{}')
|
84
122
|
o.user('yegor256')
|
85
123
|
end
|
86
124
|
|
@@ -92,7 +130,7 @@ class TestOcto < Fbe::Test
|
|
92
130
|
.to_return(status: 503)
|
93
131
|
.times(1)
|
94
132
|
.then
|
95
|
-
.to_return(
|
133
|
+
.to_return(body: '{}')
|
96
134
|
o.user('yegor256')
|
97
135
|
end
|
98
136
|
|
@@ -136,11 +174,11 @@ class TestOcto < Fbe::Test
|
|
136
174
|
o = Fbe.octo(loog: Loog::NULL, global: {}, options: Judges::Options.new({ 'github_api_pause' => 0.01 }))
|
137
175
|
stub_request(:get, 'https://api.github.com/users/foo')
|
138
176
|
.to_return(
|
139
|
-
|
177
|
+
body: '{}',
|
140
178
|
headers: { 'x-ratelimit-remaining' => '1' }
|
141
179
|
)
|
142
180
|
.to_return(
|
143
|
-
|
181
|
+
body: '{}',
|
144
182
|
headers: { 'x-ratelimit-remaining' => '10000' }
|
145
183
|
)
|
146
184
|
o.user('foo')
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fbe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04-
|
10
|
+
date: 2025-04-18 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: backtrace
|