fbe 0.0.55 → 0.0.56
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/.simplecov +1 -1
- data/Gemfile.lock +18 -12
- data/README.md +6 -2
- data/assets/bylaws/bad-branch-name-was-punished.liquid +7 -0
- data/assets/bylaws/bug-report-was-rewarded.liquid +7 -0
- data/assets/bylaws/code-contribution-was-rewarded.liquid +82 -0
- data/assets/bylaws/code-review-was-rewarded.liquid +68 -0
- data/assets/bylaws/dud-was-punished.liquid +7 -0
- data/assets/bylaws/enhancement-suggestion-was-rewarded.liquid +7 -0
- data/assets/bylaws/published-release-was-rewarded.liquid +29 -0
- data/assets/bylaws/push-to-master-was-punished.liquid +7 -0
- data/assets/bylaws/resolved-bug-was-rewarded.liquid +40 -0
- data/fbe.gemspec +1 -0
- data/lib/fbe/award.rb +26 -25
- data/lib/fbe/bylaws.rb +42 -0
- data/lib/fbe/conclude.rb +2 -2
- data/lib/fbe/fb.rb +1 -1
- data/lib/fbe/issue.rb +1 -1
- data/lib/fbe/overwrite.rb +1 -1
- data/lib/fbe/pmp.rb +1 -1
- data/lib/fbe/regularly.rb +1 -1
- data/lib/fbe/repeatedly.rb +1 -1
- data/lib/fbe/who.rb +1 -1
- data/lib/fbe.rb +1 -1
- data/test/fbe/test_award.rb +2 -2
- data/test/fbe/test_bylaws.rb +126 -0
- metadata +27 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50405a3f7472db8c909709be30db7a6eed4f5923fca49fac7ac58da9e936c324
|
4
|
+
data.tar.gz: 60d9ca2097226f9763e532e0f27f020087994953d772029fb7bfb9570e6c8396
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a4f743d351eb119586a77f6d675f4c311b511bd72823da1b4be71eb4ba5abcd70a22be42c91973835cc3b5451ae8c8bb68015945f1104ef504a23be073c2913
|
7
|
+
data.tar.gz: e3dc8bfefcfc1fbcc5519af0961b8aea92c0ea2702e9d348710557e95ccfb8df725e4d350ecb7e11a3cac839893d27c77a709458cc0dab9c29a9a85eb77da5b6
|
data/.simplecov
CHANGED
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.
|
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.
|
125
|
-
backtrace (
|
126
|
-
baza.rb (
|
128
|
+
judges (0.26.0)
|
129
|
+
backtrace (> 0)
|
130
|
+
baza.rb (> 0)
|
127
131
|
concurrent-ruby (~> 1.2)
|
128
|
-
|
132
|
+
elapsed (> 0)
|
133
|
+
factbase (> 0)
|
129
134
|
gli (~> 2.21)
|
130
|
-
iri (
|
131
|
-
loog (
|
135
|
+
iri (> 0)
|
136
|
+
loog (> 0)
|
132
137
|
moments (~> 0.3)
|
133
138
|
nokogiri (~> 1.10)
|
134
|
-
others (
|
135
|
-
retries (
|
136
|
-
tago (
|
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.
|
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.
|
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
|
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,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,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,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
|
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
|
42
|
+
# Or else, you can get a bylaw text:
|
42
43
|
#
|
43
|
-
# p = a.
|
44
|
-
# puts p.markdown # Markdown of the
|
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
|
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
|
70
|
-
# @return [Fbe::Award::
|
71
|
-
def
|
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
|
-
|
74
|
-
term.publish_to(
|
75
|
-
|
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
|
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(
|
224
|
+
def publish_to(bylaw)
|
224
225
|
case @op
|
225
226
|
when :award
|
226
227
|
@operands.each do |o|
|
227
|
-
o.publish_to(
|
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(
|
234
|
+
o.publish_to(bylaw)
|
234
235
|
rescue StandardError => e
|
235
236
|
raise "Failure in #{o}: #{e.message}"
|
236
237
|
end
|
237
|
-
|
238
|
-
|
238
|
+
bylaw.revert(@operands.size - 1)
|
239
|
+
bylaw.line(to_p(@operands[@operands.size - 1]))
|
239
240
|
when :explain
|
240
|
-
|
241
|
+
bylaw.intro(to_p(@operands[0]))
|
241
242
|
when :in
|
242
|
-
|
243
|
+
bylaw.line("assume that #{to_p(@operands[0])} is #{to_p(@operands[1])}")
|
243
244
|
when :let
|
244
|
-
|
245
|
-
|
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
|
-
|
248
|
+
bylaw.line("set #{to_p(@operands[0])} to #{to_p(@operands[1])}")
|
248
249
|
when :give
|
249
|
-
|
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
|
320
|
-
class
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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
|
data/lib/fbe/repeatedly.rb
CHANGED
@@ -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]
|
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]
|
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
data/test/fbe/test_award.rb
CHANGED
@@ -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.
|
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).
|
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.
|
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-
|
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
|