fbe 0.14.1 → 0.16.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/.github/workflows/copyrights.yml +1 -1
- data/.github/workflows/typos.yml +1 -1
- data/Gemfile.lock +36 -33
- data/fbe.gemspec +16 -16
- data/lib/fbe/bylaws.rb +26 -6
- data/lib/fbe/copy.rb +13 -5
- data/lib/fbe/delete.rb +15 -6
- data/lib/fbe/enter.rb +18 -6
- data/lib/fbe/github_graph.rb +48 -1
- data/lib/fbe/if_absent.rb +27 -12
- data/lib/fbe/issue.rb +19 -10
- data/lib/fbe/iterate.rb +124 -36
- data/lib/fbe/just_one.rb +20 -12
- data/lib/fbe/middleware/formatter.rb +33 -5
- data/lib/fbe/middleware.rb +15 -2
- data/lib/fbe/octo.rb +124 -1
- data/lib/fbe/overwrite.rb +14 -6
- data/lib/fbe/regularly.rb +19 -6
- data/lib/fbe/repeatedly.rb +20 -5
- data/lib/fbe/sec.rb +13 -6
- data/lib/fbe/unmask_repos.rb +36 -15
- data/lib/fbe/who.rb +17 -10
- data/lib/fbe.rb +1 -1
- data/test/fbe/test_octo.rb +19 -0
- metadata +35 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c418c6898cb137949a07664da066df3a81594a641f5a5bcc6b42713961e8f26
|
4
|
+
data.tar.gz: 89c4aae8d5858bf72360acee43f00e3cfa4d2943a91c8da1abf5161b572b6c77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc6272d068c113efd0ee5c539c0a4130a4e087c449bdd7daa8aad565f8b51a857145aec11fbc023f1eb586ec7ac40afc2f793fc62698d221f3a31df88be8553d
|
7
|
+
data.tar.gz: 24b9c8cc24ba545b4a3b9e70806f7c1217a569fb81015c2cc602738b46a734fb6ca725d28c525284bb1c5c63a7bf6acbb3cf60d27cb1949d682dca674f00fa84
|
data/.github/workflows/typos.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -2,23 +2,23 @@ PATH
|
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
4
|
fbe (0.0.0)
|
5
|
-
backtrace (
|
6
|
-
baza.rb (
|
7
|
-
decoor (
|
5
|
+
backtrace (> 0)
|
6
|
+
baza.rb (> 0)
|
7
|
+
decoor (> 0)
|
8
8
|
factbase (>= 0.9.3)
|
9
|
-
faraday (~> 2)
|
10
|
-
faraday-http-cache (~> 2)
|
11
|
-
faraday-multipart (~> 1)
|
12
|
-
faraday-retry (~> 2)
|
13
|
-
graphql-client (~> 0)
|
14
|
-
judges (
|
15
|
-
liquid (
|
16
|
-
loog (
|
17
|
-
obk (
|
18
|
-
octokit (~>
|
19
|
-
others (
|
20
|
-
tago (
|
21
|
-
verbose (
|
9
|
+
faraday (~> 2.0)
|
10
|
+
faraday-http-cache (~> 2.0)
|
11
|
+
faraday-multipart (~> 1.0)
|
12
|
+
faraday-retry (~> 2.0)
|
13
|
+
graphql-client (~> 0.0)
|
14
|
+
judges (> 0)
|
15
|
+
liquid (~> 5.5)
|
16
|
+
loog (> 0)
|
17
|
+
obk (> 0)
|
18
|
+
octokit (~> 10.0)
|
19
|
+
others (> 0)
|
20
|
+
tago (> 0)
|
21
|
+
verbose (> 0)
|
22
22
|
|
23
23
|
GEM
|
24
24
|
remote: https://rubygems.org/
|
@@ -41,8 +41,8 @@ GEM
|
|
41
41
|
ansi (1.5.0)
|
42
42
|
ast (2.4.3)
|
43
43
|
backtrace (0.4.0)
|
44
|
-
base64 (0.
|
45
|
-
baza.rb (0.
|
44
|
+
base64 (0.3.0)
|
45
|
+
baza.rb (0.5.0)
|
46
46
|
backtrace (> 0)
|
47
47
|
elapsed (> 0)
|
48
48
|
faraday (> 0)
|
@@ -54,8 +54,8 @@ GEM
|
|
54
54
|
retries (~> 0)
|
55
55
|
tago (~> 0)
|
56
56
|
typhoeus (~> 1.3)
|
57
|
-
benchmark (0.4.
|
58
|
-
bigdecimal (3.1
|
57
|
+
benchmark (0.4.1)
|
58
|
+
bigdecimal (3.2.1)
|
59
59
|
builder (3.3.0)
|
60
60
|
concurrent-ruby (1.3.5)
|
61
61
|
connection_pool (2.5.3)
|
@@ -64,13 +64,13 @@ GEM
|
|
64
64
|
rexml
|
65
65
|
decoor (0.0.1)
|
66
66
|
docile (1.4.1)
|
67
|
-
drb (2.2.
|
67
|
+
drb (2.2.3)
|
68
68
|
elapsed (0.0.1)
|
69
69
|
loog (> 0)
|
70
70
|
tago (> 0)
|
71
71
|
ethon (0.16.0)
|
72
72
|
ffi (>= 1.15.0)
|
73
|
-
factbase (0.
|
73
|
+
factbase (0.11.0)
|
74
74
|
backtrace (~> 0.4)
|
75
75
|
decoor (~> 0.0)
|
76
76
|
json (~> 2.7)
|
@@ -99,19 +99,19 @@ GEM
|
|
99
99
|
fiber-storage (1.0.1)
|
100
100
|
gli (2.22.2)
|
101
101
|
ostruct
|
102
|
-
graphql (2.5.
|
102
|
+
graphql (2.5.8)
|
103
103
|
base64
|
104
104
|
fiber-storage
|
105
105
|
logger
|
106
|
-
graphql-client (0.
|
106
|
+
graphql-client (0.26.0)
|
107
107
|
activesupport (>= 3.0)
|
108
108
|
graphql (>= 1.13.0)
|
109
|
-
hashdiff (1.
|
109
|
+
hashdiff (1.2.0)
|
110
110
|
i18n (1.14.7)
|
111
111
|
concurrent-ruby (~> 1.0)
|
112
|
-
iri (0.
|
113
|
-
json (2.12.
|
114
|
-
judges (0.
|
112
|
+
iri (0.11.2)
|
113
|
+
json (2.12.2)
|
114
|
+
judges (0.45.0)
|
115
115
|
backtrace (~> 0)
|
116
116
|
baza.rb (~> 0)
|
117
117
|
concurrent-ruby (~> 1.2)
|
@@ -130,7 +130,9 @@ GEM
|
|
130
130
|
typhoeus (~> 1.3)
|
131
131
|
language_server-protocol (3.17.0.5)
|
132
132
|
lint_roller (1.1.0)
|
133
|
-
liquid (5.
|
133
|
+
liquid (5.8.6)
|
134
|
+
bigdecimal
|
135
|
+
strscan (>= 3.1.1)
|
134
136
|
logger (1.7.0)
|
135
137
|
loog (0.6.1)
|
136
138
|
logger (~> 1.0)
|
@@ -153,7 +155,7 @@ GEM
|
|
153
155
|
nokogiri (1.18.8-x86_64-linux-gnu)
|
154
156
|
racc (~> 1.4)
|
155
157
|
obk (0.3.2)
|
156
|
-
octokit (
|
158
|
+
octokit (10.0.0)
|
157
159
|
faraday (>= 1, < 3)
|
158
160
|
sawyer (~> 0.9)
|
159
161
|
os (1.1.4)
|
@@ -172,11 +174,11 @@ GEM
|
|
172
174
|
tago (> 0)
|
173
175
|
racc (1.8.1)
|
174
176
|
rainbow (3.1.1)
|
175
|
-
rake (13.
|
177
|
+
rake (13.3.0)
|
176
178
|
regexp_parser (2.10.0)
|
177
179
|
retries (0.0.5)
|
178
180
|
rexml (3.4.1)
|
179
|
-
rubocop (1.75.
|
181
|
+
rubocop (1.75.8)
|
180
182
|
json (~> 2.3)
|
181
183
|
language_server-protocol (~> 3.17.0.2)
|
182
184
|
lint_roller (~> 1.1.0)
|
@@ -190,7 +192,7 @@ GEM
|
|
190
192
|
rubocop-ast (1.44.1)
|
191
193
|
parser (>= 3.3.7.2)
|
192
194
|
prism (~> 1.4)
|
193
|
-
rubocop-minitest (0.38.
|
195
|
+
rubocop-minitest (0.38.1)
|
194
196
|
lint_roller (~> 1.1)
|
195
197
|
rubocop (>= 1.75.0, < 2.0)
|
196
198
|
rubocop-ast (>= 1.38.0, < 2.0)
|
@@ -215,6 +217,7 @@ GEM
|
|
215
217
|
simplecov (~> 0.19)
|
216
218
|
simplecov-html (0.13.1)
|
217
219
|
simplecov_json_formatter (0.1.4)
|
220
|
+
strscan (3.1.5)
|
218
221
|
tago (0.1.0)
|
219
222
|
timeout (0.4.3)
|
220
223
|
total (0.4.1)
|
data/fbe.gemspec
CHANGED
@@ -22,22 +22,22 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.files = `git ls-files`.split($RS)
|
23
23
|
s.rdoc_options = ['--charset=UTF-8']
|
24
24
|
s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
|
25
|
-
s.add_dependency 'backtrace', '
|
26
|
-
s.add_dependency 'baza.rb', '
|
27
|
-
s.add_dependency 'decoor', '
|
25
|
+
s.add_dependency 'backtrace', '>0'
|
26
|
+
s.add_dependency 'baza.rb', '>0'
|
27
|
+
s.add_dependency 'decoor', '>0'
|
28
28
|
s.add_dependency 'factbase', '>=0.9.3'
|
29
|
-
s.add_dependency 'faraday', '~>2'
|
30
|
-
s.add_dependency 'faraday-http-cache', '~>2'
|
31
|
-
s.add_dependency 'faraday-multipart', '~>1'
|
32
|
-
s.add_dependency 'faraday-retry', '~>2'
|
33
|
-
s.add_dependency 'graphql-client', '~>0'
|
34
|
-
s.add_dependency 'judges', '
|
35
|
-
s.add_dependency 'liquid', '5.5
|
36
|
-
s.add_dependency 'loog', '
|
37
|
-
s.add_dependency 'obk', '
|
38
|
-
s.add_dependency 'octokit', '~>
|
39
|
-
s.add_dependency 'others', '
|
40
|
-
s.add_dependency 'tago', '
|
41
|
-
s.add_dependency 'verbose', '
|
29
|
+
s.add_dependency 'faraday', '~>2.0'
|
30
|
+
s.add_dependency 'faraday-http-cache', '~>2.0'
|
31
|
+
s.add_dependency 'faraday-multipart', '~>1.0'
|
32
|
+
s.add_dependency 'faraday-retry', '~>2.0'
|
33
|
+
s.add_dependency 'graphql-client', '~>0.0'
|
34
|
+
s.add_dependency 'judges', '>0'
|
35
|
+
s.add_dependency 'liquid', '~>5.5'
|
36
|
+
s.add_dependency 'loog', '>0'
|
37
|
+
s.add_dependency 'obk', '>0'
|
38
|
+
s.add_dependency 'octokit', '~>10.0'
|
39
|
+
s.add_dependency 'others', '>0'
|
40
|
+
s.add_dependency 'tago', '>0'
|
41
|
+
s.add_dependency 'verbose', '>0'
|
42
42
|
s.metadata['rubygems_mfa_required'] = 'true'
|
43
43
|
end
|
data/lib/fbe/bylaws.rb
CHANGED
@@ -6,15 +6,35 @@
|
|
6
6
|
require 'liquid'
|
7
7
|
require_relative '../fbe'
|
8
8
|
|
9
|
-
# Generates policies/bylaws.
|
9
|
+
# Generates policies/bylaws from Liquid templates.
|
10
10
|
#
|
11
11
|
# Using the templates stored in the +assets/bylaws+ directory, this function
|
12
|
-
# creates a hash
|
12
|
+
# creates a hash where keys are bylaw names (derived from filenames) and values
|
13
|
+
# are the rendered formulas. Templates can use three parameters to control
|
14
|
+
# the strictness and generosity of the bylaws.
|
13
15
|
#
|
14
|
-
# @param [Integer] anger
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
16
|
+
# @param [Integer] anger Strictness level for punishments (0-4, default: 2)
|
17
|
+
# - 0: Very lenient, minimal punishments
|
18
|
+
# - 2: Balanced approach (default)
|
19
|
+
# - 4: Very strict, maximum punishments
|
20
|
+
# @param [Integer] love Generosity level for rewards (0-4, default: 2)
|
21
|
+
# - 0: Minimal rewards
|
22
|
+
# - 2: Balanced rewards (default)
|
23
|
+
# - 4: Maximum rewards
|
24
|
+
# @param [Integer] paranoia Requirements threshold for rewards (1-4, default: 2)
|
25
|
+
# - 1: Easy to earn rewards
|
26
|
+
# - 2: Balanced requirements (default)
|
27
|
+
# - 4: Very difficult to earn rewards
|
28
|
+
# @return [Hash<String, String>] Hash mapping bylaw names to their formulas
|
29
|
+
# @raise [RuntimeError] If parameters are out of valid ranges
|
30
|
+
# @example Generate balanced bylaws
|
31
|
+
# bylaws = Fbe.bylaws(anger: 2, love: 2, paranoia: 2)
|
32
|
+
# bylaws['bug-report-was-rewarded']
|
33
|
+
# # => "award { 2 * love * paranoia }"
|
34
|
+
# @example Generate strict bylaws with minimal rewards
|
35
|
+
# bylaws = Fbe.bylaws(anger: 4, love: 1, paranoia: 3)
|
36
|
+
# bylaws['dud-was-punished']
|
37
|
+
# # => "award { -16 * anger }"
|
18
38
|
def Fbe.bylaws(anger: 2, love: 2, paranoia: 2)
|
19
39
|
raise "The 'anger' must be in the [0..4] interval: #{anger.inspect}" unless !anger.negative? && anger < 5
|
20
40
|
raise "The 'love' must be in the [0..4] interval: #{love.inspect}" unless !love.negative? && love < 5
|
data/lib/fbe/copy.rb
CHANGED
@@ -9,12 +9,20 @@ require_relative 'fb'
|
|
9
9
|
# Makes a copy of a fact, moving all properties to a new fact.
|
10
10
|
#
|
11
11
|
# All properties from the +source+ will be copied to the +target+, except those
|
12
|
-
# listed in the +except
|
12
|
+
# listed in the +except+ array. Only copies properties that don't already exist
|
13
|
+
# in the target. Multi-valued properties are copied with all their values.
|
13
14
|
#
|
14
|
-
# @param [Factbase::Fact] source The source
|
15
|
-
# @param [Factbase::Fact] target The target
|
16
|
-
# @param [Array<String>] except List of
|
17
|
-
# @return [Integer]
|
15
|
+
# @param [Factbase::Fact] source The source fact to copy from
|
16
|
+
# @param [Factbase::Fact] target The target fact to copy to
|
17
|
+
# @param [Array<String>] except List of property names to NOT copy (defaults to empty)
|
18
|
+
# @return [Integer] The number of property values that were copied
|
19
|
+
# @raise [RuntimeError] If source, target, or except is nil
|
20
|
+
# @note Existing properties in target are preserved (not overwritten)
|
21
|
+
# @example Copy all properties except timestamps
|
22
|
+
# source = fb.query('(eq type "user")').first
|
23
|
+
# target = fb.insert
|
24
|
+
# count = Fbe.copy(source, target, except: ['_time', '_id'])
|
25
|
+
# puts "Copied #{count} property values"
|
18
26
|
def Fbe.copy(source, target, except: [])
|
19
27
|
raise 'The source is nil' if source.nil?
|
20
28
|
raise 'The target is nil' if target.nil?
|
data/lib/fbe/delete.rb
CHANGED
@@ -6,13 +6,22 @@
|
|
6
6
|
require_relative '../fbe'
|
7
7
|
require_relative 'fb'
|
8
8
|
|
9
|
-
# Delete a
|
9
|
+
# Delete properties from a fact by creating a new fact without them.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# @
|
11
|
+
# This method doesn't modify the original fact. Instead, it deletes the existing
|
12
|
+
# fact from the factbase and creates a new one with all properties except those
|
13
|
+
# specified for deletion.
|
14
|
+
#
|
15
|
+
# @param [Factbase::Fact] fact The fact to delete properties from (must have an ID)
|
16
|
+
# @param [Array<String>] props List of property names to delete
|
17
|
+
# @param [Factbase] fb The factbase to use (defaults to Fbe.fb)
|
18
|
+
# @param [String] id The property name used as unique identifier (defaults to '_id')
|
19
|
+
# @return [Factbase::Fact] New fact without the deleted properties
|
20
|
+
# @raise [RuntimeError] If fact is nil, has no ID, or ID property doesn't exist
|
21
|
+
# @example Delete multiple properties from a fact
|
22
|
+
# fact = fb.query('(eq type "user")').first
|
23
|
+
# new_fact = Fbe.delete(fact, 'age', 'city')
|
24
|
+
# # new_fact will have all properties except 'age' and 'city'
|
16
25
|
def Fbe.delete(fact, *props, fb: Fbe.fb, id: '_id')
|
17
26
|
raise 'The fact is nil' if fact.nil?
|
18
27
|
i = fact[id]
|
data/lib/fbe/enter.rb
CHANGED
@@ -6,13 +6,25 @@
|
|
6
6
|
require 'baza-rb'
|
7
7
|
require_relative '../fbe'
|
8
8
|
|
9
|
-
# Enter a new valve.
|
9
|
+
# Enter a new valve in the Zerocracy system.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# @param [
|
15
|
-
# @
|
11
|
+
# A valve is a checkpoint or gate in the processing pipeline. This method
|
12
|
+
# records the entry into a valve with a reason, unless in testing mode.
|
13
|
+
#
|
14
|
+
# @param [String] badge Unique badge identifier for the valve
|
15
|
+
# @param [String] why The reason for entering this valve
|
16
|
+
# @param [Judges::Options] options The options from judges tool (uses $options if not provided)
|
17
|
+
# @param [Loog] loog The logging facility (uses $loog if not provided)
|
18
|
+
# @yield Block to execute within the valve context
|
19
|
+
# @return [Object] The result of the yielded block
|
20
|
+
# @raise [RuntimeError] If badge, why, or required globals are nil
|
21
|
+
# @note Requires $options and $loog global variables to be set
|
22
|
+
# @note In testing mode (options.testing != nil), bypasses valve recording
|
23
|
+
# @example Enter a valve for processing
|
24
|
+
# Fbe.enter('payment-check', 'Validating payment data') do
|
25
|
+
# # Process payment validation
|
26
|
+
# validate_payment(data)
|
27
|
+
# end
|
16
28
|
def Fbe.enter(badge, why, options: $options, loog: $loog, &)
|
17
29
|
raise 'The badge is nil' if badge.nil?
|
18
30
|
raise 'The why is nil' if why.nil?
|
data/lib/fbe/github_graph.rb
CHANGED
@@ -271,12 +271,34 @@ class Fbe::Graph
|
|
271
271
|
end
|
272
272
|
end
|
273
273
|
|
274
|
-
# Fake GitHub GraphQL client
|
274
|
+
# Fake GitHub GraphQL client for testing.
|
275
|
+
#
|
276
|
+
# This class mocks the GraphQL client interface and returns predictable
|
277
|
+
# test data without making actual API calls. It's used when the application
|
278
|
+
# is in testing mode.
|
279
|
+
#
|
280
|
+
# @example Using the fake client in tests
|
281
|
+
# fake = Fbe::Graph::Fake.new
|
282
|
+
# result = fake.total_commits('owner', 'repo', 'main')
|
283
|
+
# # => 1484 (always returns the same value)
|
275
284
|
class Fake
|
285
|
+
# Executes a GraphQL query (mock implementation).
|
286
|
+
#
|
287
|
+
# @param [String] _query The GraphQL query (ignored)
|
288
|
+
# @return [Hash] Empty hash
|
276
289
|
def query(_query)
|
277
290
|
{}
|
278
291
|
end
|
279
292
|
|
293
|
+
# Returns mock resolved conversation threads.
|
294
|
+
#
|
295
|
+
# @param [String] owner Repository owner
|
296
|
+
# @param [String] name Repository name
|
297
|
+
# @param [Integer] _number Pull request number (ignored)
|
298
|
+
# @return [Array<Hash>] Array of conversation threads
|
299
|
+
# @example
|
300
|
+
# fake.resolved_conversations('zerocracy', 'baza', 42)
|
301
|
+
# # => [conversation data for zerocracy_baza]
|
280
302
|
def resolved_conversations(owner, name, _number)
|
281
303
|
data = {
|
282
304
|
zerocracy_baza: [
|
@@ -286,6 +308,14 @@ class Fbe::Graph
|
|
286
308
|
data[:"#{owner}_#{name}"] || []
|
287
309
|
end
|
288
310
|
|
311
|
+
# Returns mock issue and pull request counts.
|
312
|
+
#
|
313
|
+
# @param [String] _owner Repository owner (ignored)
|
314
|
+
# @param [String] _name Repository name (ignored)
|
315
|
+
# @return [Hash] Hash with 'issues' and 'pulls' counts
|
316
|
+
# @example
|
317
|
+
# fake.total_issues_and_pulls('owner', 'repo')
|
318
|
+
# # => {"issues"=>23, "pulls"=>19}
|
289
319
|
def total_issues_and_pulls(_owner, _name)
|
290
320
|
{
|
291
321
|
'issues' => 23,
|
@@ -293,10 +323,23 @@ class Fbe::Graph
|
|
293
323
|
}
|
294
324
|
end
|
295
325
|
|
326
|
+
# Returns mock total commit count.
|
327
|
+
#
|
328
|
+
# @param [String] _owner Repository owner (ignored)
|
329
|
+
# @param [String] _name Repository name (ignored)
|
330
|
+
# @param [String] _branch Branch name (ignored)
|
331
|
+
# @return [Integer] Always returns 1484
|
296
332
|
def total_commits(_owner, _name, _branch)
|
297
333
|
1484
|
298
334
|
end
|
299
335
|
|
336
|
+
# Returns mock issue type event data.
|
337
|
+
#
|
338
|
+
# @param [String] node_id The event node ID
|
339
|
+
# @return [Hash, nil] Event data for known IDs, nil otherwise
|
340
|
+
# @example
|
341
|
+
# fake.issue_type_event('ITAE_examplevq862Ga8lzwAAAAQZanzv')
|
342
|
+
# # => {'type'=>'IssueTypeAddedEvent', ...}
|
300
343
|
def issue_type_event(node_id)
|
301
344
|
case node_id
|
302
345
|
when 'ITAE_examplevq862Ga8lzwAAAAQZanzv'
|
@@ -362,6 +405,10 @@ class Fbe::Graph
|
|
362
405
|
|
363
406
|
private
|
364
407
|
|
408
|
+
# Generates mock conversation thread data.
|
409
|
+
#
|
410
|
+
# @param [String] id The conversation thread ID
|
411
|
+
# @return [Hash] Mock conversation data with comments
|
365
412
|
def conversation(id)
|
366
413
|
{
|
367
414
|
'id' => id,
|
data/lib/fbe/if_absent.rb
CHANGED
@@ -8,28 +8,43 @@ require 'time'
|
|
8
8
|
require_relative '../fbe'
|
9
9
|
require_relative 'fb'
|
10
10
|
|
11
|
-
# Injects a fact if it's absent in the factbase, otherwise
|
12
|
-
#
|
11
|
+
# Injects a fact if it's absent in the factbase, otherwise returns nil.
|
12
|
+
#
|
13
|
+
# Checks if a fact with the same property values already exists. If not,
|
14
|
+
# creates a new fact. System properties (_id, _time, _version) are excluded
|
15
|
+
# from the uniqueness check.
|
13
16
|
#
|
14
17
|
# Here is what you do when you want to add a fact to the factbase, but
|
15
18
|
# don't want to make a duplicate of an existing one:
|
16
19
|
#
|
17
20
|
# require 'fbe/if_absent'
|
18
|
-
# n =
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# n.when = Time.now
|
21
|
+
# n = Fbe.if_absent do |f|
|
22
|
+
# f.what = 'something'
|
23
|
+
# f.details = 'important'
|
24
|
+
# end
|
25
|
+
# return if n.nil? # Fact already existed
|
26
|
+
# n.when = Time.now # Add additional properties to the new fact
|
25
27
|
#
|
26
28
|
# This code will definitely create one fact with +what+ equals to +something+
|
27
29
|
# and +details+ equals to +important+, while the +when+ will be equal to the
|
28
30
|
# time of its first creation.
|
29
31
|
#
|
30
|
-
# @param [Factbase] fb The
|
31
|
-
# @yield [Factbase::Fact]
|
32
|
-
# @return [nil
|
32
|
+
# @param [Factbase] fb The factbase to check and insert into (defaults to Fbe.fb)
|
33
|
+
# @yield [Factbase::Fact] A proxy fact object to set properties on
|
34
|
+
# @return [nil, Factbase::Fact] nil if fact exists, otherwise the newly created fact
|
35
|
+
# @note String values are properly escaped in queries
|
36
|
+
# @note Time values are converted to UTC ISO8601 format for comparison
|
37
|
+
# @example Ensure unique user registration
|
38
|
+
# user = Fbe.if_absent do |f|
|
39
|
+
# f.type = 'user'
|
40
|
+
# f.email = 'john@example.com'
|
41
|
+
# end
|
42
|
+
# if user
|
43
|
+
# user.registered_at = Time.now
|
44
|
+
# puts "New user created"
|
45
|
+
# else
|
46
|
+
# puts "User already exists"
|
47
|
+
# end
|
33
48
|
def Fbe.if_absent(fb: Fbe.fb)
|
34
49
|
attrs = {}
|
35
50
|
f =
|
data/lib/fbe/issue.rb
CHANGED
@@ -6,18 +6,27 @@
|
|
6
6
|
require_relative '../fbe'
|
7
7
|
require_relative 'octo'
|
8
8
|
|
9
|
-
# Converts
|
9
|
+
# Converts GitHub repository and issue IDs into a formatted issue reference.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
11
|
+
# Takes the +repository+ and +issue+ properties from the provided +fact+,
|
12
|
+
# queries the GitHub API to get the repository's full name, and formats it
|
13
|
+
# as a standard GitHub issue reference (e.g., "zerocracy/fbe#42").
|
14
|
+
# Results are cached globally to minimize API calls.
|
15
15
|
#
|
16
|
-
# @param [Factbase::Fact] fact The fact
|
17
|
-
# @param [Judges::Options] options The options
|
18
|
-
# @param [Hash] global The hash for global caching
|
19
|
-
# @param [Loog] loog The logging facility
|
20
|
-
# @return [String]
|
16
|
+
# @param [Factbase::Fact] fact The fact containing repository and issue properties
|
17
|
+
# @param [Judges::Options] options The options from judges tool (uses $options global)
|
18
|
+
# @param [Hash] global The hash for global caching (uses $global)
|
19
|
+
# @param [Loog] loog The logging facility (uses $loog global)
|
20
|
+
# @return [String] Formatted issue reference (e.g., "owner/repo#123")
|
21
|
+
# @raise [RuntimeError] If fact is nil or required properties are missing
|
22
|
+
# @raise [RuntimeError] If required global variables are not set
|
23
|
+
# @note Requires 'repository' and 'issue' properties in the fact
|
24
|
+
# @note Repository names are cached to reduce GitHub API calls
|
25
|
+
# @example Format an issue reference
|
26
|
+
# issue_fact = fb.query('(eq type "issue")').first
|
27
|
+
# issue_fact.repository = 549866411 # Repository ID
|
28
|
+
# issue_fact.issue = 42 # Issue number
|
29
|
+
# puts Fbe.issue(issue_fact) # => "zerocracy/fbe#42"
|
21
30
|
def Fbe.issue(fact, options: $options, global: $global, loog: $loog)
|
22
31
|
raise 'The fact is nil' if fact.nil?
|
23
32
|
raise 'The $global is not set' if global.nil?
|