fbe 0.0.55 → 0.0.56

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 705cf29669f71d490c86421f566b0ec05c61fa1d8352b97d752ea26b8bcbb294
4
- data.tar.gz: e68fc23391048fac0a41a5b26af5ac85c4a34b3c434845710736d093d7eeb714
3
+ metadata.gz: 50405a3f7472db8c909709be30db7a6eed4f5923fca49fac7ac58da9e936c324
4
+ data.tar.gz: 60d9ca2097226f9763e532e0f27f020087994953d772029fb7bfb9570e6c8396
5
5
  SHA512:
6
- metadata.gz: 20ca9dfe05821edf5df55fccc51303fa23598e81dd15361cfb8b8f23db99b399c9e984ed0a1e1e97f43a0ebd048bd0beec5d8f870163cf0cea5c264fc1a505fc
7
- data.tar.gz: e8fdc7f6988f441cf0d0cb63c52f29a95f17c9681be435eb6c57012403e903e0ce65bd4b60402e802485221f3c7d7ca0cc847d1ba2f40e318af9be82ab989dcc
6
+ metadata.gz: 7a4f743d351eb119586a77f6d675f4c311b511bd72823da1b4be71eb4ba5abcd70a22be42c91973835cc3b5451ae8c8bb68015945f1104ef504a23be073c2913
7
+ data.tar.gz: e3dc8bfefcfc1fbcc5519af0961b8aea92c0ea2702e9d348710557e95ccfb8df725e4d350ecb7e11a3cac839893d27c77a709458cc0dab9c29a9a85eb77da5b6
data/.simplecov CHANGED
@@ -36,6 +36,6 @@ else
36
36
  SimpleCov.start do
37
37
  add_filter '/test/'
38
38
  add_filter '/features/'
39
- minimum_coverage 20
39
+ minimum_coverage 15
40
40
  end
41
41
  end
data/Gemfile.lock CHANGED
@@ -11,6 +11,7 @@ PATH
11
11
  faraday-retry (> 0)
12
12
  graphql-client (> 0)
13
13
  judges (> 0)
14
+ liquid (= 5.5.1)
14
15
  loog (> 0)
15
16
  obk (> 0)
16
17
  octokit (> 0)
@@ -54,7 +55,7 @@ GEM
54
55
  ast (2.4.2)
55
56
  backtrace (0.4.0)
56
57
  base64 (0.2.0)
57
- baza.rb (0.0.6)
58
+ baza.rb (0.0.7)
58
59
  backtrace (> 0)
59
60
  faraday (> 0)
60
61
  faraday-http-cache (> 0)
@@ -77,6 +78,9 @@ GEM
77
78
  diff-lcs (1.5.1)
78
79
  docile (1.4.1)
79
80
  drb (2.2.1)
81
+ elapsed (0.0.1)
82
+ loog (> 0)
83
+ tago (> 0)
80
84
  erubi (1.13.0)
81
85
  ethon (0.16.0)
82
86
  ffi (>= 1.15.0)
@@ -121,21 +125,23 @@ GEM
121
125
  reline (>= 0.4.2)
122
126
  iri (0.8.0)
123
127
  json (2.7.2)
124
- judges (0.25.2)
125
- backtrace (~> 0)
126
- baza.rb (~> 0)
128
+ judges (0.26.0)
129
+ backtrace (> 0)
130
+ baza.rb (> 0)
127
131
  concurrent-ruby (~> 1.2)
128
- factbase (~> 0)
132
+ elapsed (> 0)
133
+ factbase (> 0)
129
134
  gli (~> 2.21)
130
- iri (~> 0)
131
- loog (~> 0)
135
+ iri (> 0)
136
+ loog (> 0)
132
137
  moments (~> 0.3)
133
138
  nokogiri (~> 1.10)
134
- others (~> 0)
135
- retries (~> 0)
136
- tago (~> 0)
139
+ others (> 0)
140
+ retries (> 0)
141
+ tago (> 0)
137
142
  typhoeus (~> 1.3)
138
143
  language_server-protocol (3.17.0.3)
144
+ liquid (5.5.1)
139
145
  logger (1.6.0)
140
146
  loofah (2.22.0)
141
147
  crass (~> 1.0.2)
@@ -164,7 +170,7 @@ GEM
164
170
  faraday (>= 1, < 3)
165
171
  sawyer (~> 0.9)
166
172
  others (0.0.3)
167
- parallel (1.26.2)
173
+ parallel (1.26.3)
168
174
  parser (3.3.4.2)
169
175
  ast (~> 2.4.1)
170
176
  racc
@@ -233,7 +239,7 @@ GEM
233
239
  rubocop-ast (>= 1.31.1, < 2.0)
234
240
  ruby-progressbar (~> 1.7)
235
241
  unicode-display_width (>= 2.4.0, < 3.0)
236
- rubocop-ast (1.32.0)
242
+ rubocop-ast (1.32.1)
237
243
  parser (>= 3.3.1.0)
238
244
  rubocop-performance (1.21.1)
239
245
  rubocop (>= 1.48.1, < 2.0)
data/README.md CHANGED
@@ -29,19 +29,23 @@ These tools help manage facts:
29
29
  * `Fbe.overwrite` changes a property in a fact to another value by deleting
30
30
  the fact first, and then creating a new similar fact with all previous
31
31
  properties but one changed.
32
- * `Fbe.pmp` takes a PMP-related property by the area.
33
32
 
34
33
  They help with formatting:
35
34
 
36
35
  * `Fbe.who` formats user name.
37
36
  * `Fbe.issue` formats issue number.
38
- * `Fbe.award` calculates award by the policy.
37
+ * `Fbe.award` calculates award by the bylaw.
39
38
  * `Fbe.sec` formats seconds.
40
39
 
41
40
  They help with external connections:
42
41
 
43
42
  * `Fbe.octo` connects to GitHub API.
44
43
 
44
+ They help with management:
45
+
46
+ * `Fbe.pmp` takes a PMP-related property by the area.
47
+ * `Fbe.bylaws` builds a hash with bylaws.
48
+
45
49
  ## How to contribute
46
50
 
47
51
  Read
@@ -0,0 +1,7 @@
1
+ (award
2
+ (explain "If a branch has a name that doesn\\\'t obey the convention, a penalty is given to the author")
3
+ (aka
4
+ (let fee -12)
5
+ (give fee "as a basis")
6
+ "deduct ${fee} points")
7
+ )
@@ -0,0 +1,7 @@
1
+ (award
2
+ (explain "When a bug is reported and accepted by the team, the reporter gets a bonus")
3
+ (aka
4
+ (let bonus {{ 8 | times: love }})
5
+ (give bonus "as a basis")
6
+ "award ${bonus} points")
7
+ )
@@ -0,0 +1,82 @@
1
+ (award
2
+ (explain "When a code contribution is made, the author gets a bonus")
3
+ (in hoc "the total number of hits-of-code in the contribution")
4
+ (in comments "the total number of comments made by all reviewers")
5
+ (in reviews "the number of reviews provided")
6
+
7
+ (aka
8
+ (let basis {{ 8 | times: love }})
9
+ (give basis "as a basis")
10
+ "award ${basis} points")
11
+
12
+ (aka
13
+ (let hoc_k {{ 0.05 | times: love }})
14
+ (let hoc_threshold 200)
15
+ (let hoc_max 16)
16
+ (let hoc_min 5)
17
+ (set bonus_for_hoc (if (lt hoc hoc_threshold) (times hoc hoc_k) 0))
18
+ (set bonus_for_hoc (between bonus_for_hoc hoc_min hoc_max))
19
+ (give bonus_for_hoc "for the ${hoc} hits-of-code that you wrote")
20
+ "add ${hoc_k} points for each
21
+ [hit-of-code](https://www.yegor256.com/2014/11/14/hits-of-code.html),
22
+ but not more than ${hoc_max} points")
23
+
24
+ (aka
25
+ (let many_hoc_fee {{ 4 | times: anger }})
26
+ (set penalty_for_hoc (if (gte hoc hoc_threshold) (times -1 many_hoc_fee) 0))
27
+ (give penalty_for_hoc "for too many hits-of-code (${hoc} >= ${hoc_threshold})")
28
+ "deduct ${many_hoc_fee} points if more than ${hoc_threshold}
29
+ [hits-of-code](https://www.yegor256.com/2014/11/14/hits-of-code.html)")
30
+
31
+ (aka
32
+ (let many_hoc_fee2 {{ 8 | times: anger }})
33
+ (let hoc_threshold2 800)
34
+ (set penalty_for_hoc2 (if (gte hoc hoc_threshold2) (times -1 many_hoc_fee2) 0))
35
+ (give penalty_for_hoc2 "for way too many hits-of-code (${hoc} >= ${hoc_threshold2})")
36
+ "deduct ${many_hoc_fee2} points if more than ${hoc_threshold2}
37
+ [hits-of-code](https://www.yegor256.com/2014/11/14/hits-of-code.html)")
38
+
39
+ (aka
40
+ (let no_review_fee {{ 8 | times: anger }})
41
+ (set penalty_for_no_review (if (eq reviews 0) (times -1 no_review_fee) 0))
42
+ (give penalty_for_no_review "for the lack of code review")
43
+ "deduct ${no_review_fee} points if there were no code review")
44
+
45
+ (aka
46
+ (let comments_k {{ 0.1 | times: anger }})
47
+ (let comments_max -16)
48
+ (let comments_min -4)
49
+ (set bonus_for_comments (times comments (times -1 comments_k)))
50
+ (set bonus_for_comments (between bonus_for_comments comments_min comments_max))
51
+ (give bonus_for_comments "for too many (${comments}) comments that were made during review")
52
+ "deduct ${comments_k} points for every comment made during review, but not more than ${comments_max} points")
53
+
54
+ (aka
55
+ (let few_comments_fee {{ 2 | times: anger }})
56
+ (let comments_needed 5)
57
+ (set penalty_for_few_comments (if (and (lt comments comments_needed) (not (eq comments 0))) (times -1 few_comments_fee) 0))
58
+ (give penalty_for_few_comments "for very few (${comments}) comments")
59
+ "deduct ${few_comments_fee} points if there were less than ${comments_needed} comments made during review")
60
+
61
+ (aka
62
+ (let silence_fee {{ 8 | times: anger }})
63
+ (set penalty_for_silence (if (eq comments 0) (times -1 silence_fee) 0))
64
+ (give penalty_for_silence "for absolutely no comments posted by reviewers")
65
+ "deduct ${silence_fee} points if there were absolutely no comments made by reviewers during the review")
66
+
67
+ (aka
68
+ (let few_hoc_fee {{ 4 | times: anger }})
69
+ (let hoc_needed 20)
70
+ (set penalty_for_few_hoc (if (lt hoc hoc_needed) (times -1 few_hoc_fee) 0))
71
+ (give penalty_for_few_hoc "for too few (${hoc}) hits-of-code")
72
+ "deduct ${few_hoc_fee} points if you contribute less than ${hoc_needed} hits-of-code")
73
+
74
+ (aka
75
+ (let max 32)
76
+ (set over (if (gt (total) max) (minus max (total)) 0))
77
+ (give over "to not go over the cap")
78
+ (let min 4)
79
+ (set least (if (lt (total) min) (minus min (total)) 0))
80
+ (give least "to give you at least something")
81
+ "make sure the reward is not larger than ${max} points and not smaller than ${min} points")
82
+ )
@@ -0,0 +1,68 @@
1
+ (award
2
+ (explain "An author of every code review gets a bonus")
3
+ (in hoc "the total number of hits-of-code in the contribution")
4
+ (in comments "the total number of comments made by all reviewers")
5
+ (in self "1 if the review was made for their own code contribution, otherwise zero")
6
+
7
+ (aka
8
+ (let basis {{ 4 | times: love }})
9
+ (give basis "as a basis")
10
+ "award ${basis} points")
11
+
12
+ (aka
13
+ (let self_fee {{ 12 | times: anger }})
14
+ (set penalty_for_self_review (if (eq self 1) (times -1 self_fee) 0))
15
+ (give penalty_for_self_review "for reviewing your own contribution (which is a bad idea)")
16
+ "deduct ${self_fee} points if they reviewed their own contribution")
17
+
18
+ (aka
19
+ (let hoc_k {{ 0.01 | times: love }})
20
+ (let hoc_max 16)
21
+ (let hoc_min 5)
22
+ (set bonus_for_hoc (times hoc hoc_k))
23
+ (set bonus_for_hoc (between bonus_for_hoc hoc_min hoc_max))
24
+ (set bonus_for_hoc (if (eq self 1) 0 bonus_for_hoc))
25
+ (give bonus_for_hoc "for the ${hoc} hits-of-code that you reviewed")
26
+ "add ${hoc_k} points for each
27
+ [hit-of-code](https://www.yegor256.com/2014/11/14/hits-of-code.html),
28
+ but not more than ${hoc_max} points")
29
+
30
+ (aka
31
+ (let few_comments_fee {{ 5 | times: anger }})
32
+ (let comments_needed 6)
33
+ (set penalty_for_few_comments (if (and (lt comments comments_needed) (not (eq comments 0))) (times -1 few_comments_fee) 0))
34
+ (give penalty_for_few_comments "for very few (${comments}) comments")
35
+ "deduct ${few_comments_fee} points if there were less than ${comments_needed} comments made during review")
36
+
37
+ (aka
38
+ (let silence_fee {{ 8 | times: anger }})
39
+ (set penalty_for_silence (if (eq comments 0) (times -1 silence_fee) 0))
40
+ (give penalty_for_silence "for absolutely no comments posted")
41
+ "deduct ${silence_fee} points if there were absolutely no comments made during review")
42
+
43
+ (aka
44
+ (let comments_k {{ 0.25 | times: love }})
45
+ (let comments_max 8)
46
+ (let comments_min 5)
47
+ (set bonus_for_comments (times comments comments_k))
48
+ (set bonus_for_comments (between bonus_for_comments comments_min comments_max))
49
+ (set bonus_for_comments (if (eq self 1) 0 bonus_for_comments))
50
+ (give bonus_for_comments "for the ${comments} comment(s) that you have made")
51
+ "add ${comments_k} points for each comment during the review, but not more than ${comments_max} points")
52
+
53
+ (aka
54
+ (let hoc_fee {{ 4 | times: anger }})
55
+ (let hoc_needed 15)
56
+ (set penalty_for_hoc (if (lt hoc hoc_needed) (times -1 hoc_fee) 0))
57
+ (give penalty_for_hoc "for too few (${hoc}) hits-of-code")
58
+ "deduct ${hoc_fee} points if there were less than ${hoc_needed} hits-of-code")
59
+
60
+ (aka
61
+ (let max 32)
62
+ (set over (if (gt (total) max) (minus max (total)) 0))
63
+ (give over "to not go over the cap")
64
+ (let min 4)
65
+ (set least (if (lt (total) min) (minus min (total)) 0))
66
+ (give least "to give you at least something")
67
+ "make sure the reward is not larger than ${max} points and not smaller than ${min} points")
68
+ )
@@ -0,0 +1,7 @@
1
+ (award
2
+ (explain "When an issue is submitted but then rejected by the team, the reporter gets a penalty")
3
+ (aka
4
+ (let fee {{ -8 | times: anger }})
5
+ (give fee "as a basis")
6
+ "deduct ${fee} points")
7
+ )
@@ -0,0 +1,7 @@
1
+ (award
2
+ (explain "When an enhancement is suggested and accepted by the team, the reporter gets a bonus")
3
+ (aka
4
+ (let bonus {{ 8 | times: love }})
5
+ (give bonus "as a basis")
6
+ "award ${bonus} points")
7
+ )
@@ -0,0 +1,29 @@
1
+ (award
2
+ (explain "When a new release is published, everybody who contributed gets a bonus")
3
+ (in hoc "how many hits-of-code are in the release")
4
+ (in contributors "how many people contributed to the release")
5
+ (aka
6
+ (let basis {{ 12 | times: love }})
7
+ (give basis "as a basis")
8
+ "award ${basis} points")
9
+
10
+ (aka
11
+ (let hoc_k {{ 0.005 | times: love }})
12
+ (let hoc_max 24)
13
+ (let hoc_min 4)
14
+ (set b1 (times hoc hoc_k))
15
+ (set b1 (between b1 hoc_min hoc_max))
16
+ (give b1 "for ${hoc} hits-of-code")
17
+ "add ${hoc_k} points for each
18
+ [hit-of-code](https://www.yegor256.com/2014/11/14/hits-of-code.html),
19
+ but not more than ${hoc_max} points")
20
+
21
+ (aka
22
+ (let max 32)
23
+ (set over (if (gt (total) max) (minus max (total)) 0))
24
+ (give over "to not go over the cap")
25
+ (let min 4)
26
+ (set least (if (lt (total) min) (minus min (total)) 0))
27
+ (give least "to give you at least something")
28
+ "make sure the reward is not larger than ${max} points and not smaller than ${min} points")
29
+ )
@@ -0,0 +1,7 @@
1
+ (award
2
+ (explain "When someone pushes directly to the default branch, they get a penalty")
3
+ (aka
4
+ (let fee -16)
5
+ (give fee "as a basis")
6
+ "${fee} points")
7
+ )
@@ -0,0 +1,40 @@
1
+ (award
2
+ (explain "When a bug is resolved, the person who was assigned to it gets a bonus")
3
+ (in hours "how many hours it took to resolve the bug")
4
+ (in self "1 if the bug was reported and resolved by the same person, otherwise zero")
5
+ (set days (div hours 24))
6
+ (aka
7
+ (let basis {{ 8 | times: love }})
8
+ (give basis "as a basis")
9
+ "award ${basis} points")
10
+
11
+ (aka
12
+ (let b1 {{ 4 | times: love }})
13
+ (let hours_threshold 24)
14
+ (set b1 (if (lt hours hours_threshold) b1 0))
15
+ (give b1 "for resolving it in less than ${hours_threshold} hours")
16
+ "add ${b1} points if it was resolved in less than ${hours_threshold} hours")
17
+
18
+ (aka
19
+ (let self_fee {{ 8 | times: anger }})
20
+ (set penalty_for_self (if (eq self 1) (times -1 self_fee) 0))
21
+ (give penalty_for_self "for resolving the bug reported by you earlier")
22
+ "deduct ${self_fee} points if they resolved the bug earlier reported by themselves")
23
+
24
+ (aka
25
+ (let day_fee {{ 0.5 | times: anger }})
26
+ (set b2 (times -1 (times days day_fee)))
27
+ (let days_fee_max -20)
28
+ (set b2 (max b2 days_fee_max))
29
+ (give b2 "for ${days} days of delay")
30
+ "deduct ${day_fee} points for each day of delay, but no more than ${days_fee_max} points")
31
+
32
+ (aka
33
+ (let max 24)
34
+ (set over (if (gt (total) max) (minus max (total)) 0))
35
+ (give over "to not go over the cap")
36
+ (let min 4)
37
+ (set least (if (lt (total) min) (minus min (total)) 0))
38
+ (give least "to give you at least something")
39
+ "make sure the reward is not larger than ${max} points and not smaller than ${min} points")
40
+ )
data/fbe.gemspec CHANGED
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
48
48
  s.add_dependency 'faraday-retry', '>0'
49
49
  s.add_dependency 'graphql-client', '>0'
50
50
  s.add_dependency 'judges', '>0'
51
+ s.add_dependency 'liquid', '5.5.1'
51
52
  s.add_dependency 'loog', '>0'
52
53
  s.add_dependency 'obk', '>0'
53
54
  s.add_dependency 'octokit', '>0'
data/lib/fbe/award.rb CHANGED
@@ -23,10 +23,11 @@
23
23
  # SOFTWARE.
24
24
 
25
25
  require 'factbase/syntax'
26
+ require_relative 'fb'
26
27
 
27
28
  # A generator of awards.
28
29
  #
29
- # First, you should create a policy, using the same Lisp-ish syntax as
30
+ # First, you should create a bylaw, using the same Lisp-ish syntax as
30
31
  # we use in queries to a Factbase, for example:
31
32
  #
32
33
  # require 'fbe/award'
@@ -38,17 +39,17 @@ require 'factbase/syntax'
38
39
  # puts b.points # how many points to reward, a number
39
40
  # puts b.greeting # how to explain the reward, a text
40
41
  #
41
- # Or else, you can get a policy text:
42
+ # Or else, you can get a bylaw text:
42
43
  #
43
- # p = a.policy
44
- # puts p.markdown # Markdown of the policy
44
+ # p = a.bylaw
45
+ # puts p.markdown # Markdown of the bylaw
45
46
  #
46
47
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
47
48
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
48
49
  # License:: MIT
49
50
  class Fbe::Award
50
51
  # Ctor.
51
- # @param [String] query The query with the policy
52
+ # @param [String] query The query with the bylaw
52
53
  # @param [String] judge The name of the judge
53
54
  def initialize(query = nil, judge: $judge, global: $global, options: $options, loog: $loog)
54
55
  query = Fbe.pmp(fb: Fbe.fb, global:, options:, loog:).hr.send(judge.gsub('-', '_')) if query.nil?
@@ -66,13 +67,13 @@ class Fbe::Award
66
67
  bill
67
68
  end
68
69
 
69
- # Build a policy object from this award query.
70
- # @return [Fbe::Award::Policy] The policy
71
- def policy
70
+ # Build a bylaw object from this award query.
71
+ # @return [Fbe::Award::Bylaw] The bylaw
72
+ def bylaw
72
73
  term = Factbase::Syntax.new(@query, term: Fbe::Award::PTerm).to_term
73
- policy = Policy.new
74
- term.publish_to(policy)
75
- policy
74
+ bylaw = Bylaw.new
75
+ term.publish_to(bylaw)
76
+ bylaw
76
77
  end
77
78
 
78
79
  # A term for bill.
@@ -172,7 +173,7 @@ class Fbe::Award
172
173
  end
173
174
  end
174
175
 
175
- # A term for policy.
176
+ # A term for bylaw.
176
177
  class PTerm
177
178
  def initialize(operator, operands)
178
179
  @op = operator
@@ -220,33 +221,33 @@ class Fbe::Award
220
221
  end
221
222
  end
222
223
 
223
- def publish_to(policy)
224
+ def publish_to(bylaw)
224
225
  case @op
225
226
  when :award
226
227
  @operands.each do |o|
227
- o.publish_to(policy)
228
+ o.publish_to(bylaw)
228
229
  rescue StandardError => e
229
230
  raise "Failure in #{o}: #{e.message}"
230
231
  end
231
232
  when :aka
232
233
  @operands[0..-2].each do |o|
233
- o.publish_to(policy)
234
+ o.publish_to(bylaw)
234
235
  rescue StandardError => e
235
236
  raise "Failure in #{o}: #{e.message}"
236
237
  end
237
- policy.revert(@operands.size - 1)
238
- policy.line(to_p(@operands[@operands.size - 1]))
238
+ bylaw.revert(@operands.size - 1)
239
+ bylaw.line(to_p(@operands[@operands.size - 1]))
239
240
  when :explain
240
- policy.intro(to_p(@operands[0]))
241
+ bylaw.intro(to_p(@operands[0]))
241
242
  when :in
242
- policy.line("assume that #{to_p(@operands[0])} is #{to_p(@operands[1])}")
243
+ bylaw.line("assume that #{to_p(@operands[0])} is #{to_p(@operands[1])}")
243
244
  when :let
244
- policy.line("let #{to_p(@operands[0])} be equal to #{to_p(@operands[1])}")
245
- policy.let(@operands[0], @operands[1])
245
+ bylaw.line("let #{to_p(@operands[0])} be equal to #{to_p(@operands[1])}")
246
+ bylaw.let(@operands[0], @operands[1])
246
247
  when :set
247
- policy.line("set #{to_p(@operands[0])} to #{to_p(@operands[1])}")
248
+ bylaw.line("set #{to_p(@operands[0])} to #{to_p(@operands[1])}")
248
249
  when :give
249
- policy.line("award #{to_p(@operands[0])}")
250
+ bylaw.line("award #{to_p(@operands[0])}")
250
251
  else
251
252
  raise "Unknown term '#{@op}'"
252
253
  end
@@ -316,8 +317,8 @@ class Fbe::Award
316
317
  end
317
318
  end
318
319
 
319
- # A policy.
320
- class Policy
320
+ # A bylaw.
321
+ class Bylaw
321
322
  attr_reader :vars
322
323
 
323
324
  def initialize
data/lib/fbe/bylaws.rb ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # MIT License
4
+ #
5
+ # Copyright (c) 2024 Zerocracy
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+
25
+ require 'liquid'
26
+ require_relative '../fbe'
27
+
28
+ # A generator of policies/bylaws.
29
+ #
30
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
31
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
32
+ # License:: MIT
33
+ def Fbe.bylaws(anger: 2, love: 2)
34
+ home = File.join(__dir__, '../../assets/bylaws')
35
+ raise "The directory with templates is absent '#{home}'" unless File.exist?(home)
36
+ Dir[File.join(home, '*.liquid')].to_h do |f|
37
+ formula = Liquid::Template.parse(File.read(f)).render(
38
+ 'anger' => anger, 'love' => love
39
+ )
40
+ [File.basename(f).gsub(/\.liquid$/, ''), formula]
41
+ end
42
+ end
data/lib/fbe/conclude.rb CHANGED
@@ -33,7 +33,7 @@ require_relative 'if_absent'
33
33
  # @param [String] judge The name of the judge, from the +judges+ tool
34
34
  # @param [Hash] global The hash for global caching
35
35
  # @param [Judges::Options] options The options coming from the +judges+ tool
36
- # @param [Loog] logg The logging facility
36
+ # @param [Loog] loog The logging facility
37
37
  def Fbe.conclude(fb: Fbe.fb, judge: $judge, loog: $loog, options: $options, global: $global, &)
38
38
  c = Fbe::Conclude.new(fb:, judge:, loog:, options:, global:)
39
39
  c.instance_eval(&)
@@ -50,7 +50,7 @@ class Fbe::Conclude
50
50
  # @param [String] judge The name of the judge, from the +judges+ tool
51
51
  # @param [Hash] global The hash for global caching
52
52
  # @param [Judges::Options] options The options coming from the +judges+ tool
53
- # @param [Loog] logg The logging facility
53
+ # @param [Loog] loog The logging facility
54
54
  def initialize(fb:, judge:, global:, options:, loog:)
55
55
  @fb = fb
56
56
  @judge = judge
data/lib/fbe/fb.rb CHANGED
@@ -35,7 +35,7 @@ require_relative '../fbe'
35
35
  # @param [Factbase] fb The global factbase provided by the +judges+ tool
36
36
  # @param [Hash] global The hash for global caching
37
37
  # @param [Judges::Options] options The options coming from the +judges+ tool
38
- # @param [Loog] logg The logging facility
38
+ # @param [Loog] loog The logging facility
39
39
  def Fbe.fb(fb: $fb, global: $global, options: $options, loog: $loog)
40
40
  global[:fb] ||=
41
41
  begin
data/lib/fbe/issue.rb CHANGED
@@ -29,7 +29,7 @@ require_relative '../fbe'
29
29
  # @param [Factbase::Fact] fact The fact, where to get the ID of GitHub issue
30
30
  # @param [Judges::Options] options The options coming from the +judges+ tool
31
31
  # @param [Hash] global The hash for global caching
32
- # @param [Loog] logg The logging facility
32
+ # @param [Loog] loog The logging facility
33
33
  def Fbe.issue(fact, options: $options, global: $global, loog: $loog)
34
34
  rid = fact['repository']
35
35
  raise "There is no 'repository' property" if rid.nil?
data/lib/fbe/overwrite.rb CHANGED
@@ -36,7 +36,7 @@ require_relative 'fb'
36
36
  #
37
37
  # @param [Factbase::Fact] fact The fact to modify
38
38
  # @param [String] property The name of the property to set
39
- # @param [Any] vqlue The value to set
39
+ # @param [Any] value The value to set
40
40
  def Fbe.overwrite(fact, property, value, fb: Fbe.fb)
41
41
  raise 'The fact is nil' if fact.nil?
42
42
  raise "The property is not a String but #{property.class} (#{property})" unless property.is_a?(String)
data/lib/fbe/pmp.rb CHANGED
@@ -31,7 +31,7 @@ require_relative '../fbe'
31
31
  # @param [Factbase] fb The factbase
32
32
  # @param [Hash] global The hash for global caching
33
33
  # @param [Judges::Options] options The options coming from the +judges+ tool
34
- # @param [Loog] logg The logging facility
34
+ # @param [Loog] loog The logging facility
35
35
  def Fbe.pmp(fb: Fbe.fb, global: $global, options: $options, loog: $loog)
36
36
  others do |*args1|
37
37
  area = args1.first
data/lib/fbe/regularly.rb CHANGED
@@ -32,7 +32,7 @@ require_relative 'fb'
32
32
  # @param [Integer] p_since_days Since when to collect stats, X days
33
33
  # @param [Factbase] fb The factbase
34
34
  # @param [String] judge The name of the judge, from the +judges+ tool
35
- # @param [Loog] logg The logging facility
35
+ # @param [Loog] loog The logging facility
36
36
  def Fbe.regularly(area, p_every_days, p_since_days = nil, fb: Fbe.fb, judge: $judge, loog: $loog, &)
37
37
  pmp = fb.query("(and (eq what 'pmp') (eq area '#{area}') (exists #{p_every_days}))").each.to_a.first
38
38
  interval = pmp.nil? ? 7 : pmp[p_every_days].first
@@ -32,7 +32,7 @@ require_relative 'overwrite'
32
32
  # @param [Integer] p_every_hours How frequently to run, every X hours
33
33
  # @param [Factbase] fb The factbase
34
34
  # @param [String] judge The name of the judge, from the +judges+ tool
35
- # @param [Loog] logg The logging facility
35
+ # @param [Loog] loog The logging facility
36
36
  def Fbe.repeatedly(area, p_every_hours, fb: Fbe.fb, judge: $judge, loog: $loog, &)
37
37
  pmp = fb.query("(and (eq what 'pmp') (eq area '#{area}') (exists #{p_every_hours}))").each.to_a.first
38
38
  hours = pmp.nil? ? 24 : pmp[p_every_hours].first
data/lib/fbe/who.rb CHANGED
@@ -30,7 +30,7 @@ require_relative '../fbe'
30
30
  # @param [String] prop The property in the fact, with the ID
31
31
  # @param [Judges::Options] options The options coming from the +judges+ tool
32
32
  # @param [Hash] global The hash for global caching
33
- # @param [Loog] logg The logging facility
33
+ # @param [Loog] loog The logging facility
34
34
  def Fbe.who(fact, prop = :who, options: $options, global: $global, loog: $loog)
35
35
  id = fact[prop.to_s]
36
36
  raise "There is no #{prop} property" if id.nil?
data/lib/fbe.rb CHANGED
@@ -27,5 +27,5 @@
27
27
  # License:: MIT
28
28
  module Fbe
29
29
  # Current version of the gem (changed by .rultor.yml on every release)
30
- VERSION = '0.0.55'
30
+ VERSION = '0.0.56'
31
31
  end
@@ -73,7 +73,7 @@ class TestAward < Minitest::Test
73
73
  'bug in 10 (<36) hours',
74
74
  '+30 as a basis'
75
75
  ].each { |t| assert(g.include?(t), g) }
76
- md = a.policy.markdown
76
+ md = a.bylaw.markdown
77
77
  [
78
78
  'First, assume that _hours_ is hours',
79
79
  ', and award _b₂_'
@@ -129,7 +129,7 @@ class TestAward < Minitest::Test
129
129
  '(award (aka (let x 17) (give x "hey") "add ${x} when necessary"))' =>
130
130
  'Just add **17** when necessary'
131
131
  }.each do |q, t|
132
- md = Fbe::Award.new(q).policy.markdown
132
+ md = Fbe::Award.new(q).bylaw.markdown
133
133
  assert(md.include?(t), md)
134
134
  end
135
135
  end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ # MIT License
4
+ #
5
+ # Copyright (c) 2024 Zerocracy
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+
25
+ require 'minitest/autorun'
26
+ require 'loog'
27
+ require_relative '../test__helper'
28
+ require_relative '../../lib/fbe/award'
29
+ require_relative '../../lib/fbe/bylaws'
30
+
31
+ # Test.
32
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
33
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
34
+ # License:: MIT
35
+ class TestBylaws < Minitest::Test
36
+ def test_simple
37
+ laws = Fbe.bylaws
38
+ assert(laws.size > 1)
39
+ assert(!laws['published-release-was-rewarded'].nil?)
40
+ end
41
+
42
+ def test_check_all_bills
43
+ awards = {
44
+ 'published-release-was-rewarded' => {
45
+ { hoc: 0, contributors: 1 } => 24,
46
+ { hoc: 10, contributors: 1 } => 24,
47
+ { hoc: 100, contributors: 1 } => 24,
48
+ { hoc: 500, contributors: 1 } => 29,
49
+ { hoc: 1_000, contributors: 1 } => 32,
50
+ { hoc: 10_000, contributors: 1 } => 32,
51
+ { hoc: 30_000, contributors: 1 } => 32
52
+ },
53
+ 'resolved-bug-was-rewarded' => {
54
+ { hours: 1, self: 0 } => 24,
55
+ { hours: 48, self: 0 } => 14,
56
+ { hours: 80, self: 0 } => 13,
57
+ { hours: 300, self: 0 } => 4,
58
+ { hours: 3_000, self: 0 } => 4,
59
+ { hours: 30_000, self: 0 } => 4,
60
+ { hours: 1, self: 1 } => 8
61
+ },
62
+ 'push-to-master-was-punished' => {
63
+ {} => -16
64
+ },
65
+ 'code-review-was-rewarded' => {
66
+ { hoc: 0, comments: 0, self: 0 } => 4,
67
+ { hoc: 3, comments: 0, self: 0 } => 4,
68
+ { hoc: 78, comments: 7, self: 0 } => 8,
69
+ { hoc: 600, comments: 1, self: 0 } => 10,
70
+ { hoc: 500, comments: 40, self: 0 } => 26,
71
+ { hoc: 5_000, comments: 100, self: 0 } => 32,
72
+ { hoc: 100, comments: 50, self: 1 } => 4,
73
+ { hoc: 10_000, comments: 200, self: 1 } => 4
74
+ },
75
+ 'code-contribution-was-rewarded' => {
76
+ { hoc: 0, comments: 0, reviews: 0 } => 4,
77
+ { hoc: 3, comments: 0, reviews: 0 } => 4,
78
+ { hoc: 78, comments: 0, reviews: 0 } => 4,
79
+ { hoc: 78, comments: 1, reviews: 0 } => 4,
80
+ { hoc: 50, comments: 15, reviews: 0 } => 5,
81
+ { hoc: 50, comments: 25, reviews: 0 } => 4,
82
+ { hoc: 180, comments: 7, reviews: 2 } => 32,
83
+ { hoc: 150, comments: 5, reviews: 1 } => 31,
84
+ { hoc: 500, comments: 25, reviews: 2 } => 4,
85
+ { hoc: 99, comments: 6, reviews: 1 } => 26,
86
+ { hoc: 1_500, comments: 3, reviews: 0 } => 4,
87
+ { hoc: 15_000, comments: 40, reviews: 0 } => 4
88
+ },
89
+ 'bug-report-was-rewarded' => {
90
+ {} => 16
91
+ },
92
+ 'enhancement-suggestion-was-rewarded' => {
93
+ {} => 16
94
+ },
95
+ 'dud-was-punished' => {
96
+ {} => -16
97
+ },
98
+ 'bad-branch-name-was-punished' => {
99
+ {} => -12
100
+ }
101
+ }
102
+ awards.each do |title, pairs|
103
+ formula = Fbe.bylaws[title]
104
+ assert(!formula.nil?, title)
105
+ a = Fbe::Award.new(formula)
106
+ help = [
107
+ " #{title}: {\n ",
108
+ pairs.map do |args, _|
109
+ [
110
+ '{',
111
+ args.empty? ? '' : "#{args.map { |k, v| " #{k}: #{v.to_s.gsub(/(?<!^)([0-9]{3})$/, '_\1')}" }.join(',')} ",
112
+ "} => #{a.bill(args).points}"
113
+ ].join
114
+ end.join(",\n "),
115
+ "\n },"
116
+ ].join
117
+ pairs.each do |args, points|
118
+ b = a.bill(args)
119
+ next if b.points == points
120
+ raise \
121
+ "Wrong reward of #{b.points} points from #{title}, " \
122
+ "while #{points} expected (#{args}): #{b.greeting}\n\n#{help}"
123
+ end
124
+ end
125
+ end
126
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fbe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.55
4
+ version: 0.0.56
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-18 00:00:00.000000000 Z
11
+ date: 2024-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: liquid
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '='
144
+ - !ruby/object:Gem::Version
145
+ version: 5.5.1
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: 5.5.1
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: loog
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -236,9 +250,19 @@ files:
236
250
  - LICENSE.txt
237
251
  - README.md
238
252
  - Rakefile
253
+ - assets/bylaws/bad-branch-name-was-punished.liquid
254
+ - assets/bylaws/bug-report-was-rewarded.liquid
255
+ - assets/bylaws/code-contribution-was-rewarded.liquid
256
+ - assets/bylaws/code-review-was-rewarded.liquid
257
+ - assets/bylaws/dud-was-punished.liquid
258
+ - assets/bylaws/enhancement-suggestion-was-rewarded.liquid
259
+ - assets/bylaws/published-release-was-rewarded.liquid
260
+ - assets/bylaws/push-to-master-was-punished.liquid
261
+ - assets/bylaws/resolved-bug-was-rewarded.liquid
239
262
  - fbe.gemspec
240
263
  - lib/fbe.rb
241
264
  - lib/fbe/award.rb
265
+ - lib/fbe/bylaws.rb
242
266
  - lib/fbe/conclude.rb
243
267
  - lib/fbe/copy.rb
244
268
  - lib/fbe/fb.rb
@@ -261,6 +285,7 @@ files:
261
285
  - rules/basic.fe
262
286
  - test/fbe/middleware/test_quota.rb
263
287
  - test/fbe/test_award.rb
288
+ - test/fbe/test_bylaws.rb
264
289
  - test/fbe/test_conclude.rb
265
290
  - test/fbe/test_copy.rb
266
291
  - test/fbe/test_fb.rb