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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bdf5c399cce9ed9558af9ad5ae54c5acc4da5a0461bbe6e7b09d430cba4dd481
4
- data.tar.gz: 99a06827b9b501288146d1ce2e2d65169ca57e8f292ca1e9c481d935e5475cec
3
+ metadata.gz: 50140dbca73e4022726fad153402221b92d01a94f1cfc22eeb8f382170f0b4bc
4
+ data.tar.gz: 8fc5d55bc4b46f57dadb0bb36bd5461f2253bef19e143fb15704263e64d0ccd8
5
5
  SHA512:
6
- metadata.gz: da68e83a59fe793f173802db1df9e13f0c2a5a6845bec43023416769b3a8d41672a06b176508dc20ff2f0d841a9a0e2e55c551101cfd18ecf65edc1e6ca78af7
7
- data.tar.gz: e8a9db23f68d6f368db568a66b3461e21402ee971a2d1620377a1605ab2b5883c70f8057a178ba57325447a47efd1027d0b34f8f54d6b6acbf59f9ac9e31d80f
6
+ metadata.gz: ce99b5a1ad7500b952a731a863497b50b0f7b553a1b4521202149f1878d8b9e8eef8af79438d7ab96cb8ac238182a6ad044a98e82677efbc439d4a5ce39a6bfd
7
+ data.tar.gz: d51c72a5299c03aeb1e1bf20839a94e3d1c05fc679c6d32c8959d8634d2a9cdfa080082950358e33ba62bda4242dd8231f11bbb2a7f7752165c9fd5f7e04f5e6
data/Gemfile.lock CHANGED
@@ -175,7 +175,7 @@ GEM
175
175
  regexp_parser (2.10.0)
176
176
  retries (0.0.5)
177
177
  rexml (3.4.1)
178
- rubocop (1.75.3)
178
+ rubocop (1.75.4)
179
179
  json (~> 2.3)
180
180
  language_server-protocol (~> 3.17.0.2)
181
181
  lint_roller (~> 1.1.0)
@@ -1,7 +1,7 @@
1
1
  (award
2
2
  (explain "When a bug is reported and accepted by the team, the reporter receives a bonus")
3
3
  (aka
4
- (let bonus {{ 4 | times: love }})
4
+ (let bonus {{ 6 | times: love }})
5
5
  (give bonus "as a basis")
6
6
  "award ${bonus} points")
7
7
  )
@@ -5,7 +5,7 @@
5
5
  (in reviews "the number of reviews provided")
6
6
 
7
7
  (aka
8
- (let basis {{ 2 | times: love }})
8
+ (let basis {{ 8 | times: love }})
9
9
  (give basis "as a basis")
10
10
  "award ${basis} points")
11
11
 
@@ -5,7 +5,7 @@
5
5
  (in self "1 if the review was made for their own code contribution, otherwise zero")
6
6
 
7
7
  (aka
8
- (let basis {{ 2 | times: love }})
8
+ (let basis {{ 6 | times: love }})
9
9
  (give basis "as a basis")
10
10
  "award ${basis} points")
11
11
 
@@ -1,7 +1,7 @@
1
1
  (award
2
2
  (explain "When an enhancement is suggested and accepted by the team, the reporter receives a bonus")
3
3
  (aka
4
- (let bonus {{ 4 | times: love }})
4
+ (let bonus {{ 6 | times: love }})
5
5
  (give bonus "as a basis")
6
6
  "award ${bonus} points")
7
7
  )
@@ -4,7 +4,7 @@
4
4
  (in self "1 if the bug was reported and resolved by the same person, otherwise zero")
5
5
  (set days (div hours 24))
6
6
  (aka
7
- (let basis {{ 2 | times: love }})
7
+ (let basis {{ 4 | times: love }})
8
8
  (give basis "as a basis")
9
9
  "award ${basis} points")
10
10
 
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 bill.
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 bylaw.
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
- # @yield [Factbase::Fact] The next fact found by the query
164
- # @return [Integer] The count of the facts seen
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)
@@ -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
- # The HTTP class
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, for tests.
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
- # Give this repo a star.
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
- # Get details of the user.
159
- # @param [String|Integer] uid The login of the user or its ID
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 [String|Integer] The value of the property found
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
@@ -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.9.0' unless const_defined?(:VERSION)
13
+ VERSION = '0.10.0' unless const_defined?(:VERSION)
14
14
  end
@@ -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 } => 8,
35
- { hours: 48, self: 0 } => 4,
36
- { hours: 80, self: 0 } => 4,
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 } => 4,
49
- { hoc: 600, comments: 1, self: 0 } => 4,
50
- { hoc: 500, comments: 40, self: 0 } => 17,
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 } => 13,
63
- { hoc: 199, comments: 8, reviews: 3 } => 14,
64
- { hoc: 150, comments: 5, reviews: 1 } => 12,
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 } => 4,
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
- {} => 8
72
+ {} => 12
72
73
  },
73
74
  'enhancement-suggestion-was-rewarded' => {
74
- {} => 8
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.9.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: 2025-04-23 00:00:00.000000000 Z
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.2
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: []