fbe 0.27.0 → 0.28.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 +3 -3
- data/lib/fbe/if_absent.rb +4 -2
- data/lib/fbe/iterate.rb +4 -0
- data/lib/fbe/overwrite.rb +6 -6
- data/lib/fbe/tombstone.rb +67 -0
- data/lib/fbe.rb +1 -1
- data/test/fbe/test_iterate.rb +15 -0
- data/test/fbe/test_tombstone.rb +46 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22c7a8e786ff71b8449f19751665bc82f32ba777248218bcac806b76b8be3fa2
|
4
|
+
data.tar.gz: 361d1413b6649089e1ba3e8b499d60540b25261da616b94ac56687fe1af1b7fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04b8c247dda95f931519f496cab03d02c8d912eafc0d2114e1dd21d507a9b81ed156d26accd2f5be50394cc3dec1fe4c86d4c0415f4f0a8a5c4d1eccef3510b8
|
7
|
+
data.tar.gz: 75f0f3ca32b28aee6d1206975bb066b7da7c022f9bee785c723d2a88585cce70ec6e7c5da201418676c0b56bda9db385f8af2ddd0557d157137e5dc3241c3563
|
data/Gemfile.lock
CHANGED
@@ -121,7 +121,7 @@ GEM
|
|
121
121
|
iri (0.11.2)
|
122
122
|
joined (0.4.0)
|
123
123
|
json (2.13.2)
|
124
|
-
judges (0.53.
|
124
|
+
judges (0.53.3)
|
125
125
|
backtrace (~> 0.4)
|
126
126
|
baza.rb (~> 0.5)
|
127
127
|
concurrent-ruby (~> 1.2)
|
@@ -188,7 +188,7 @@ GEM
|
|
188
188
|
rake (13.3.0)
|
189
189
|
regexp_parser (2.11.2)
|
190
190
|
retries (0.0.5)
|
191
|
-
rexml (3.4.
|
191
|
+
rexml (3.4.2)
|
192
192
|
rubocop (1.80.0)
|
193
193
|
json (~> 2.3)
|
194
194
|
language_server-protocol (~> 3.17.0.2)
|
@@ -223,7 +223,7 @@ GEM
|
|
223
223
|
docile (~> 1.1)
|
224
224
|
simplecov-html (~> 0.11)
|
225
225
|
simplecov_json_formatter (~> 0.1)
|
226
|
-
simplecov-cobertura (3.
|
226
|
+
simplecov-cobertura (3.1.0)
|
227
227
|
rexml
|
228
228
|
simplecov (~> 0.19)
|
229
229
|
simplecov-html (0.13.2)
|
data/lib/fbe/if_absent.rb
CHANGED
@@ -30,6 +30,7 @@ require_relative 'fb'
|
|
30
30
|
# time of its first creation.
|
31
31
|
#
|
32
32
|
# @param [Factbase] fb The factbase to check and insert into (defaults to Fbe.fb)
|
33
|
+
# @param [Boolean] always If true, return the object in any case
|
33
34
|
# @yield [Factbase::Fact] A proxy fact object to set properties on
|
34
35
|
# @return [nil, Factbase::Fact] nil if fact exists, otherwise the newly created fact
|
35
36
|
# @note String values are properly escaped in queries
|
@@ -45,7 +46,7 @@ require_relative 'fb'
|
|
45
46
|
# else
|
46
47
|
# puts "User already exists"
|
47
48
|
# end
|
48
|
-
def Fbe.if_absent(fb: Fbe.fb)
|
49
|
+
def Fbe.if_absent(fb: Fbe.fb, always: false)
|
49
50
|
attrs = {}
|
50
51
|
f =
|
51
52
|
others(map: attrs) do |*args|
|
@@ -71,7 +72,8 @@ def Fbe.if_absent(fb: Fbe.fb)
|
|
71
72
|
"(eq #{k} #{vv})"
|
72
73
|
end.join(' ')
|
73
74
|
q = "(and #{q})"
|
74
|
-
before = fb.query(q).each.
|
75
|
+
before = fb.query(q).each.first
|
76
|
+
return before if before && always
|
75
77
|
return nil if before
|
76
78
|
n = fb.insert
|
77
79
|
attrs.each { |k, v| n.send(:"#{k}=", v) }
|
data/lib/fbe/iterate.rb
CHANGED
@@ -212,6 +212,10 @@ class Fbe::Iterate
|
|
212
212
|
@loog.info("We are off GitHub quota, time to stop after #{start.ago}")
|
213
213
|
break
|
214
214
|
end
|
215
|
+
if Time.now - start > timeout
|
216
|
+
@loog.info('We are over time, it is time to stop')
|
217
|
+
break
|
218
|
+
end
|
215
219
|
repos.each do |repo|
|
216
220
|
if @quota_aware && oct.off_quota?
|
217
221
|
@loog.debug("We are off GitHub quota, we must skip #{repo}")
|
data/lib/fbe/overwrite.rb
CHANGED
@@ -17,7 +17,7 @@ require_relative 'fb'
|
|
17
17
|
#
|
18
18
|
# @param [Factbase::Fact] fact The fact to modify (must have _id property)
|
19
19
|
# @param [String] property The name of the property to set
|
20
|
-
# @param [Any] value The value to set (can be any type)
|
20
|
+
# @param [Any] value The value to set (can be any type, including array)
|
21
21
|
# @param [Factbase] fb The factbase to use (defaults to Fbe.fb)
|
22
22
|
# @return [nil] Nothing
|
23
23
|
# @raise [RuntimeError] If fact is nil, has no _id, or property is not a String
|
@@ -27,7 +27,7 @@ require_relative 'fb'
|
|
27
27
|
# user = fb.query('(eq login "john")').first
|
28
28
|
# updated_user = Fbe.overwrite(user, 'status', 'active')
|
29
29
|
# # All properties preserved, only 'status' is set to 'active'
|
30
|
-
def Fbe.overwrite(fact, property, value, fb: Fbe.fb)
|
30
|
+
def Fbe.overwrite(fact, property, value, fb: Fbe.fb, fid: '_id')
|
31
31
|
raise 'The fact is nil' if fact.nil?
|
32
32
|
raise 'The fb is nil' if fb.nil?
|
33
33
|
raise "The property is not a String but #{property.class} (#{property})" unless property.is_a?(String)
|
@@ -36,12 +36,12 @@ def Fbe.overwrite(fact, property, value, fb: Fbe.fb)
|
|
36
36
|
fact.all_properties.each do |prop|
|
37
37
|
before[prop.to_s] = fact[prop]
|
38
38
|
end
|
39
|
-
id = fact[
|
40
|
-
raise
|
41
|
-
raise "No facts by
|
39
|
+
id = fact[fid]&.first
|
40
|
+
raise "There is no #{fid} in the fact, cannot use Fbe.overwrite" if id.nil?
|
41
|
+
raise "No facts by #{fid} = #{id}" if fb.query("(eq #{fid} #{id})").delete!.zero?
|
42
42
|
fb.txn do |fbt|
|
43
43
|
n = fbt.insert
|
44
|
-
before[property.to_s] = [value]
|
44
|
+
before[property.to_s] = value.is_a?(Array) ? value : [value]
|
45
45
|
before.each do |k, vv|
|
46
46
|
next unless n[k].nil?
|
47
47
|
vv.each do |v|
|
@@ -0,0 +1,67 @@
|
|
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 'fb'
|
8
|
+
require_relative 'if_absent'
|
9
|
+
require_relative 'overwrite'
|
10
|
+
|
11
|
+
# Checks whether an issue is already under a tombstone.
|
12
|
+
#
|
13
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
|
+
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
|
+
# License:: MIT
|
16
|
+
class Fbe::Tombstone
|
17
|
+
# Ctor.
|
18
|
+
# @param [Factbase] fb The factbase to use (defaults to Fbe.fb)
|
19
|
+
def initialize(fb: Fbe.fb, fid: '_id')
|
20
|
+
@fb = fb
|
21
|
+
@fid = fid
|
22
|
+
end
|
23
|
+
|
24
|
+
# Put it there.
|
25
|
+
# @param [Integer] repo ID of repository
|
26
|
+
# @param [Integer] issue ID of issue
|
27
|
+
def bury!(repo, issue)
|
28
|
+
f =
|
29
|
+
Fbe.if_absent(fb: @fb, always: true) do |n|
|
30
|
+
n.what = 'tombstone'
|
31
|
+
n.repository = repo
|
32
|
+
end
|
33
|
+
f.send(:"#{@fid}=", SecureRandom.random_number(99_999)) if f[@fid].nil?
|
34
|
+
nn = f['issues']&.map { |ii| ii.split('-').map(&:to_i) } || []
|
35
|
+
nn << [issue, issue]
|
36
|
+
nn = nn.sort_by(&:first)
|
37
|
+
merged = []
|
38
|
+
nn.each do |a, b|
|
39
|
+
if merged.empty?
|
40
|
+
merged << [a, b]
|
41
|
+
else
|
42
|
+
last = merged[-1]
|
43
|
+
if last[1] == a - 1
|
44
|
+
last[1] = b
|
45
|
+
else
|
46
|
+
merged << [a, b]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
Fbe.overwrite(f, 'issues', merged.map { |ii| "#{ii[0]}-#{ii[1]}" }, fb: @fb, fid: @fid)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Is it there?
|
54
|
+
# @param [Integer] repo ID of repository
|
55
|
+
# @param [Integer] issue ID of issue
|
56
|
+
# @return [Boolean] True if it's there
|
57
|
+
def has?(repo, issue)
|
58
|
+
f = @fb.query(
|
59
|
+
"(and (eq what 'tombstone') (eq repository #{repo}) (exists issues))"
|
60
|
+
).each.first
|
61
|
+
return false if f.nil?
|
62
|
+
f['issues'].any? do |ii|
|
63
|
+
a, b = ii.split('-').map(&:to_i)
|
64
|
+
(a..b).cover?(issue)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/fbe.rb
CHANGED
data/test/fbe/test_iterate.rb
CHANGED
@@ -31,6 +31,21 @@ class TestIterate < Fbe::Test
|
|
31
31
|
assert_equal(4, fb.size)
|
32
32
|
end
|
33
33
|
|
34
|
+
def test_stops_on_timeout
|
35
|
+
opts = Judges::Options.new(['repositories=foo/bar', 'testing=true'])
|
36
|
+
fb = Factbase.new
|
37
|
+
fb.insert.foo = 42
|
38
|
+
Fbe.iterate(fb:, loog: Loog::NULL, options: opts, global: {}) do
|
39
|
+
as 'labels-were-scanned'
|
40
|
+
by '(agg (always) (max foo))'
|
41
|
+
repeats 2
|
42
|
+
over(timeout: 0.1) do
|
43
|
+
sleep 0.2
|
44
|
+
end
|
45
|
+
end
|
46
|
+
assert_equal(2, fb.size)
|
47
|
+
end
|
48
|
+
|
34
49
|
def test_many_repeats
|
35
50
|
opts = Judges::Options.new(['repositories=foo/bar,foo/second', 'testing=true'])
|
36
51
|
cycles = 0
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
|
+
# SPDX-License-Identifier: MIT
|
5
|
+
|
6
|
+
require 'factbase'
|
7
|
+
require_relative '../../lib/fbe/tombstone'
|
8
|
+
require_relative '../test__helper'
|
9
|
+
|
10
|
+
# Test.
|
11
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
|
+
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
13
|
+
# License:: MIT
|
14
|
+
class TestTombstone < Fbe::Test
|
15
|
+
def test_simple
|
16
|
+
fb = Factbase.new
|
17
|
+
ts = Fbe::Tombstone.new(fb:)
|
18
|
+
ts.bury!(41, 13)
|
19
|
+
ts.bury!(42, 13)
|
20
|
+
ts.bury!(42, 999)
|
21
|
+
assert(ts.has?(41, 13))
|
22
|
+
assert(ts.has?(42, 999))
|
23
|
+
refute(ts.has?(8, 7))
|
24
|
+
refute(ts.has?(43, 999))
|
25
|
+
refute(ts.has?(43, 990))
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_on_empty
|
29
|
+
fb = Factbase.new
|
30
|
+
ts = Fbe::Tombstone.new(fb:)
|
31
|
+
refute(ts.has?(8, 7))
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_merges_them
|
35
|
+
fb = Factbase.new
|
36
|
+
ts = Fbe::Tombstone.new(fb:)
|
37
|
+
ts.bury!(42, 13)
|
38
|
+
ts.bury!(42, 18)
|
39
|
+
ts.bury!(42, 14)
|
40
|
+
ts.bury!(42, 17)
|
41
|
+
ts.bury!(42, 15)
|
42
|
+
ts.bury!(42, 16)
|
43
|
+
assert(ts.has?(42, 16))
|
44
|
+
refute(ts.has?(42, 22))
|
45
|
+
end
|
46
|
+
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.
|
4
|
+
version: 0.28.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
@@ -387,6 +387,7 @@ files:
|
|
387
387
|
- lib/fbe/regularly.rb
|
388
388
|
- lib/fbe/repeatedly.rb
|
389
389
|
- lib/fbe/sec.rb
|
390
|
+
- lib/fbe/tombstone.rb
|
390
391
|
- lib/fbe/unmask_repos.rb
|
391
392
|
- lib/fbe/who.rb
|
392
393
|
- renovate.json
|
@@ -414,6 +415,7 @@ files:
|
|
414
415
|
- test/fbe/test_regularly.rb
|
415
416
|
- test/fbe/test_repeatedly.rb
|
416
417
|
- test/fbe/test_sec.rb
|
418
|
+
- test/fbe/test_tombstone.rb
|
417
419
|
- test/fbe/test_unmask_repos.rb
|
418
420
|
- test/fbe/test_who.rb
|
419
421
|
- test/test__helper.rb
|