fbe 0.9.0 → 0.10.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 +1 -1
- data/assets/bylaws/bug-report-was-rewarded.liquid +1 -1
- data/assets/bylaws/code-contribution-was-rewarded.liquid +1 -1
- data/assets/bylaws/code-review-was-rewarded.liquid +1 -1
- data/assets/bylaws/enhancement-suggestion-was-rewarded.liquid +1 -1
- data/assets/bylaws/resolved-bug-was-rewarded.liquid +1 -1
- data/lib/fbe/award.rb +145 -3
- data/lib/fbe/conclude.rb +39 -2
- data/lib/fbe/github_graph.rb +52 -1
- data/lib/fbe/middleware/formatter.rb +14 -0
- data/lib/fbe/octo.rb +57 -4
- data/lib/fbe/pmp.rb +17 -1
- data/lib/fbe.rb +1 -1
- data/test/fbe/test_bylaws.rb +13 -12
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50140dbca73e4022726fad153402221b92d01a94f1cfc22eeb8f382170f0b4bc
|
4
|
+
data.tar.gz: 8fc5d55bc4b46f57dadb0bb36bd5461f2253bef19e143fb15704263e64d0ccd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce99b5a1ad7500b952a731a863497b50b0f7b553a1b4521202149f1878d8b9e8eef8af79438d7ab96cb8ac238182a6ad044a98e82677efbc439d4a5ce39a6bfd
|
7
|
+
data.tar.gz: d51c72a5299c03aeb1e1bf20839a94e3d1c05fc679c6d32c8959d8634d2a9cdfa080082950358e33ba62bda4242dd8231f11bbb2a7f7752165c9fd5f7e04f5e6
|
data/Gemfile.lock
CHANGED
data/lib/fbe/award.rb
CHANGED
@@ -62,20 +62,46 @@ class Fbe::Award
|
|
62
62
|
bylaw
|
63
63
|
end
|
64
64
|
|
65
|
-
# A term for
|
65
|
+
# A term module for processing award billing logic.
|
66
|
+
#
|
67
|
+
# This module is used to extend Factbase terms to handle award calculations
|
68
|
+
# and billing operations. It provides methods to calculate point values and
|
69
|
+
# evaluate complex award expressions.
|
66
70
|
module BTerm
|
71
|
+
# Returns a string representation of the term.
|
72
|
+
#
|
73
|
+
# @return [String] The term as a string in S-expression format
|
74
|
+
# @example
|
75
|
+
# term.to_s #=> "(give (times loc 5) 'for LoC')"
|
67
76
|
def to_s
|
68
77
|
"(#{@op} #{@operands.join(' ')})"
|
69
78
|
end
|
70
79
|
|
80
|
+
# Indicates whether the term is static.
|
81
|
+
#
|
82
|
+
# @return [Boolean] Always returns true for BTerm
|
71
83
|
def static?
|
72
84
|
true
|
73
85
|
end
|
74
86
|
|
87
|
+
# Indicates whether the term is abstract.
|
88
|
+
#
|
89
|
+
# @return [Boolean] Always returns false for BTerm
|
75
90
|
def abstract?
|
76
91
|
false
|
77
92
|
end
|
78
93
|
|
94
|
+
# Processes this term and applies its operations to a bill.
|
95
|
+
#
|
96
|
+
# @param [Fbe::Award::Bill] bill The bill to update
|
97
|
+
# @return [nil]
|
98
|
+
# @raise [RuntimeError] If there's a failure processing any term
|
99
|
+
# @example
|
100
|
+
# term = Factbase::Syntax.new('(award (give 100 "for effort"))').to_term
|
101
|
+
# term.redress!(Fbe::Award::BTerm)
|
102
|
+
# bill = Fbe::Award::Bill.new
|
103
|
+
# term.bill_to(bill)
|
104
|
+
# bill.points #=> 100
|
79
105
|
def bill_to(bill)
|
80
106
|
case @op
|
81
107
|
when :award
|
@@ -105,6 +131,16 @@ class Fbe::Award
|
|
105
131
|
end
|
106
132
|
end
|
107
133
|
|
134
|
+
# Evaluates a value in the context of a bill.
|
135
|
+
#
|
136
|
+
# @param [Object] any The value to evaluate (symbol, term, or literal)
|
137
|
+
# @param [Fbe::Award::Bill] bill The bill providing context for evaluation
|
138
|
+
# @return [Object] The evaluated value
|
139
|
+
# @raise [RuntimeError] If a symbol isn't found in the bill
|
140
|
+
# @example
|
141
|
+
# bill = Fbe::Award::Bill.new
|
142
|
+
# bill.set(:loc, 100)
|
143
|
+
# term.to_val(:loc, bill) #=> 100
|
108
144
|
def to_val(any, bill)
|
109
145
|
if any.is_a?(BTerm)
|
110
146
|
any.calc(bill)
|
@@ -117,6 +153,21 @@ class Fbe::Award
|
|
117
153
|
end
|
118
154
|
end
|
119
155
|
|
156
|
+
# Calculates the value of this term in the context of a bill.
|
157
|
+
#
|
158
|
+
# This method evaluates terms like arithmetic operations, logical
|
159
|
+
# operations, and other expressions based on the operator type.
|
160
|
+
#
|
161
|
+
# @param [Fbe::Award::Bill] bill The bill providing context for calculation
|
162
|
+
# @return [Object] The calculated value (number, boolean, etc.)
|
163
|
+
# @raise [RuntimeError] If the term operation is unknown
|
164
|
+
# @example
|
165
|
+
# bill = Fbe::Award::Bill.new
|
166
|
+
# bill.set(:x, 10)
|
167
|
+
# bill.set(:y, 5)
|
168
|
+
# term = Factbase::Syntax.new('(times x y)').to_term
|
169
|
+
# term.redress!(Fbe::Award::BTerm)
|
170
|
+
# term.calc(bill) #=> 50
|
120
171
|
def calc(bill)
|
121
172
|
case @op
|
122
173
|
when :total
|
@@ -275,29 +326,70 @@ class Fbe::Award
|
|
275
326
|
end
|
276
327
|
end
|
277
328
|
|
278
|
-
# A bill.
|
329
|
+
# A bill class that accumulates points and explanations for rewards.
|
330
|
+
#
|
331
|
+
# This class tracks variables, point values, and explanatory text
|
332
|
+
# for each award component. It provides methods to calculate total points
|
333
|
+
# and generate a human-readable summary of the rewards.
|
279
334
|
class Bill
|
335
|
+
# @return [Hash] Variables set in this bill
|
280
336
|
attr_reader :vars
|
281
337
|
|
338
|
+
# Creates a new empty bill.
|
339
|
+
#
|
340
|
+
# @example
|
341
|
+
# bill = Fbe::Award::Bill.new
|
282
342
|
def initialize
|
283
343
|
@lines = []
|
284
344
|
@vars = {}
|
285
345
|
end
|
286
346
|
|
347
|
+
# Sets a variable in the bill's context.
|
348
|
+
#
|
349
|
+
# @param [Symbol] var The variable name
|
350
|
+
# @param [Object] value The value to assign
|
351
|
+
# @return [Object] The assigned value
|
352
|
+
# @example
|
353
|
+
# bill = Fbe::Award::Bill.new
|
354
|
+
# bill.set(:lines_of_code, 500)
|
287
355
|
def set(var, value)
|
288
356
|
@vars[var] = value
|
289
357
|
end
|
290
358
|
|
359
|
+
# Adds a point value with explanatory text to the bill.
|
360
|
+
#
|
361
|
+
# @param [Integer, Float] value The point value to add
|
362
|
+
# @param [String] text The explanation for these points
|
363
|
+
# @return [nil]
|
364
|
+
# @note Zero-valued points are ignored
|
365
|
+
# @example
|
366
|
+
# bill = Fbe::Award::Bill.new
|
367
|
+
# bill.line(50, "for code review")
|
291
368
|
def line(value, text)
|
292
369
|
return if value.zero?
|
293
370
|
text = text.gsub(/\$\{([a-z_0-9]+)\}/) { |_x| @vars[Regexp.last_match[1].to_sym] }
|
294
371
|
@lines << { v: value, t: text }
|
295
372
|
end
|
296
373
|
|
374
|
+
# Calculates the total points in this bill.
|
375
|
+
#
|
376
|
+
# @return [Integer] The sum of all point values, rounded to an integer
|
377
|
+
# @example
|
378
|
+
# bill = Fbe::Award::Bill.new
|
379
|
+
# bill.line(42.5, "for answer")
|
380
|
+
# bill.points #=> 43
|
297
381
|
def points
|
298
382
|
@lines.sum { |l| l[:v] }.to_f.round.to_i
|
299
383
|
end
|
300
384
|
|
385
|
+
# Generates a human-readable summary of the bill.
|
386
|
+
#
|
387
|
+
# @return [String] A description of the points earned
|
388
|
+
# @example
|
389
|
+
# bill = Fbe::Award::Bill.new
|
390
|
+
# bill.line(50, "for code review")
|
391
|
+
# bill.line(25, "for documentation")
|
392
|
+
# bill.greeting #=> "You've earned +75 points for this: +50 for code review; +25 for documentation. "
|
301
393
|
def greeting
|
302
394
|
items = @lines.map { |l| "#{format('%+d', l[:v])} #{l[:t]}" }
|
303
395
|
case items.size
|
@@ -311,33 +403,83 @@ class Fbe::Award
|
|
311
403
|
end
|
312
404
|
end
|
313
405
|
|
314
|
-
# A
|
406
|
+
# A class for generating human-readable bylaws.
|
407
|
+
#
|
408
|
+
# This class builds textual descriptions of award bylaws including
|
409
|
+
# introductions, calculation steps, and variable substitutions.
|
410
|
+
# It produces Markdown-formatted output describing how awards are calculated.
|
315
411
|
class Bylaw
|
412
|
+
# @return [Hash] Variables defined in this bylaw
|
316
413
|
attr_reader :vars
|
317
414
|
|
415
|
+
# Creates a new empty bylaw.
|
416
|
+
#
|
417
|
+
# @example
|
418
|
+
# bylaw = Fbe::Award::Bylaw.new
|
318
419
|
def initialize
|
319
420
|
@lines = []
|
320
421
|
@intro = ''
|
321
422
|
@lets = {}
|
322
423
|
end
|
323
424
|
|
425
|
+
# Removes the specified number of most recently added lines.
|
426
|
+
#
|
427
|
+
# @param [Integer] num The number of lines to remove from the end
|
428
|
+
# @return [Array] The removed lines
|
429
|
+
# @example
|
430
|
+
# bylaw = Fbe::Award::Bylaw.new
|
431
|
+
# bylaw.line("award 50 points")
|
432
|
+
# bylaw.line("award 30 points")
|
433
|
+
# bylaw.revert(1) # Removes "award 30 points"
|
324
434
|
def revert(num)
|
325
435
|
@lines.slice!(-num, num)
|
326
436
|
end
|
327
437
|
|
438
|
+
# Sets the introductory text for the bylaw.
|
439
|
+
#
|
440
|
+
# @param [String] text The introductory text to set
|
441
|
+
# @return [String] The introductory text
|
442
|
+
# @example
|
443
|
+
# bylaw = Fbe::Award::Bylaw.new
|
444
|
+
# bylaw.intro("This bylaw determines rewards for code contributions")
|
328
445
|
def intro(text)
|
329
446
|
@intro = text
|
330
447
|
end
|
331
448
|
|
449
|
+
# Adds a line of text to the bylaw, replacing variable references.
|
450
|
+
#
|
451
|
+
# @param [String] line The line of text to add
|
452
|
+
# @return [nil]
|
453
|
+
# @example
|
454
|
+
# bylaw = Fbe::Award::Bylaw.new
|
455
|
+
# bylaw.let(:points, 50)
|
456
|
+
# bylaw.line("award ${points} points")
|
332
457
|
def line(line)
|
333
458
|
line = line.gsub(/\$\{([a-z_0-9]+)\}/) { |_x| "**#{@lets[Regexp.last_match[1].to_sym]}**" }
|
334
459
|
@lines << line
|
335
460
|
end
|
336
461
|
|
462
|
+
# Registers a variable with its value for substitution in lines.
|
463
|
+
#
|
464
|
+
# @param [Symbol] key The variable name
|
465
|
+
# @param [Object] value The value to associate with the variable
|
466
|
+
# @return [Object] The assigned value
|
467
|
+
# @example
|
468
|
+
# bylaw = Fbe::Award::Bylaw.new
|
469
|
+
# bylaw.let(:points, 50)
|
337
470
|
def let(key, value)
|
338
471
|
@lets[key] = value
|
339
472
|
end
|
340
473
|
|
474
|
+
# Generates a Markdown-formatted representation of the bylaw.
|
475
|
+
#
|
476
|
+
# @return [String] The bylaw formatted as Markdown text
|
477
|
+
# @example
|
478
|
+
# bylaw = Fbe::Award::Bylaw.new
|
479
|
+
# bylaw.intro("This bylaw determines rewards for code contributions")
|
480
|
+
# bylaw.line("award **50** points")
|
481
|
+
# bylaw.markdown
|
482
|
+
# #=> "This bylaw determines rewards for code contributions. Just award **50** points."
|
341
483
|
def markdown
|
342
484
|
pars = []
|
343
485
|
pars << "#{@intro}." unless @intro.empty?
|
data/lib/fbe/conclude.rb
CHANGED
@@ -160,8 +160,24 @@ class Fbe::Conclude
|
|
160
160
|
|
161
161
|
private
|
162
162
|
|
163
|
-
#
|
164
|
-
#
|
163
|
+
# Executes a query and processes each matching fact.
|
164
|
+
#
|
165
|
+
# This internal method handles fetching facts from the factbase,
|
166
|
+
# monitoring quotas and timeouts, and processing each fact through
|
167
|
+
# the provided block.
|
168
|
+
#
|
169
|
+
# @yield [Factbase::Transaction, Factbase::Fact] Transaction and the matching fact
|
170
|
+
# @return [Integer] The count of facts processed
|
171
|
+
# @example
|
172
|
+
# # Inside the Fbe::Conclude class
|
173
|
+
# def example_method
|
174
|
+
# roll do |fbt, fact|
|
175
|
+
# # Process the fact
|
176
|
+
# new_fact = fbt.insert
|
177
|
+
# # Return the new fact
|
178
|
+
# new_fact
|
179
|
+
# end
|
180
|
+
# end
|
165
181
|
def roll(&)
|
166
182
|
passed = 0
|
167
183
|
start = Time.now
|
@@ -185,6 +201,27 @@ class Fbe::Conclude
|
|
185
201
|
passed
|
186
202
|
end
|
187
203
|
|
204
|
+
# Populates a new fact based on a previous fact and a processing block.
|
205
|
+
#
|
206
|
+
# This internal method copies specified properties from the previous fact,
|
207
|
+
# calls the provided block for custom processing, and sets metadata
|
208
|
+
# on the new fact.
|
209
|
+
#
|
210
|
+
# @param [Factbase::Fact] fact The fact to populate
|
211
|
+
# @param [Factbase::Fact] prev The previous fact to copy from
|
212
|
+
# @yield [Factbase::Fact, Factbase::Fact] New fact and the previous fact
|
213
|
+
# @return [nil]
|
214
|
+
# @example
|
215
|
+
# # Inside the Fbe::Conclude class
|
216
|
+
# def example_method
|
217
|
+
# @fb.txn do |fbt|
|
218
|
+
# new_fact = fbt.insert
|
219
|
+
# fill(new_fact, existing_fact) do |n, prev|
|
220
|
+
# n.some_property = "new value"
|
221
|
+
# "Operation completed" # This becomes fact.details
|
222
|
+
# end
|
223
|
+
# end
|
224
|
+
# end
|
188
225
|
def fill(fact, prev)
|
189
226
|
@follows.each do |follow|
|
190
227
|
v = prev.send(follow)
|
data/lib/fbe/github_graph.rb
CHANGED
@@ -35,11 +35,29 @@ class Fbe::Graph
|
|
35
35
|
@host = host
|
36
36
|
end
|
37
37
|
|
38
|
+
# Executes a GraphQL query against the GitHub API.
|
39
|
+
#
|
40
|
+
# @param [String] qry The GraphQL query to execute
|
41
|
+
# @return [GraphQL::Client::Response] The query result data
|
42
|
+
# @example
|
43
|
+
# graph = Fbe::Graph.new(token: 'github_token')
|
44
|
+
# result = graph.query('{viewer {login}}')
|
45
|
+
# puts result.viewer.login #=> "octocat"
|
38
46
|
def query(qry)
|
39
47
|
result = client.query(client.parse(qry))
|
40
48
|
result.data
|
41
49
|
end
|
42
50
|
|
51
|
+
# Retrieves resolved conversation threads from a pull request.
|
52
|
+
#
|
53
|
+
# @param [String] owner The repository owner (username or organization)
|
54
|
+
# @param [String] name The repository name
|
55
|
+
# @param [Integer] number The pull request number
|
56
|
+
# @return [Array<Hash>] An array of resolved conversation threads with their comments
|
57
|
+
# @example
|
58
|
+
# graph = Fbe::Graph.new(token: 'github_token')
|
59
|
+
# threads = graph.resolved_conversations('octocat', 'Hello-World', 42)
|
60
|
+
# threads.first['comments']['nodes'].first['body'] #=> "Great work!"
|
43
61
|
def resolved_conversations(owner, name, number)
|
44
62
|
result = query(
|
45
63
|
<<~GRAPHQL
|
@@ -72,6 +90,16 @@ class Fbe::Graph
|
|
72
90
|
end || []
|
73
91
|
end
|
74
92
|
|
93
|
+
# Gets the total number of commits in a branch.
|
94
|
+
#
|
95
|
+
# @param [String] owner The repository owner (username or organization)
|
96
|
+
# @param [String] name The repository name
|
97
|
+
# @param [String] branch The branch name (e.g., "master" or "main")
|
98
|
+
# @return [Integer] The total number of commits in the branch
|
99
|
+
# @example
|
100
|
+
# graph = Fbe::Graph.new(token: 'github_token')
|
101
|
+
# count = graph.total_commits('octocat', 'Hello-World', 'main')
|
102
|
+
# puts count #=> 42
|
75
103
|
def total_commits(owner, name, branch)
|
76
104
|
result = query(
|
77
105
|
<<~GRAPHQL
|
@@ -93,6 +121,15 @@ class Fbe::Graph
|
|
93
121
|
result.repository.ref.target.history.total_count
|
94
122
|
end
|
95
123
|
|
124
|
+
# Gets the total number of issues and pull requests in a repository.
|
125
|
+
#
|
126
|
+
# @param [String] owner The repository owner (username or organization)
|
127
|
+
# @param [String] name The repository name
|
128
|
+
# @return [Hash] A hash with 'issues' and 'pulls' counts
|
129
|
+
# @example
|
130
|
+
# graph = Fbe::Graph.new(token: 'github_token')
|
131
|
+
# counts = graph.total_issues_and_pulls('octocat', 'Hello-World')
|
132
|
+
# puts counts #=> {"issues"=>42, "pulls"=>17}
|
96
133
|
def total_issues_and_pulls(owner, name)
|
97
134
|
result = query(
|
98
135
|
<<~GRAPHQL
|
@@ -116,6 +153,9 @@ class Fbe::Graph
|
|
116
153
|
|
117
154
|
private
|
118
155
|
|
156
|
+
# Creates or returns a cached GraphQL client instance.
|
157
|
+
#
|
158
|
+
# @return [GraphQL::Client] A configured GraphQL client for GitHub
|
119
159
|
def client
|
120
160
|
@client ||=
|
121
161
|
begin
|
@@ -127,13 +167,24 @@ class Fbe::Graph
|
|
127
167
|
end
|
128
168
|
end
|
129
169
|
|
130
|
-
#
|
170
|
+
# HTTP transport class for GraphQL client to communicate with GitHub API
|
171
|
+
#
|
172
|
+
# This class extends GraphQL::Client::HTTP to handle GitHub-specific
|
173
|
+
# authentication and endpoints.
|
131
174
|
class HTTP < GraphQL::Client::HTTP
|
175
|
+
# Initializes a new HTTP transport with GitHub authentication.
|
176
|
+
#
|
177
|
+
# @param [String] token GitHub API token for authentication
|
178
|
+
# @param [String] host GitHub API host (default: 'api.github.com')
|
132
179
|
def initialize(token, host)
|
133
180
|
@token = token
|
134
181
|
super("https://#{host}/graphql")
|
135
182
|
end
|
136
183
|
|
184
|
+
# Provides headers for GraphQL requests including authentication.
|
185
|
+
#
|
186
|
+
# @param [Object] _context The GraphQL request context (unused)
|
187
|
+
# @return [Hash] Headers for the request
|
137
188
|
def headers(_context)
|
138
189
|
{ Authorization: "Bearer #{@token}" }
|
139
190
|
end
|
@@ -54,11 +54,25 @@ class Fbe::Middleware::Formatter < Faraday::Logging::Formatter
|
|
54
54
|
|
55
55
|
private
|
56
56
|
|
57
|
+
# Indents text with two spaces, including all lines.
|
58
|
+
#
|
59
|
+
# @param [String, nil] txt The text to indent
|
60
|
+
# @return [String] The indented text, or an empty string if input was nil
|
61
|
+
# @example
|
62
|
+
# shifted("line1\nline2")
|
63
|
+
# #=> " line1\n line2"
|
57
64
|
def shifted(txt)
|
58
65
|
return '' if txt.nil?
|
59
66
|
" #{txt.gsub("\n", "\n ")}"
|
60
67
|
end
|
61
68
|
|
69
|
+
# Formats HTTP headers as a multi-line string.
|
70
|
+
#
|
71
|
+
# @param [Hash, nil] headers The headers to format
|
72
|
+
# @return [String] The formatted headers, or an empty string if input was nil
|
73
|
+
# @example
|
74
|
+
# dump_headers({"Content-Type" => "application/json", "Authorization" => "Bearer token"})
|
75
|
+
# #=> "Content-Type: \"application/json\"\nAuthorization: \"Bearer token\""
|
62
76
|
def dump_headers(headers)
|
63
77
|
return '' if headers.nil?
|
64
78
|
headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
|
data/lib/fbe/octo.rb
CHANGED
@@ -124,17 +124,40 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
|
-
# Fake GitHub client
|
127
|
+
# Fake GitHub client for testing purposes.
|
128
|
+
#
|
129
|
+
# This class provides mock implementations of Octokit methods for testing.
|
130
|
+
# It returns predictable data structures that mimic GitHub API responses.
|
128
131
|
class Fbe::FakeOctokit
|
132
|
+
# Generates a random time in the past.
|
133
|
+
#
|
134
|
+
# @return [Time] A random time within the last 10,000 seconds
|
135
|
+
# @example
|
136
|
+
# fake_client = Fbe::FakeOctokit.new
|
137
|
+
# time = fake_client.random_time #=> 2024-09-04 12:34:56 -0700
|
129
138
|
def random_time
|
130
139
|
Time.now - rand(10_000)
|
131
140
|
end
|
132
141
|
|
142
|
+
# Converts a string name to a deterministic integer.
|
143
|
+
#
|
144
|
+
# @param [String, Integer] name The name to convert or pass through
|
145
|
+
# @return [Integer, String] The sum of character codes if input is a string, otherwise the original input
|
146
|
+
# @example
|
147
|
+
# fake_client = Fbe::FakeOctokit.new
|
148
|
+
# fake_client.name_to_number("octocat") #=> 728
|
149
|
+
# fake_client.name_to_number(42) #=> 42
|
133
150
|
def name_to_number(name)
|
134
151
|
return name unless name.is_a?(String)
|
135
152
|
name.chars.sum(&:ord)
|
136
153
|
end
|
137
154
|
|
155
|
+
# Returns a mock rate limit object.
|
156
|
+
#
|
157
|
+
# @return [Object] An object with a remaining method that returns 100
|
158
|
+
# @example
|
159
|
+
# fake_client = Fbe::FakeOctokit.new
|
160
|
+
# fake_client.rate_limit.remaining #=> 100
|
138
161
|
def rate_limit
|
139
162
|
o = Object.new
|
140
163
|
def o.remaining
|
@@ -150,13 +173,25 @@ class Fbe::FakeOctokit
|
|
150
173
|
]
|
151
174
|
end
|
152
175
|
|
153
|
-
#
|
176
|
+
# Gives a star to a repository.
|
177
|
+
#
|
178
|
+
# @param [String] _repo The repository name (e.g., 'user/repo')
|
179
|
+
# @return [Boolean] Always returns true
|
180
|
+
# @example
|
181
|
+
# fake_client = Fbe::FakeOctokit.new
|
182
|
+
# fake_client.star('octocat/Hello-World') #=> true
|
154
183
|
def star(_repo)
|
155
184
|
true
|
156
185
|
end
|
157
186
|
|
158
|
-
#
|
159
|
-
#
|
187
|
+
# Gets details of a GitHub user.
|
188
|
+
#
|
189
|
+
# @param [String, Integer] uid The login of the user or its numeric ID
|
190
|
+
# @return [Hash] User information including id, login, and type
|
191
|
+
# @example
|
192
|
+
# fake_client = Fbe::FakeOctokit.new
|
193
|
+
# fake_client.user(526_301) #=> {:id=>444, :login=>"yegor256", :type=>"User"}
|
194
|
+
# fake_client.user('octocat') #=> {:id=>444, :login=>nil, :type=>"User"}
|
160
195
|
def user(uid)
|
161
196
|
login = (uid == 526_301 ? 'yegor256' : 'torvalds') if uid.is_a?(Integer)
|
162
197
|
{
|
@@ -166,6 +201,15 @@ class Fbe::FakeOctokit
|
|
166
201
|
}
|
167
202
|
end
|
168
203
|
|
204
|
+
# Gets workflow runs for a repository.
|
205
|
+
#
|
206
|
+
# @param [String] repo The repository name
|
207
|
+
# @param [Hash] _opts Additional options (not used in mock)
|
208
|
+
# @return [Hash] Information about workflow runs including counts and details
|
209
|
+
# @example
|
210
|
+
# fake_client = Fbe::FakeOctokit.new
|
211
|
+
# result = fake_client.repository_workflow_runs('octocat/Hello-World')
|
212
|
+
# result[:total_count] #=> 2
|
169
213
|
def repository_workflow_runs(repo, _opts = {})
|
170
214
|
{
|
171
215
|
total_count: 2,
|
@@ -176,6 +220,15 @@ class Fbe::FakeOctokit
|
|
176
220
|
}
|
177
221
|
end
|
178
222
|
|
223
|
+
# Gets usage information for a specific workflow run.
|
224
|
+
#
|
225
|
+
# @param [String] _repo The repository name
|
226
|
+
# @param [Integer] _id The workflow run ID
|
227
|
+
# @return [Hash] Billing and usage information for the workflow run
|
228
|
+
# @example
|
229
|
+
# fake_client = Fbe::FakeOctokit.new
|
230
|
+
# usage = fake_client.workflow_run_usage('octocat/Hello-World', 42)
|
231
|
+
# usage[:run_duration_ms] #=> 53000
|
179
232
|
def workflow_run_usage(_repo, _id)
|
180
233
|
{
|
181
234
|
billable: {
|
data/lib/fbe/pmp.rb
CHANGED
@@ -19,11 +19,27 @@ require_relative 'fb'
|
|
19
19
|
# this method throws an exception. The factbase must contain PMP-related facts.
|
20
20
|
# Most probably, a special judge must fill it up with such a fact.
|
21
21
|
#
|
22
|
+
# The method uses a double nested `others` block to create a chainable interface
|
23
|
+
# that allows accessing configuration like:
|
24
|
+
#
|
25
|
+
# Fbe.pmp.hr.reward_points
|
26
|
+
# Fbe.pmp.cost.hourly_rate
|
27
|
+
# Fbe.pmp.time.deadline
|
28
|
+
#
|
22
29
|
# @param [Factbase] fb The factbase
|
23
30
|
# @param [Hash] global The hash for global caching
|
24
31
|
# @param [Judges::Options] options The options coming from the +judges+ tool
|
25
32
|
# @param [Loog] loog The logging facility
|
26
|
-
# @return [
|
33
|
+
# @return [Object] A proxy object that allows method chaining to access PMP properties
|
34
|
+
# @example
|
35
|
+
# # Get HR reward points from PMP configuration
|
36
|
+
# points = Fbe.pmp.hr.reward_points
|
37
|
+
#
|
38
|
+
# # Get hourly rate from cost area
|
39
|
+
# rate = Fbe.pmp.cost.hourly_rate
|
40
|
+
#
|
41
|
+
# # Get deadline from time area
|
42
|
+
# deadline = Fbe.pmp.time.deadline
|
27
43
|
def Fbe.pmp(fb: Fbe.fb, global: $global, options: $options, loog: $loog)
|
28
44
|
others do |*args1|
|
29
45
|
area = args1.first
|
data/lib/fbe.rb
CHANGED
data/test/fbe/test_bylaws.rb
CHANGED
@@ -31,9 +31,9 @@ class TestBylaws < Fbe::Test
|
|
31
31
|
{ hoc: 30_000, contributors: 1 } => 32
|
32
32
|
},
|
33
33
|
'resolved-bug-was-rewarded' => {
|
34
|
-
{ hours: 1, self: 0 } =>
|
35
|
-
{ hours: 48, self: 0 } =>
|
36
|
-
{ hours: 80, self: 0 } =>
|
34
|
+
{ hours: 1, self: 0 } => 12,
|
35
|
+
{ hours: 48, self: 0 } => 6,
|
36
|
+
{ hours: 80, self: 0 } => 5,
|
37
37
|
{ hours: 300, self: 0 } => 4,
|
38
38
|
{ hours: 3_000, self: 0 } => 4,
|
39
39
|
{ hours: 30_000, self: 0 } => 4,
|
@@ -45,9 +45,10 @@ class TestBylaws < Fbe::Test
|
|
45
45
|
'code-review-was-rewarded' => {
|
46
46
|
{ hoc: 0, comments: 0, self: 0 } => 4,
|
47
47
|
{ hoc: 3, comments: 0, self: 0 } => 4,
|
48
|
-
{ hoc: 78, comments: 7, self: 0 } =>
|
49
|
-
{ hoc:
|
50
|
-
{ hoc:
|
48
|
+
{ hoc: 78, comments: 7, self: 0 } => 12,
|
49
|
+
{ hoc: 120, comments: 4, self: 0 } => 4,
|
50
|
+
{ hoc: 600, comments: 1, self: 0 } => 8,
|
51
|
+
{ hoc: 500, comments: 40, self: 0 } => 24,
|
51
52
|
{ hoc: 5_000, comments: 100, self: 0 } => 24,
|
52
53
|
{ hoc: 100, comments: 50, self: 1 } => 4,
|
53
54
|
{ hoc: 10_000, comments: 200, self: 1 } => 4
|
@@ -59,19 +60,19 @@ class TestBylaws < Fbe::Test
|
|
59
60
|
{ hoc: 78, comments: 1, reviews: 0 } => 4,
|
60
61
|
{ hoc: 50, comments: 15, reviews: 0 } => 4,
|
61
62
|
{ hoc: 50, comments: 25, reviews: 0 } => 4,
|
62
|
-
{ hoc: 180, comments: 7, reviews: 2 } =>
|
63
|
-
{ hoc: 199, comments: 8, reviews: 3 } =>
|
64
|
-
{ hoc: 150, comments: 5, reviews: 1 } =>
|
63
|
+
{ hoc: 180, comments: 7, reviews: 2 } => 24,
|
64
|
+
{ hoc: 199, comments: 8, reviews: 3 } => 24,
|
65
|
+
{ hoc: 150, comments: 5, reviews: 1 } => 24,
|
65
66
|
{ hoc: 500, comments: 25, reviews: 2 } => 4,
|
66
|
-
{ hoc: 99, comments: 6, reviews: 1 } =>
|
67
|
+
{ hoc: 99, comments: 6, reviews: 1 } => 16,
|
67
68
|
{ hoc: 1_500, comments: 3, reviews: 0 } => 4,
|
68
69
|
{ hoc: 15_000, comments: 40, reviews: 0 } => 4
|
69
70
|
},
|
70
71
|
'bug-report-was-rewarded' => {
|
71
|
-
{} =>
|
72
|
+
{} => 12
|
72
73
|
},
|
73
74
|
'enhancement-suggestion-was-rewarded' => {
|
74
|
-
{} =>
|
75
|
+
{} => 12
|
75
76
|
},
|
76
77
|
'dud-was-punished' => {
|
77
78
|
{} => -16
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fbe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: backtrace
|
@@ -253,8 +253,8 @@ email: yegor256@gmail.com
|
|
253
253
|
executables: []
|
254
254
|
extensions: []
|
255
255
|
extra_rdoc_files:
|
256
|
-
- README.md
|
257
256
|
- LICENSE.txt
|
257
|
+
- README.md
|
258
258
|
files:
|
259
259
|
- ".0pdd.yml"
|
260
260
|
- ".gitattributes"
|
@@ -358,7 +358,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
358
358
|
- !ruby/object:Gem::Version
|
359
359
|
version: '0'
|
360
360
|
requirements: []
|
361
|
-
rubygems_version: 3.6.
|
361
|
+
rubygems_version: 3.6.7
|
362
362
|
specification_version: 4
|
363
363
|
summary: FactBase Extended (FBE), a collection of utility classes for Zerocracy judges
|
364
364
|
test_files: []
|