fbe 0.40.0 → 0.41.1

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: d19c0535556f2bc17f04be6cd25be80552d3016e22d1abc52ad867425e29cd31
4
- data.tar.gz: 9a9dc13820984a088462dae32ce4b1c3adeb236290770a56529ee9aa1308405e
3
+ metadata.gz: e5e897714a3789136f4e029b50a785506d23a21e3a666c670ce470aadc87eb1c
4
+ data.tar.gz: f1a86de706ff760e725f56ac060c4a36c5b5a5c4def42ffb4c46c289852b2e91
5
5
  SHA512:
6
- metadata.gz: d81b8b123cd43763746e53d02f62b9f2430fb9ab0a21e70d4f6250ca499ac5a3fc59775ddfbd37138fadcc8c7d51f0cc8a724e4923c3c9837deecd022d3c789b
7
- data.tar.gz: 63e1fd591916726362b7fdc68c2153f57f3e2a22c5db01b4d280262d6dd3fbbf86b573bc612c2e4c3fb51b8e0211f7c89e910f0b85bdb59bf1edfa4913f3e7ab
6
+ metadata.gz: 51a2136d5e94ee50f1fa941e368976a91502e8a4469d0e4bd4fcf87cb6b0f90b86393224a28daf48b315c072c2f4c474eafa89fc41ce526df15b193be6d85bbb
7
+ data.tar.gz: dc51650d3aa4c74680070d50fac3488b6d49ea591ad8231a6a2b3e311f1abb63f11aeea895545b6fed63a1c7c385da068dd53f53ed931c192b710e93302d3cf3
@@ -16,4 +16,4 @@ jobs:
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
18
  - uses: actions/checkout@v5
19
- - uses: fsfe/reuse-action@v5
19
+ - uses: fsfe/reuse-action@v6
@@ -16,6 +16,6 @@ jobs:
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
18
  - uses: actions/checkout@v5
19
- - uses: crate-ci/typos@v1.37.2
19
+ - uses: crate-ci/typos@v1.38.1
20
20
  with:
21
21
  config: .github/.typos.toml
data/Gemfile.lock CHANGED
@@ -146,7 +146,7 @@ GEM
146
146
  logger (1.7.0)
147
147
  loog (0.6.1)
148
148
  logger (~> 1.0)
149
- minitest (5.25.5)
149
+ minitest (5.26.0)
150
150
  minitest-reporters (1.7.1)
151
151
  ansi
152
152
  builder
data/lib/fbe/conclude.rb CHANGED
@@ -8,6 +8,7 @@ require_relative '../fbe'
8
8
  require_relative 'fb'
9
9
  require_relative 'if_absent'
10
10
  require_relative 'octo'
11
+ require_relative 'over'
11
12
 
12
13
  # Creates an instance of {Fbe::Conclude} and evals it with the block provided.
13
14
  #
@@ -195,29 +196,16 @@ class Fbe::Conclude
195
196
  # end
196
197
  # end
197
198
  def roll(&)
198
- if @lifetime_aware && @options.lifetime && Time.now - @epoch > @options.lifetime * 0.9
199
- @loog.debug("We ran out of lifetime (#{@epoch.ago} already), can't even start")
200
- return
201
- end
202
- if @timeout_aware && @options.timeout && Time.now - @kickoff > @options.timeout * 0.9
203
- @loog.debug("We've spent more than #{@kickoff.ago}, won't even start")
204
- return
205
- end
199
+ return 0 if Fbe.over?(
200
+ global: @global, options: @options, loog: @loog, epoch: @epoch, kickoff: @kickoff,
201
+ quota_aware: @quota_aware, lifetime_aware: @lifetime_aware, timeout_aware: @timeout_aware
202
+ )
206
203
  passed = 0
207
- oct = Fbe.octo(loog: @loog, options: @options, global: @global)
208
204
  @fb.query(@query).each do |a|
209
- if @quota_aware && oct.off_quota?(threshold: 100)
210
- @loog.info('We ran out of GitHub quota, must stop here')
211
- break
212
- end
213
- if @lifetime_aware && @options.lifetime && Time.now - @epoch > @options.lifetime * 0.9
214
- @loog.debug("We ran out of lifetime (#{@epoch.ago} already), must stop here")
215
- break
216
- end
217
- if @timeout_aware && @options.timeout && Time.now - @kickoff > @options.timeout * 0.9
218
- @loog.debug("We've spent more than #{@kickoff.ago}, must stop here")
219
- break
220
- end
205
+ break if Fbe.over?(
206
+ global: @global, options: @options, loog: @loog, epoch: @epoch, kickoff: @kickoff,
207
+ quota_aware: @quota_aware, lifetime_aware: @lifetime_aware, timeout_aware: @timeout_aware
208
+ )
221
209
  @fb.txn do |fbt|
222
210
  n = yield fbt, a
223
211
  @loog.info("#{n.what}: #{n.details}") unless n.nil?
@@ -226,6 +214,9 @@ class Fbe::Conclude
226
214
  end
227
215
  @loog.debug("Found and processed #{passed} facts by: #{@query}")
228
216
  passed
217
+ rescue Fbe::OffQuota => e
218
+ @loog.info(e.message)
219
+ passed
229
220
  end
230
221
 
231
222
  # Populates a new fact based on a previous fact and a processing block.
@@ -95,16 +95,32 @@ class Fbe::Graph
95
95
  # @param [String] owner The repository owner (username or organization)
96
96
  # @param [String] name The repository name
97
97
  # @param [String] branch The branch name (e.g., "master" or "main")
98
- # @return [Integer] The total number of commits in the branch
98
+ # @param [Array<Array<String, String, String>> repos List of owner, name, branch
99
+ # @return [Integer, Array<Hash>] The total number of commits in the branch or array with hash
99
100
  # @example
100
101
  # graph = Fbe::Graph.new(token: 'github_token')
101
102
  # count = graph.total_commits('octocat', 'Hello-World', 'main')
102
103
  # puts count #=> 42
103
- def total_commits(owner, name, branch)
104
- result = query(
105
- <<~GRAPHQL
106
- {
107
- repository(owner: "#{owner}", name: "#{name}") {
104
+ # @example
105
+ # result = Fbe.github_graph.total_commits(
106
+ # repos: [
107
+ # ['zerocracy', 'fbe', 'master'],
108
+ # ['zerocracy', 'judges-action', 'master']
109
+ # ]
110
+ # )
111
+ # puts result #=>
112
+ # [{"owner"=>"zerocracy", "name"=>"fbe", "branch"=>"master", "total_commits"=>754},
113
+ # {"owner"=>"zerocracy", "name"=>"judges-action", "branch"=>"master", "total_commits"=>2251}]
114
+ def total_commits(owner = nil, name = nil, branch = nil, repos: nil)
115
+ raise 'Need owner, name and branch or repos' if owner.nil? && name.nil? && branch.nil? && repos.nil?
116
+ raise 'Owner, name and branch is required' if (owner.nil? || name.nil? || branch.nil?) && repos.nil?
117
+ raise 'Repos list cannot be empty' if owner.nil? && name.nil? && branch.nil? && repos&.empty?
118
+ raise 'Need only owner, name and branch or repos' if (!owner.nil? || !name.nil? || !branch.nil?) && !repos.nil?
119
+ repos ||= [[owner, name, branch]]
120
+ requests =
121
+ repos.each_with_index.map do |(owner, name, branch), i|
122
+ <<~GRAPHQL
123
+ repo_#{i}: repository(owner: "#{owner}", name: "#{name}") {
108
124
  ref(qualifiedName: "#{branch}") {
109
125
  target {
110
126
  ... on Commit {
@@ -115,10 +131,25 @@ class Fbe::Graph
115
131
  }
116
132
  }
117
133
  }
134
+ GRAPHQL
135
+ end
136
+ result = query("{\n#{requests.join("\n")}\n}")
137
+ if owner && name && branch
138
+ ref = result.repo_0&.ref
139
+ raise "Repository '#{owner}/#{name}' or branch '#{branch}' not found" unless ref&.target&.history
140
+ ref.target.history.total_count
141
+ else
142
+ repos.each_with_index.map do |(owner, name, branch), i|
143
+ ref = result.send(:"repo_#{i}")&.ref
144
+ raise "Repository '#{owner}/#{name}' or branch '#{branch}' not found" unless ref&.target&.history
145
+ {
146
+ 'owner' => owner,
147
+ 'name' => name,
148
+ 'branch' => branch,
149
+ 'total_commits' => ref.target.history.total_count
118
150
  }
119
- GRAPHQL
120
- )
121
- result.repository.ref.target.history.total_count
151
+ end
152
+ end
122
153
  end
123
154
 
124
155
  # Gets the total number of issues and pull requests in a repository.
@@ -451,12 +482,28 @@ class Fbe::Graph
451
482
 
452
483
  # Returns mock total commit count.
453
484
  #
454
- # @param [String] _owner Repository owner (ignored)
455
- # @param [String] _name Repository name (ignored)
456
- # @param [String] _branch Branch name (ignored)
457
- # @return [Integer] Always returns 1484
458
- def total_commits(_owner, _name, _branch)
459
- 1484
485
+ # @param [String] owner Repository owner
486
+ # @param [String] name Repository name
487
+ # @param [String] branch Branch name
488
+ # @param [Array<Array<String, String, String>> repos List of owner, name, branch
489
+ # @return [Integer, Array<Hash>] Returns 1484 for single repo or array of hashes
490
+ def total_commits(owner = nil, name = nil, branch = nil, repos: nil)
491
+ raise 'Need owner, name and branch or repos' if owner.nil? && name.nil? && branch.nil? && repos.nil?
492
+ raise 'Owner, name and branch is required' if (owner.nil? || name.nil? || branch.nil?) && repos.nil?
493
+ raise 'Repos list cannot be empty' if owner.nil? && name.nil? && branch.nil? && repos&.empty?
494
+ raise 'Need only owner, name and branch or repos' if (!owner.nil? || !name.nil? || !branch.nil?) && !repos.nil?
495
+ if owner && name && branch
496
+ 1484
497
+ else
498
+ repos.each_with_index.map do |(owner, name, branch), _i|
499
+ {
500
+ 'owner' => owner,
501
+ 'name' => name,
502
+ 'branch' => branch,
503
+ 'total_commits' => 1484
504
+ }
505
+ end
506
+ end
460
507
  end
461
508
 
462
509
  # Returns mock issue type event data.
data/lib/fbe/iterate.rb CHANGED
@@ -10,6 +10,7 @@ require_relative '../fbe'
10
10
  require_relative 'fb'
11
11
  require_relative 'if_absent'
12
12
  require_relative 'octo'
13
+ require_relative 'over'
13
14
  require_relative 'overwrite'
14
15
  require_relative 'unmask_repos'
15
16
 
@@ -267,29 +268,19 @@ class Fbe::Iterate
267
268
  starts = before.dup
268
269
  values = {}
269
270
  loop do
270
- if @quota_aware && oct.off_quota?(threshold: 100)
271
- @loog.info("We are off GitHub quota, time to stop after #{started.ago}")
272
- break
273
- end
274
- if @lifetime_aware && @options.lifetime && Time.now - @epoch > @options.lifetime * 0.9
275
- @loog.debug("We ran out of lifetime (#{@epoch.ago} already), must stop here")
276
- break
277
- end
278
- if @timeout_aware && @options.timeout && Time.now - @kickoff > @options.timeout * 0.9
279
- @loog.debug("We've spent more than #{@kickoff.ago}, must stop here")
271
+ if Fbe.over?(
272
+ global: @global, options: @options, loog: @loog, epoch: @epoch, kickoff: @kickoff,
273
+ quota_aware: @quota_aware, lifetime_aware: @lifetime_aware, timeout_aware: @timeout_aware
274
+ )
275
+ @loog.info("Time to stop after #{started.ago}")
280
276
  break
281
277
  end
282
278
  repos.each do |repo|
283
- if @quota_aware && oct.off_quota?(threshold: 100)
284
- @loog.info("We are off GitHub quota, we must skip #{repo}")
285
- break
286
- end
287
- if @lifetime_aware && @options.lifetime && Time.now - @epoch > @options.lifetime * 0.9
288
- @loog.info("We are working for #{@epoch.ago} already, won't check repository ##{repo}")
289
- next
290
- end
291
- if @timeout_aware && @options.timeout && Time.now - @kickoff > @options.timeout * 0.9
292
- @loog.debug("We've spent more than #{@kickoff.ago}, won't check repository ##{repo}")
279
+ if Fbe.over?(
280
+ global: @global, options: @options, loog: @loog, epoch: @epoch, kickoff: @kickoff,
281
+ quota_aware: @quota_aware, lifetime_aware: @lifetime_aware, timeout_aware: @timeout_aware
282
+ )
283
+ @loog.info("Won't check repository ##{repo}")
293
284
  break
294
285
  end
295
286
  next if restarted.include?(repo)
@@ -335,16 +326,23 @@ class Fbe::Iterate
335
326
  break
336
327
  end
337
328
  end
338
- repos.each do |repo|
339
- next if before[repo] == starts[repo]
340
- f =
341
- Fbe.if_absent(fb: @fb, always: true) do |n|
342
- n.what = 'iterate'
343
- n.where = 'github'
344
- n.repository = repo
345
- end
346
- Fbe.overwrite(f, @label, before[repo], fb: @fb)
347
- end
348
329
  @loog.debug("Finished scanning #{repos.size} repos in #{@kickoff.ago}: #{seen.map { |k, v| "#{k}:#{v}" }.joined}")
330
+ rescue Fbe::OffQuota => e
331
+ @loog.info(e.message)
332
+ ensure
333
+ if defined?(repos) && !repos.nil? &&
334
+ defined?(before) && !before.nil? &&
335
+ defined?(starts) && !starts.nil?
336
+ repos.each do |repo|
337
+ next if before[repo] == starts[repo]
338
+ f =
339
+ Fbe.if_absent(fb: @fb, always: true) do |n|
340
+ n.what = 'iterate'
341
+ n.where = 'github'
342
+ n.repository = repo
343
+ end
344
+ Fbe.overwrite(f, @label, before[repo], fb: @fb)
345
+ end
346
+ end
349
347
  end
350
348
  end
data/lib/fbe/over.rb ADDED
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
4
+ # SPDX-License-Identifier: MIT
5
+
6
+ require_relative '../fbe'
7
+ require_relative 'octo'
8
+
9
+ # Check GitHub API quota, lifetime, and timeout.
10
+ #
11
+ # @param [Hash] global Hash of global options
12
+ # @param [Judges::Options] options The options available globally
13
+ # @param [Loog] loog Logging facility
14
+ # @param [Time] epoch When the entire update started
15
+ # @param [Time] kickoff When the particular judge started
16
+ # @param [Boolean] quota_aware Enable or disable check of GitHub API quota
17
+ # @param [Boolean] lifetime_aware Enable or disable check of lifetime limitations
18
+ # @param [Boolean] timeout_aware Enable or disable check of timeout limitations
19
+ # @return [Boolean] check result
20
+ def Fbe.over?(
21
+ global: $global, options: $options, loog: $loog,
22
+ epoch: $epoch || Time.now, kickoff: $kickoff || Time.now,
23
+ quota_aware: true, lifetime_aware: true, timeout_aware: true
24
+ )
25
+ if quota_aware && Fbe.octo(loog:, options:, global:).off_quota?(threshold: 100)
26
+ loog.info('We are off GitHub quota, time to stop')
27
+ return true
28
+ end
29
+ if lifetime_aware && options.lifetime && Time.now - epoch > options.lifetime * 0.9
30
+ loog.info("We ran out of lifetime (#{epoch.ago} already), must stop here")
31
+ return true
32
+ end
33
+ if timeout_aware && options.timeout && Time.now - kickoff > options.timeout * 0.9
34
+ loog.info("We've spent more than #{kickoff.ago}, must stop here")
35
+ return true
36
+ end
37
+ false
38
+ 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.40.0' unless const_defined?(:VERSION)
13
+ VERSION = '0.41.1' unless const_defined?(:VERSION)
14
14
  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.40.0
4
+ version: 0.41.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -384,6 +384,7 @@ files:
384
384
  - lib/fbe/middleware/sqlite_store.rb
385
385
  - lib/fbe/middleware/trace.rb
386
386
  - lib/fbe/octo.rb
387
+ - lib/fbe/over.rb
387
388
  - lib/fbe/overwrite.rb
388
389
  - lib/fbe/pmp.rb
389
390
  - lib/fbe/regularly.rb