fbe 0.24.1 → 0.24.3

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: ce6c8e11155234d3e42b7b78fc60f9dc8584a173d0d248b604bd61b39d26180f
4
- data.tar.gz: 8a642207f5d847c3bbc795f0c48f3410f49e8c9641a3108d14ac6802b398e91e
3
+ metadata.gz: ce758baa2b569c87b5c6318bd2a58df0a5041c578164bb07f337c197a83ef4a7
4
+ data.tar.gz: fa85c249bc4ea36ecf435e0412bccd9a1c8885ed222f0538be0c02ebd4f59ccc
5
5
  SHA512:
6
- metadata.gz: e4440719106088a76557dffdc71fd9b91c3f1f25bb5eb7cd98cb1e5afc8f32d182bc4a0fb58ab47901b3c5394c1b8d213593b2a34419095816917c1756632667
7
- data.tar.gz: 5b2930074b232c9be48e45addab74d7d3cb806e145445adc488e8bbec35d1c598713aed670cfc65a7238dd21a46dd9d03ed4c145714e95dafb3e5aa627f2416e
6
+ metadata.gz: 43e184c1ee6955ca80cd5a4ba01aa47cf5e59ce8ad1767c03e535c77c253a1bb9223d6603825ef99c6d094828d03e3ae7b6a68e3cc4b7766cfb108c3058fa714
7
+ data.tar.gz: f1399b8d6b1022a2460f6c1049bd2b58aa924933773c0bdbec3cc21ba65e28aeca6712d382fdd070e0ec5f44f8c5ac3608aacdb9d87857c11f00b45bc6efd728
data/Gemfile.lock CHANGED
@@ -14,6 +14,7 @@ PATH
14
14
  filesize (~> 0.2)
15
15
  graphql-client (~> 0.26)
16
16
  intercepted (~> 0.2)
17
+ joined (~> 0.1)
17
18
  judges (~> 0.46)
18
19
  liquid (~> 5.5)
19
20
  loog (~> 0.6)
@@ -46,7 +47,7 @@ GEM
46
47
  ast (2.4.3)
47
48
  backtrace (0.4.1)
48
49
  base64 (0.3.0)
49
- baza.rb (0.9.7)
50
+ baza.rb (0.9.8)
50
51
  backtrace (~> 0.4)
51
52
  elapsed (~> 0.0)
52
53
  faraday (~> 2.13)
@@ -86,7 +87,7 @@ GEM
86
87
  others (~> 0.0)
87
88
  tago (~> 0.0)
88
89
  yaml (~> 0.3)
89
- faraday (2.13.1)
90
+ faraday (2.13.2)
90
91
  faraday-net_http (>= 2.0, < 3.5)
91
92
  json
92
93
  logger
@@ -118,6 +119,7 @@ GEM
118
119
  concurrent-ruby (~> 1.0)
119
120
  intercepted (0.2.0)
120
121
  iri (0.11.2)
122
+ joined (0.3.0)
121
123
  json (2.12.2)
122
124
  judges (0.51.0)
123
125
  backtrace (~> 0.4)
@@ -187,7 +189,7 @@ GEM
187
189
  regexp_parser (2.10.0)
188
190
  retries (0.0.5)
189
191
  rexml (3.4.1)
190
- rubocop (1.77.0)
192
+ rubocop (1.78.0)
191
193
  json (~> 2.3)
192
194
  language_server-protocol (~> 3.17.0.2)
193
195
  lint_roller (~> 1.1.0)
data/fbe.gemspec CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.add_dependency 'filesize', '~>0.2'
35
35
  s.add_dependency 'graphql-client', '~>0.26'
36
36
  s.add_dependency 'intercepted', '~>0.2'
37
+ s.add_dependency 'joined', '~>0.1'
37
38
  s.add_dependency 'judges', '~>0.46'
38
39
  s.add_dependency 'liquid', '~>5.5'
39
40
  s.add_dependency 'loog', '~>0.6'
data/lib/fbe/award.rb CHANGED
@@ -4,6 +4,7 @@
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'factbase/syntax'
7
+ require 'joined'
7
8
  require_relative 'fb'
8
9
 
9
10
  # A generator of awards.
@@ -146,7 +147,7 @@ class Fbe::Award
146
147
  any.calc(bill)
147
148
  elsif any.is_a?(Symbol)
148
149
  v = bill.vars[any]
149
- raise "Unknown name #{any.inspect} among: #{bill.vars.keys.map(&:inspect).join(', ')}" if v.nil?
150
+ raise "Unknown name #{any.inspect} among: #{bill.vars.keys.map(&:inspect).joined}" if v.nil?
150
151
  v
151
152
  else
152
153
  any
data/lib/fbe/conclude.rb CHANGED
@@ -17,13 +17,13 @@ require_relative 'if_absent'
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(fb: Fbe.fb, judge: $judge, loog: $loog, options: $options, global: $global, &)
20
+ def Fbe.conclude(fb: Fbe.fb, judge: $judge, loog: $loog, options: $options, global: $global, time: Time, &)
21
21
  raise 'The fb is nil' if fb.nil?
22
22
  raise 'The $judge is not set' if judge.nil?
23
23
  raise 'The $global is not set' if global.nil?
24
24
  raise 'The $options is not set' if options.nil?
25
25
  raise 'The $loog is not set' if loog.nil?
26
- c = Fbe::Conclude.new(fb:, judge:, loog:, options:, global:)
26
+ c = Fbe::Conclude.new(fb:, judge:, loog:, options:, global:, time:)
27
27
  c.instance_eval(&)
28
28
  end
29
29
 
@@ -58,7 +58,8 @@ class Fbe::Conclude
58
58
  # @param [Hash] global The hash for global caching
59
59
  # @param [Judges::Options] options The options coming from the +judges+ tool
60
60
  # @param [Loog] loog The logging facility
61
- def initialize(fb:, judge:, global:, options:, loog:)
61
+ # @param [Time] time The time
62
+ def initialize(fb:, judge:, global:, options:, loog:, time: Time)
62
63
  @fb = fb
63
64
  @judge = judge
64
65
  @loog = loog
@@ -68,6 +69,7 @@ class Fbe::Conclude
68
69
  @follows = []
69
70
  @quota_aware = false
70
71
  @timeout = 60
72
+ @time = time
71
73
  end
72
74
 
73
75
  # Make this block aware of GitHub API quota.
@@ -180,22 +182,23 @@ class Fbe::Conclude
180
182
  # end
181
183
  def roll(&)
182
184
  passed = 0
183
- start = Time.now
185
+ start = @time.now
184
186
  oct = Fbe.octo(loog: @loog, options: @options, global: @global)
185
187
  @fb.query(@query).each do |a|
188
+ if @quota_aware && oct.off_quota?
189
+ @loog.debug('We ran out of GitHub quota, must stop here')
190
+ break
191
+ end
192
+ now = @time.now
193
+ if now > start + @timeout
194
+ @loog.debug("We've spent more than #{start.ago}, must stop here")
195
+ break
196
+ end
186
197
  @fb.txn do |fbt|
187
- if @quota_aware && oct.off_quota?
188
- @loog.debug('We ran out of GitHub quota, must stop here')
189
- throw :commit
190
- end
191
- if Time.now > start + @timeout
192
- @loog.debug("We've spent more than #{start.ago}, must stop here")
193
- throw :commit
194
- end
195
198
  n = yield fbt, a
196
199
  @loog.info("#{n.what}: #{n.details}") unless n.nil?
197
- passed += 1
198
200
  end
201
+ passed += 1
199
202
  end
200
203
  @loog.debug("Found and processed #{passed} facts by: #{@query}")
201
204
  passed
data/lib/fbe/iterate.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
+ require 'joined'
6
7
  require 'tago'
7
8
  require 'time'
8
9
  require_relative '../fbe'
@@ -270,6 +271,6 @@ class Fbe::Iterate
270
271
  break
271
272
  end
272
273
  end
273
- @loog.debug("Finished scanning #{repos.size} repos in #{start.ago}: #{seen.map { |k, v| "#{k}:#{v}" }.join(', ')}")
274
+ @loog.debug("Finished scanning #{repos.size} repos in #{start.ago}: #{seen.map { |k, v| "#{k}:#{v}" }.joined}")
274
275
  end
275
276
  end
data/lib/fbe/octo.rb CHANGED
@@ -665,7 +665,8 @@ class Fbe::FakeOctokit
665
665
  user: { login: 'yegor256', id: 526_301, type: 'User' },
666
666
  created_at: Time.parse('2025-06-01 12:00:55 UTC'),
667
667
  updated_at: Time.parse('2025-06-01 15:47:18 UTC'),
668
- closed_at: Time.parse('2025-06-02 15:00:00 UTC')
668
+ closed_at: Time.parse('2025-06-02 15:00:00 UTC'),
669
+ closed_by: { id: 526_301, login: 'yegor256' }
669
670
  }
670
671
  elsif number == 143
671
672
  {
@@ -676,7 +677,8 @@ class Fbe::FakeOctokit
676
677
  pull_request: { merged_at: nil },
677
678
  created_at: Time.parse('2025-05-29 17:00:55 UTC'),
678
679
  updated_at: Time.parse('2025-05-29 19:00:00 UTC'),
679
- closed_at: Time.parse('2025-06-01 18:20:00 UTC')
680
+ closed_at: Time.parse('2025-06-01 18:20:00 UTC'),
681
+ closed_by: { id: 526_301, login: 'yegor256' }
680
682
  }
681
683
  else
682
684
  {
@@ -708,6 +710,12 @@ class Fbe::FakeOctokit
708
710
  repo: {
709
711
  full_name: repo
710
712
  },
713
+ base: {
714
+ repo: {
715
+ full_name: repo
716
+ }
717
+ },
718
+ state: 'closed',
711
719
  user: { login: 'yegor256', id: 526_301, type: 'User' },
712
720
  head: { ref: 'master', sha: '6dcb09b5b57875f334f61aebed695e2e4193db5e' },
713
721
  additions: 12,
@@ -715,7 +723,9 @@ class Fbe::FakeOctokit
715
723
  changed_files: 3,
716
724
  comments: 2,
717
725
  review_comments: 2,
718
- created_at: Time.parse('2024-09-20 19:00:00 UTC')
726
+ closed_at: Time.parse('2024-12-20'),
727
+ merged_at: Time.parse('2024-12-20'),
728
+ created_at: Time.parse('2024-09-20')
719
729
  }
720
730
  end
721
731
 
@@ -3,6 +3,7 @@
3
3
  # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
+ require 'joined'
6
7
  require_relative '../fbe'
7
8
  require_relative 'octo'
8
9
 
@@ -53,6 +54,8 @@ end
53
54
  # @note Exclusion patterns must start with '-' (e.g., '-org/pattern*')
54
55
  # @note Results are shuffled to distribute load when processing
55
56
  def Fbe.unmask_repos(options: $options, global: $global, loog: $loog)
57
+ raise 'Repositories mask is not specified' unless options.repositories
58
+ raise 'Repositories mask is empty' if options.repositories.empty?
56
59
  repos = []
57
60
  octo = Fbe.octo(loog:, global:, options:)
58
61
  masks = (options.repositories || '').split(',')
@@ -71,8 +74,8 @@ def Fbe.unmask_repos(options: $options, global: $global, loog: $loog)
71
74
  repos.reject! { |r| re.match?(r) }
72
75
  end
73
76
  repos.reject! { |repo| octo.repository(repo)[:archived] }
74
- raise "No repos found matching: #{options.repositories}" if repos.empty?
77
+ raise "No repos found matching: #{options.repositories.inspect}" if repos.empty?
75
78
  repos.shuffle!
76
- loog.debug("Scanning #{repos.size} repositories: #{repos.join(', ')}...")
79
+ loog.debug("Scanning #{repos.size} repositories: #{repos.joined}...")
77
80
  repos
78
81
  end
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.24.1' unless const_defined?(:VERSION)
13
+ VERSION = '0.24.3' unless const_defined?(:VERSION)
14
14
  end
@@ -125,4 +125,48 @@ class TestConclude < Fbe::Test
125
125
  end
126
126
  assert_equal(2, fb.size)
127
127
  end
128
+
129
+ def test_stop_if_timeout_exceeded
130
+ $fb = Factbase.new
131
+ $fb.insert.then do |f|
132
+ f._id = 1
133
+ f.foo = 5
134
+ end
135
+ $fb.insert.then do |f|
136
+ f._id = 2
137
+ f.foo = 4
138
+ end
139
+ $fb.insert.then do |f|
140
+ f._id = 3
141
+ f.bar = 3
142
+ end
143
+ $fb.insert.then do |f|
144
+ f._id = 4
145
+ f.foo = 2
146
+ end
147
+ $fb.insert.then do |f|
148
+ f._id = 5
149
+ f.foo = 1
150
+ end
151
+ $global = {}
152
+ $options = Judges::Options.new({ 'testing' => true })
153
+ $loog = Loog::NULL
154
+ $judge = ''
155
+ total = 0
156
+ now = Time.now
157
+ time = Minitest::Mock.new
158
+ time.expect(:now, now)
159
+ time.expect(:now, now + 4)
160
+ time.expect(:now, now + 8)
161
+ time.expect(:now, now + 12)
162
+ Fbe.conclude(time: time) do
163
+ on '(exists foo)'
164
+ timeout 10
165
+ consider do |f|
166
+ total += f.foo
167
+ end
168
+ end
169
+ assert_equal(9, total)
170
+ time.verify
171
+ end
128
172
  end
@@ -662,4 +662,51 @@ class TestOcto < Fbe::Test
662
662
  https://github.com/octokit/octokit.rb/blob/ea3413c3174571e87c83d358fc893cc7613091fa/lib/octokit/connection.rb#L109-L119
663
663
  MSG
664
664
  end
665
+
666
+ def test_octo_cache_still_available_on_duration_of_age
667
+ WebMock.disable_net_connect!
668
+ now = Time.now
669
+ age = 60
670
+ stub_request(:get, 'https://api.github.com/rate_limit')
671
+ .to_return(
672
+ status: 200, headers: { 'Content-Type' => 'application/json', 'X-RateLimit-Remaining' => '5000' },
673
+ body: { 'rate' => { 'limit' => 5000, 'remaining' => 5000, 'reset' => 1_672_531_200 } }.to_json
674
+ )
675
+ Dir.mktmpdir do |dir|
676
+ sqlite_cache = File.expand_path('t.db', dir)
677
+ o = Fbe.octo(loog: fake_loog, global: {}, options: Judges::Options.new({ 'sqlite_cache' => sqlite_cache }))
678
+ stub_request(:get, 'https://api.github.com/repositories/798641472').to_return(
679
+ status: 200,
680
+ body: { id: 798_641_472, name: 'factbase' }.to_json,
681
+ headers: {
682
+ 'Date' => now.httpdate,
683
+ 'Content-Type' => 'application/json; charset=utf-8',
684
+ 'Cache-Control' => "public, max-age=#{age}, s-maxage=#{age}",
685
+ 'Etag' => 'W/"f5f1ea995fd7266816f681aca5a81f539420c469070a47568bebdaa3055487bc"',
686
+ 'Last-Modified' => 'Fri, 04 Jul 2025 13:39:42 GMT'
687
+ }
688
+ ).times(1).then.to_raise('no more request to /repositories/798641472')
689
+ assert_equal('factbase', o.repo(798_641_472)['name'])
690
+ Time.stub(:now, now + age - 1) do
691
+ assert_equal('factbase', o.repo(798_641_472)['name'])
692
+ end
693
+ stub_request(:get, 'https://api.github.com/repositories/798641472').to_return(
694
+ status: 200,
695
+ body: { id: 798_641_472, name: 'factbase_changed' }.to_json,
696
+ headers: {
697
+ 'Date' => (now + age).httpdate,
698
+ 'Content-Type' => 'application/json; charset=utf-8',
699
+ 'Cache-Control' => "public, max-age=#{age}, s-maxage=#{age}",
700
+ 'Etag' => 'W/"f5f1ea995fd7266816f681aca5a81f539420c469070a47568bebdaa3055487be"',
701
+ 'Last-Modified' => 'Fri, 04 Jul 2025 13:39:42 GMT'
702
+ }
703
+ ).times(1).then.to_raise('no more request to /repositories/798641472')
704
+ Time.stub(:now, now + age) do
705
+ assert_equal('factbase_changed', o.repo(798_641_472)['name'])
706
+ end
707
+ Time.stub(:now, now + (2 * age) - 1) do
708
+ assert_equal('factbase_changed', o.repo(798_641_472)['name'])
709
+ end
710
+ end
711
+ end
665
712
  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.24.1
4
+ version: 0.24.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -177,6 +177,20 @@ dependencies:
177
177
  - - "~>"
178
178
  - !ruby/object:Gem::Version
179
179
  version: '0.2'
180
+ - !ruby/object:Gem::Dependency
181
+ name: joined
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: '0.1'
187
+ type: :runtime
188
+ prerelease: false
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '0.1'
180
194
  - !ruby/object:Gem::Dependency
181
195
  name: judges
182
196
  requirement: !ruby/object:Gem::Requirement