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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af8e39332315cd637642316ea61761792955d43688813b75339b112b58747900
4
- data.tar.gz: 6a2fa9d6c135c1ec2500872ace2bba09d00a89fe87c1af6435e54e880f361df4
3
+ metadata.gz: 485d65ab1a72472bc118062f665516e8092e0f35b6b566acf567cad26259944c
4
+ data.tar.gz: c558708f7897da86b6c2133154cfb5861aa6fd1aeef8686eb109290de43b7b03
5
5
  SHA512:
6
- metadata.gz: 94a48b37c3d821a8c609e99accfc1fb350b1e317f2cb27c7d351a8a472ff1565edec77d4a3bd2a1d39c758c8e6faa71e5706a1a30fe0364bceffd25144466642
7
- data.tar.gz: 8073b49266007c50ae6989ffb1b006fbcddce056cb042be19f5ca39c4e99ad97b58ad77c598d51102b51ef77b9545a4f86fd29cf0323edb7fee9920ff6e65227
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.9.10)
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.1-arm64-darwin)
96
- ffi (1.17.1-x64-mingw-ucrt)
97
- ffi (1.17.1-x86_64-darwin)
98
- ffi (1.17.1-x86_64-linux-gnu)
99
- fiber-storage (1.0.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
- catch :stop do
164
- @fb.txn do |fbt|
165
- fbt.query(@query).each do |a|
166
- if @quota_aware && Fbe.octo(loog: @loog, options: @options, global: @global).off_quota
167
- @loog.debug('We ran out of GitHub quota, must stop here')
168
- throw :stop
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
- def user(name)
151
- login = name
152
- login = name == 526_301 ? 'yegor256' : 'torvalds' if login.is_a?(Integer)
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: name == 29_139_614 ? 'Bot' : 'User'
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(
@@ -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
@@ -10,5 +10,5 @@
10
10
  # License:: MIT
11
11
  module Fbe
12
12
  # Current version of the gem (changed by +.rultor.yml+ on every release)
13
- VERSION = '0.7.0' unless const_defined?(:VERSION)
13
+ VERSION = '0.8.0' unless const_defined?(:VERSION)
14
14
  end
@@ -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 } => 8,
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,
@@ -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
@@ -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(status: 200, body: '{}', headers: { 'Cache-Control' => 'public, max-age=60', 'etag' => 'abc' })
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
- .to_return(status: 200, body: '{}', headers: { 'X-RateLimit-Remaining' => '1000' })
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(status: 200, body: '{}')
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(status: 200, body: '{}')
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
- status: 200, body: '{}',
177
+ body: '{}',
140
178
  headers: { 'x-ratelimit-remaining' => '1' }
141
179
  )
142
180
  .to_return(
143
- status: 200, body: '{}',
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.7.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-15 00:00:00.000000000 Z
10
+ date: 2025-04-18 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: backtrace