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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d28d22ca3024f7acbd6630b903aeaaf5391e2debb3cd7dbab920c664473f1567
4
- data.tar.gz: 955bd9e464b2450eeeee67c9cbcc222687c00a1bb6bc5d9b5e37539d7b43700b
3
+ metadata.gz: 2621af2f5ed4213f7137482238a6c1fc2af0f534a88b196e277cdf17bb9d27de
4
+ data.tar.gz: 65bfa710cd5680c579207ea1ce650c25ed743b39b835ce1500cd1b62d7d57fd4
5
5
  SHA512:
6
- metadata.gz: 87935f90c30759d39a960e0c44c717bf7cd6080114aa538546b3970efdec95449a3e749fbe6b575cf064cbd536f133a694d1ba11a9e608cf6fc43c058ec85867
7
- data.tar.gz: e1b306dfdb743aac0efaaa41fbaa73aeb327cdeae33a254046211eb98608c876e7ae351800dde5ff72a74741774985cad53c264a51d24d8cfa12cb570d044189
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(fb: Fbe.fb, judge: $judge, loog: $loog, options: $options, global: $global, time: Time, &)
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
- @quota_aware = false
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. This helps prevent interruptions
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 quota_aware
83
- @quota_aware = true
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
@@ -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.30.0' unless const_defined?(:VERSION)
13
+ VERSION = '0.31.0' 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.30.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,6 +0,0 @@
1
- {
2
- "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
- "extends": [
4
- "config:base"
5
- ]
6
- }
@@ -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