fbe 0.0.35 → 0.0.37
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +6 -6
- data/lib/fbe/award.rb +23 -3
- data/lib/fbe/fb.rb +16 -14
- data/lib/fbe/if_absent.rb +8 -7
- data/lib/fbe/octo.rb +101 -81
- data/lib/fbe/pmp.rb +43 -0
- data/lib/fbe/unmask_repos.rb +3 -1
- data/lib/fbe.rb +1 -1
- data/test/fbe/test_award.rb +18 -1
- data/test/fbe/test_if_absent.rb +26 -21
- data/test/fbe/test_octo.rb +6 -0
- data/test/fbe/test_pmp.rb +54 -0
- data/test/fbe/test_unmask_repos.rb +7 -4
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 412a42887c949db37c75084feeed5b3c187284a34491d3412da0abdf812dfbca
|
4
|
+
data.tar.gz: 3b16ac60cbad4ab99ba3c141be9e1b347db16c884826d307341bddd4eea164b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bedce35fba41f38cd0605a2fb5ad32497e00f4a95db0a130c15c1d8d886955d797024410b1d96844470792fe0731db6ae97d332ce472ffd4db39cfb710483a8
|
7
|
+
data.tar.gz: f43d741abf35225cc9d4708ef255fc7abf56f5288560b1b7e56e876e84781bfeacde5a8c5a5ca20240a8b8fd6be49045a1bf14e206ccf881cae5142e648c7592
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -27,9 +27,9 @@ gem 'minitest', '5.24.1', require: false
|
|
27
27
|
gem 'minitest-reporters', '1.7.1', require: false
|
28
28
|
gem 'rake', '13.2.1', require: false
|
29
29
|
gem 'rspec-rails', '6.1.3', require: false
|
30
|
-
gem 'rubocop', '1.65.
|
30
|
+
gem 'rubocop', '1.65.1', require: false
|
31
31
|
gem 'rubocop-performance', '1.21.1', require: false
|
32
|
-
gem 'rubocop-rspec', '3.0.
|
32
|
+
gem 'rubocop-rspec', '3.0.4', require: false
|
33
33
|
gem 'simplecov', '0.22.0', require: false
|
34
34
|
gem 'simplecov-cobertura', '2.1.0', require: false
|
35
35
|
gem 'webmock', '3.23.1', require: false
|
data/Gemfile.lock
CHANGED
@@ -150,7 +150,7 @@ GEM
|
|
150
150
|
psych (5.1.2)
|
151
151
|
stringio
|
152
152
|
public_suffix (6.0.0)
|
153
|
-
racc (1.8.
|
153
|
+
racc (1.8.1)
|
154
154
|
rack (3.1.7)
|
155
155
|
rack-session (2.0.0)
|
156
156
|
rack (>= 3.0.0)
|
@@ -182,7 +182,7 @@ GEM
|
|
182
182
|
reline (0.5.9)
|
183
183
|
io-console (~> 0.5)
|
184
184
|
retries (0.0.5)
|
185
|
-
rexml (3.3.
|
185
|
+
rexml (3.3.4)
|
186
186
|
strscan
|
187
187
|
rspec-core (3.13.0)
|
188
188
|
rspec-support (~> 3.13.0)
|
@@ -201,7 +201,7 @@ GEM
|
|
201
201
|
rspec-mocks (~> 3.13)
|
202
202
|
rspec-support (~> 3.13)
|
203
203
|
rspec-support (3.13.1)
|
204
|
-
rubocop (1.65.
|
204
|
+
rubocop (1.65.1)
|
205
205
|
json (~> 2.3)
|
206
206
|
language_server-protocol (>= 3.17.0)
|
207
207
|
parallel (~> 1.10)
|
@@ -217,7 +217,7 @@ GEM
|
|
217
217
|
rubocop-performance (1.21.1)
|
218
218
|
rubocop (>= 1.48.1, < 2.0)
|
219
219
|
rubocop-ast (>= 1.31.1, < 2.0)
|
220
|
-
rubocop-rspec (3.0.
|
220
|
+
rubocop-rspec (3.0.4)
|
221
221
|
rubocop (~> 1.61)
|
222
222
|
ruby-progressbar (1.13.0)
|
223
223
|
sawyer (0.9.2)
|
@@ -267,9 +267,9 @@ DEPENDENCIES
|
|
267
267
|
minitest-reporters (= 1.7.1)
|
268
268
|
rake (= 13.2.1)
|
269
269
|
rspec-rails (= 6.1.3)
|
270
|
-
rubocop (= 1.65.
|
270
|
+
rubocop (= 1.65.1)
|
271
271
|
rubocop-performance (= 1.21.1)
|
272
|
-
rubocop-rspec (= 3.0.
|
272
|
+
rubocop-rspec (= 3.0.4)
|
273
273
|
simplecov (= 0.22.0)
|
274
274
|
simplecov-cobertura (= 2.1.0)
|
275
275
|
webmock (= 3.23.1)
|
data/lib/fbe/award.rb
CHANGED
@@ -47,10 +47,17 @@ require 'factbase/syntax'
|
|
47
47
|
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
48
48
|
# License:: MIT
|
49
49
|
class Fbe::Award
|
50
|
-
|
50
|
+
# Ctor.
|
51
|
+
# @param [String] query The query with the policy
|
52
|
+
# @param [String] judge The name of the judge
|
53
|
+
def initialize(query = nil, judge: $judge, global: $global, options: $options, loog: $loog)
|
54
|
+
query = Fbe.pmp(fb: Fbe.fb, global:, options:, loog:).hr.send(judge.gsub('-', '_')) if query.nil?
|
51
55
|
@query = query
|
52
56
|
end
|
53
57
|
|
58
|
+
# Build a bill object from this award query.
|
59
|
+
# @param [Hash] vars Hash of variables
|
60
|
+
# @return [Fbe::Award::Bill] The bill
|
54
61
|
def bill(vars = {})
|
55
62
|
term = Factbase::Syntax.new(@query, term: Fbe::Award::BTerm).to_term
|
56
63
|
bill = Bill.new
|
@@ -59,6 +66,8 @@ class Fbe::Award
|
|
59
66
|
bill
|
60
67
|
end
|
61
68
|
|
69
|
+
# Build a policy object from this award query.
|
70
|
+
# @return [Fbe::Award::Policy] The policy
|
62
71
|
def policy
|
63
72
|
term = Factbase::Syntax.new(@query, term: Fbe::Award::PTerm).to_term
|
64
73
|
policy = Policy.new
|
@@ -122,6 +131,12 @@ class Fbe::Award
|
|
122
131
|
bill.points
|
123
132
|
when :if
|
124
133
|
to_val(@operands[0], bill) ? to_val(@operands[1], bill) : to_val(@operands[2], bill)
|
134
|
+
when :and
|
135
|
+
@operands.all? { |o| to_val(o, bill) }
|
136
|
+
when :or
|
137
|
+
@operands.any? { |o| to_val(o, bill) }
|
138
|
+
when :not
|
139
|
+
!to_val(@operands[0], bill)
|
125
140
|
when :eq
|
126
141
|
to_val(@operands[0], bill) == to_val(@operands[1], bill)
|
127
142
|
when :lt
|
@@ -150,7 +165,6 @@ class Fbe::Award
|
|
150
165
|
b = to_val(@operands[2], bill)
|
151
166
|
min, max = [a, b].minmax
|
152
167
|
return 0 if (!v.negative? && v < min) || (!v.positive? && v > max)
|
153
|
-
|
154
168
|
v.clamp(min, max)
|
155
169
|
else
|
156
170
|
raise "Unknown term '#{@op}'"
|
@@ -171,6 +185,12 @@ class Fbe::Award
|
|
171
185
|
'total'
|
172
186
|
when :if
|
173
187
|
"if #{to_p(@operands[0])} then #{to_p(@operands[1])} else #{to_p(@operands[2])}"
|
188
|
+
when :and
|
189
|
+
@operands.map(&:to_s).join(' and ')
|
190
|
+
when :or
|
191
|
+
@operands.map(&:to_s).join(' or ')
|
192
|
+
when :not
|
193
|
+
"not #{@operands[0]}"
|
174
194
|
when :eq
|
175
195
|
"#{to_p(@operands[0])} = #{to_p(@operands[1])}"
|
176
196
|
when :lt
|
@@ -332,7 +352,7 @@ class Fbe::Award
|
|
332
352
|
else
|
333
353
|
pars += @lines.each_with_index.map { |t, i| "#{i.zero? ? 'First' : 'Then'}, #{t}." }
|
334
354
|
end
|
335
|
-
pars.join(' ').gsub('. Then, award ', ', and award ')
|
355
|
+
pars.join(' ').gsub('. Then, award ', ', and award ').gsub(/\s{2,}/, ' ')
|
336
356
|
end
|
337
357
|
end
|
338
358
|
end
|
data/lib/fbe/fb.rb
CHANGED
@@ -31,19 +31,21 @@ require 'factbase/rules'
|
|
31
31
|
require_relative '../fbe'
|
32
32
|
|
33
33
|
def Fbe.fb(fb: $fb, global: $global, options: $options, loog: $loog)
|
34
|
-
global[:fb] ||=
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
global[:fb] ||=
|
35
|
+
begin
|
36
|
+
rules = Dir.glob(File.join('rules', '*.fe')).map { |f| File.read(f) }
|
37
|
+
fbe = Factbase::Rules.new(
|
38
|
+
fb,
|
39
|
+
"(and \n#{rules.join("\n")}\n)",
|
40
|
+
uid: '_id'
|
41
|
+
)
|
42
|
+
fbe =
|
43
|
+
Factbase::Pre.new(fbe) do |f|
|
44
|
+
max = fb.query('(eq _id (max _id))').each.to_a.first
|
45
|
+
f._id = (max.nil? ? 0 : max._id) + 1
|
46
|
+
f._time = Time.now
|
47
|
+
f._version = "#{Factbase::VERSION}/#{Judges::VERSION}/#{options.judges_action_version}"
|
48
|
+
end
|
49
|
+
Factbase::Looged.new(fbe, loog)
|
46
50
|
end
|
47
|
-
Factbase::Looged.new(fbe, loog)
|
48
|
-
end
|
49
51
|
end
|
data/lib/fbe/if_absent.rb
CHANGED
@@ -30,14 +30,15 @@ require_relative 'fb'
|
|
30
30
|
# Injects a fact if it's absent in the factbase.
|
31
31
|
def Fbe.if_absent(fb: Fbe.fb)
|
32
32
|
attrs = {}
|
33
|
-
f =
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
f =
|
34
|
+
others(map: attrs) do |*args|
|
35
|
+
k = args[0]
|
36
|
+
if k.end_with?('=')
|
37
|
+
@map[k[0..-2].to_sym] = args[1]
|
38
|
+
else
|
39
|
+
@map[k.to_sym]
|
40
|
+
end
|
39
41
|
end
|
40
|
-
end
|
41
42
|
yield f
|
42
43
|
q = attrs.except('_id', '_time', '_version').map do |k, v|
|
43
44
|
vv = v.to_s
|
data/lib/fbe/octo.rb
CHANGED
@@ -35,97 +35,99 @@ require_relative 'middleware/quota'
|
|
35
35
|
|
36
36
|
def Fbe.octo(options: $options, global: $global, loog: $loog)
|
37
37
|
raise 'The $global is not set' if global.nil?
|
38
|
-
global[:octo] ||=
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
loog.debug("The 'github_token' option is not provided")
|
44
|
-
token = ENV.fetch('GITHUB_TOKEN', nil)
|
38
|
+
global[:octo] ||=
|
39
|
+
begin
|
40
|
+
if options.testing.nil?
|
41
|
+
o = Octokit::Client.new
|
42
|
+
token = options.github_token
|
45
43
|
if token.nil?
|
46
|
-
loog.debug("The '
|
44
|
+
loog.debug("The 'github_token' option is not provided")
|
45
|
+
token = ENV.fetch('GITHUB_TOKEN', nil)
|
46
|
+
if token.nil?
|
47
|
+
loog.debug("The 'GITHUB_TOKEN' environment variable is not set")
|
48
|
+
else
|
49
|
+
loog.debug("The 'GITHUB_TOKEN' environment was provided")
|
50
|
+
end
|
47
51
|
else
|
48
|
-
loog.debug("The '
|
52
|
+
loog.debug("The 'github_token' option was provided")
|
49
53
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
loog.warn('Accessing GitHub API without a token!')
|
55
|
-
elsif token.empty?
|
56
|
-
loog.warn('The GitHub API token is an empty string, won\'t use it')
|
57
|
-
else
|
58
|
-
o = Octokit::Client.new(access_token: token)
|
59
|
-
loog.info("Accessing GitHub API with a token (#{token.length} chars, ending by #{token[-4..]})")
|
60
|
-
end
|
61
|
-
o.auto_paginate = true
|
62
|
-
o.per_page = 100
|
63
|
-
o.connection_options = {
|
64
|
-
request: {
|
65
|
-
open_timeout: 15,
|
66
|
-
timeout: 15
|
67
|
-
}
|
68
|
-
}
|
69
|
-
stack = Faraday::RackBuilder.new do |builder|
|
70
|
-
builder.use(
|
71
|
-
Faraday::Retry::Middleware,
|
72
|
-
exceptions: Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [
|
73
|
-
Octokit::TooManyRequests, Octokit::ServiceUnavailable
|
74
|
-
],
|
75
|
-
max: 4,
|
76
|
-
interval: ENV['RACK_ENV'] == 'test' ? 0.01 : 4,
|
77
|
-
methods: [:get],
|
78
|
-
backoff_factor: 2
|
79
|
-
)
|
80
|
-
builder.use(
|
81
|
-
Fbe::Middleware::Quota,
|
82
|
-
logger: loog,
|
83
|
-
pause: options.github_api_pause
|
84
|
-
)
|
85
|
-
builder.use(Faraday::HttpCache, serializer: Marshal, shared_cache: false, logger: Loog::NULL)
|
86
|
-
builder.use(Octokit::Response::RaiseError)
|
87
|
-
builder.use(Faraday::Response::Logger, Loog::NULL)
|
88
|
-
builder.adapter(Faraday.default_adapter)
|
89
|
-
end
|
90
|
-
o.middleware = stack
|
91
|
-
o = Verbose.new(o, log: loog)
|
92
|
-
else
|
93
|
-
loog.debug('The connection to GitHub API is mocked')
|
94
|
-
o = Fbe::FakeOctokit.new
|
95
|
-
end
|
96
|
-
decoor(o, loog:) do
|
97
|
-
def off_quota
|
98
|
-
left = @origin.rate_limit.remaining
|
99
|
-
if left < 5
|
100
|
-
@loog.info("To much GitHub API quota consumed already (remaining=#{left}), stopping")
|
101
|
-
true
|
54
|
+
if token.nil?
|
55
|
+
loog.warn('Accessing GitHub API without a token!')
|
56
|
+
elsif token.empty?
|
57
|
+
loog.warn('The GitHub API token is an empty string, won\'t use it')
|
102
58
|
else
|
103
|
-
|
59
|
+
o = Octokit::Client.new(access_token: token)
|
60
|
+
loog.info("Accessing GitHub API with a token (#{token.length} chars, ending by #{token[-4..]})")
|
104
61
|
end
|
62
|
+
o.auto_paginate = true
|
63
|
+
o.per_page = 100
|
64
|
+
o.connection_options = {
|
65
|
+
request: {
|
66
|
+
open_timeout: 15,
|
67
|
+
timeout: 15
|
68
|
+
}
|
69
|
+
}
|
70
|
+
stack =
|
71
|
+
Faraday::RackBuilder.new do |builder|
|
72
|
+
builder.use(
|
73
|
+
Faraday::Retry::Middleware,
|
74
|
+
exceptions: Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [
|
75
|
+
Octokit::TooManyRequests, Octokit::ServiceUnavailable
|
76
|
+
],
|
77
|
+
max: 4,
|
78
|
+
interval: ENV['RACK_ENV'] == 'test' ? 0.01 : 4,
|
79
|
+
methods: [:get],
|
80
|
+
backoff_factor: 2
|
81
|
+
)
|
82
|
+
builder.use(
|
83
|
+
Fbe::Middleware::Quota,
|
84
|
+
logger: loog,
|
85
|
+
pause: options.github_api_pause
|
86
|
+
)
|
87
|
+
builder.use(Faraday::HttpCache, serializer: Marshal, shared_cache: false, logger: Loog::NULL)
|
88
|
+
builder.use(Octokit::Response::RaiseError)
|
89
|
+
builder.use(Faraday::Response::Logger, Loog::NULL)
|
90
|
+
builder.adapter(Faraday.default_adapter)
|
91
|
+
end
|
92
|
+
o.middleware = stack
|
93
|
+
o = Verbose.new(o, log: loog)
|
94
|
+
else
|
95
|
+
loog.debug('The connection to GitHub API is mocked')
|
96
|
+
o = Fbe::FakeOctokit.new
|
105
97
|
end
|
98
|
+
decoor(o, loog:) do
|
99
|
+
def off_quota
|
100
|
+
left = @origin.rate_limit.remaining
|
101
|
+
if left < 5
|
102
|
+
@loog.info("To much GitHub API quota consumed already (remaining=#{left}), stopping")
|
103
|
+
true
|
104
|
+
else
|
105
|
+
false
|
106
|
+
end
|
107
|
+
end
|
106
108
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
109
|
+
def user_name_by_id(id)
|
110
|
+
json = @origin.user(id)
|
111
|
+
name = json[:login]
|
112
|
+
@loog.debug("GitHub user ##{id} has a name: @#{name}")
|
113
|
+
name
|
114
|
+
end
|
113
115
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
116
|
+
def repo_id_by_name(name)
|
117
|
+
json = @origin.repository(name)
|
118
|
+
id = json[:id]
|
119
|
+
@loog.debug("GitHub repository #{name} has an ID: ##{id}")
|
120
|
+
id
|
121
|
+
end
|
120
122
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
def repo_name_by_id(id)
|
124
|
+
json = @origin.repository(id)
|
125
|
+
name = json[:full_name]
|
126
|
+
@loog.debug("GitHub repository ##{id} has a name: #{name}")
|
127
|
+
name
|
128
|
+
end
|
126
129
|
end
|
127
130
|
end
|
128
|
-
end
|
129
131
|
end
|
130
132
|
|
131
133
|
# Fake GitHub client, for tests.
|
@@ -189,6 +191,24 @@ class Fbe::FakeOctokit
|
|
189
191
|
}
|
190
192
|
end
|
191
193
|
|
194
|
+
def workflow_run_usage(_repo, _id)
|
195
|
+
{
|
196
|
+
billable: {
|
197
|
+
UBUNTU: {
|
198
|
+
total_ms: 0,
|
199
|
+
jobs: 1,
|
200
|
+
job_runs: [
|
201
|
+
{
|
202
|
+
job_id: 1,
|
203
|
+
duration_ms: 0
|
204
|
+
}
|
205
|
+
]
|
206
|
+
}
|
207
|
+
},
|
208
|
+
run_duration_ms: 53_000
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
192
212
|
def releases(_repo, _opts = {})
|
193
213
|
[
|
194
214
|
release('https://github...'),
|
@@ -235,7 +255,7 @@ class Fbe::FakeOctokit
|
|
235
255
|
has_pages: false,
|
236
256
|
has_discussions: false,
|
237
257
|
forks_count: 0,
|
238
|
-
archived:
|
258
|
+
archived: name == 'zerocracy/datum',
|
239
259
|
disabled: false,
|
240
260
|
open_issues_count: 6,
|
241
261
|
license: { key: 'mit', name: 'MIT License' },
|
data/lib/fbe/pmp.rb
ADDED
@@ -0,0 +1,43 @@
|
|
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 'others'
|
26
|
+
require_relative 'fb'
|
27
|
+
|
28
|
+
# Project management functions.
|
29
|
+
module Fbe; end
|
30
|
+
|
31
|
+
def Fbe.pmp(fb: Fbe.fb, global: $global, options: $options, loog: $loog)
|
32
|
+
others do |*args1|
|
33
|
+
area = args1.first
|
34
|
+
others do |*args2|
|
35
|
+
param = args2.first
|
36
|
+
f = Fbe.fb(global:, fb:, options:, loog:).query("(and (eq what 'pmp') (eq area '#{area}'))").each.to_a.first
|
37
|
+
raise "Unknown area '#{area}'" if f.nil?
|
38
|
+
r = f[param]
|
39
|
+
raise "Unknown property '#{param}' in the '#{area}' area" if r.nil?
|
40
|
+
r.first
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/fbe/unmask_repos.rb
CHANGED
@@ -37,6 +37,7 @@ module Fbe
|
|
37
37
|
|
38
38
|
def self.unmask_repos(options: $options, global: $global, loog: $loog)
|
39
39
|
repos = []
|
40
|
+
octo = Fbe.octo(loog:, global:, options:)
|
40
41
|
masks = (options.repositories || '').split(',')
|
41
42
|
masks.reject { |m| m.start_with?('-') }.each do |mask|
|
42
43
|
unless mask.include?('*')
|
@@ -44,7 +45,7 @@ module Fbe
|
|
44
45
|
next
|
45
46
|
end
|
46
47
|
re = Fbe.mask_to_regex(mask)
|
47
|
-
|
48
|
+
octo.repositories(mask.split('/')[0]).each do |r|
|
48
49
|
repos << r[:full_name] if re.match?(r[:full_name])
|
49
50
|
end
|
50
51
|
end
|
@@ -52,6 +53,7 @@ module Fbe
|
|
52
53
|
re = Fbe.mask_to_regex(mask[1..])
|
53
54
|
repos.reject! { |r| re.match?(r) }
|
54
55
|
end
|
56
|
+
repos.reject! { |repo| octo.repository(repo)[:archived] }
|
55
57
|
raise "No repos found matching: #{options.repositories}" if repos.empty?
|
56
58
|
loog.debug("Scanning #{repos.size} repositories: #{repos.join(', ')}...")
|
57
59
|
repos
|
data/lib/fbe.rb
CHANGED
data/test/fbe/test_award.rb
CHANGED
@@ -42,7 +42,12 @@ class TestAward < Minitest::Test
|
|
42
42
|
(give basis "as a basis")
|
43
43
|
(let fee 10)
|
44
44
|
(aka
|
45
|
-
(set b1
|
45
|
+
(set b1
|
46
|
+
(if
|
47
|
+
(and
|
48
|
+
(lt hours max)
|
49
|
+
(not (eq hours 0)))
|
50
|
+
fee 0))
|
46
51
|
(give b1 "for resolving the bug in ${hours} (<${max}) hours")
|
47
52
|
"add ${+fee} if it was resolved in less than ${max} hours")
|
48
53
|
(set days (div hours 24))
|
@@ -76,6 +81,7 @@ class TestAward < Minitest::Test
|
|
76
81
|
def test_some_terms
|
77
82
|
{
|
78
83
|
'(let x 25)' => 0,
|
84
|
+
'(award (give (times 5 0.25 "fun")))' => 1,
|
79
85
|
'(award (give 25 "for being a good boy"))' => 25,
|
80
86
|
'(award (give (between 42 -10 -50) "empty"))' => -10,
|
81
87
|
'(award (give (between -3 -10 -50) "empty"))' => 0,
|
@@ -86,6 +92,17 @@ class TestAward < Minitest::Test
|
|
86
92
|
end
|
87
93
|
end
|
88
94
|
|
95
|
+
def test_some_greetings
|
96
|
+
{
|
97
|
+
'(award (give (times 5 0.25 "fun")))' => 'You\'ve earned +1 points. ',
|
98
|
+
'(award (give 25 "for being a good boy"))' => 'You\'ve earned +25 points. ',
|
99
|
+
'(award (let x 0.1) (set b (times x 14)) (give b "fun"))' => 'You\'ve earned +1 points. '
|
100
|
+
}.each do |q, v|
|
101
|
+
a = Fbe::Award.new(q)
|
102
|
+
assert_equal(v, a.bill.greeting, q)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
89
106
|
def test_must_not_give_anything_when_too_small_value
|
90
107
|
{
|
91
108
|
'(award (give (between 0 5 20)))' => 0,
|
data/test/fbe/test_if_absent.rb
CHANGED
@@ -38,9 +38,10 @@ class TestIfAbsent < Minitest::Test
|
|
38
38
|
def test_ignores
|
39
39
|
fb = Factbase.new
|
40
40
|
fb.insert.foo = 'hello dude'
|
41
|
-
n =
|
42
|
-
|
43
|
-
|
41
|
+
n =
|
42
|
+
Fbe.if_absent(fb:) do |f|
|
43
|
+
f.foo = 'hello dude'
|
44
|
+
end
|
44
45
|
assert(n.nil?)
|
45
46
|
end
|
46
47
|
|
@@ -48,17 +49,19 @@ class TestIfAbsent < Minitest::Test
|
|
48
49
|
fb = Factbase.new
|
49
50
|
t = Time.now
|
50
51
|
fb.insert.foo = t
|
51
|
-
n =
|
52
|
-
|
53
|
-
|
52
|
+
n =
|
53
|
+
Fbe.if_absent(fb:) do |f|
|
54
|
+
f.foo = t
|
55
|
+
end
|
54
56
|
assert(n.nil?)
|
55
57
|
end
|
56
58
|
|
57
59
|
def test_injects
|
58
60
|
fb = Factbase.new
|
59
|
-
n =
|
60
|
-
|
61
|
-
|
61
|
+
n =
|
62
|
+
Fbe.if_absent(fb:) do |f|
|
63
|
+
f.foo = 42
|
64
|
+
end
|
62
65
|
assert_equal(42, n.foo)
|
63
66
|
end
|
64
67
|
|
@@ -77,12 +80,13 @@ class TestIfAbsent < Minitest::Test
|
|
77
80
|
t = Time.now
|
78
81
|
f1.z = t
|
79
82
|
f1.bar = 3.14
|
80
|
-
n =
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
n =
|
84
|
+
Fbe.if_absent(fb:) do |f|
|
85
|
+
f.foo = 'hello, "dude"!'
|
86
|
+
f.abc = 42
|
87
|
+
f.z = t
|
88
|
+
f.bar = 3.14
|
89
|
+
end
|
86
90
|
assert(n.nil?)
|
87
91
|
end
|
88
92
|
|
@@ -94,12 +98,13 @@ class TestIfAbsent < Minitest::Test
|
|
94
98
|
t = Time.now
|
95
99
|
f1.z = t
|
96
100
|
f1.bar = 3.14
|
97
|
-
n =
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
n =
|
102
|
+
Fbe.if_absent(fb:) do |f|
|
103
|
+
f.foo = "hello, \\\"dude\\\" \\' \\' ( \n\n ) (! '"
|
104
|
+
f.abc = 42
|
105
|
+
f.z = t + 1
|
106
|
+
f.bar = 3.15
|
107
|
+
end
|
103
108
|
assert(!n.nil?)
|
104
109
|
end
|
105
110
|
end
|
data/test/fbe/test_octo.rb
CHANGED
@@ -110,6 +110,12 @@ class TestOcto < Minitest::Test
|
|
110
110
|
assert_raises { o.repository('zerocracy/fbe') }
|
111
111
|
end
|
112
112
|
|
113
|
+
def test_workflow_run_usage
|
114
|
+
WebMock.disable_net_connect!
|
115
|
+
o = Fbe.octo(loog: Loog::NULL, global: {}, options: Judges::Options.new({ 'testing' => true }))
|
116
|
+
assert_equal(53_000, o.workflow_run_usage('zerocracy/fbe', 1)[:run_duration_ms])
|
117
|
+
end
|
118
|
+
|
113
119
|
def test_commit_pulls
|
114
120
|
skip # it's a "live" test, run it manually if you need it
|
115
121
|
WebMock.enable_net_connect!
|
@@ -0,0 +1,54 @@
|
|
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 'judges/options'
|
27
|
+
require 'loog'
|
28
|
+
require 'factbase'
|
29
|
+
require_relative '../test__helper'
|
30
|
+
require_relative '../../lib/fbe/pmp'
|
31
|
+
|
32
|
+
# Test.
|
33
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
34
|
+
# Copyright:: Copyright (c) 2024 Zerocracy
|
35
|
+
# License:: MIT
|
36
|
+
class TestPmp < Minitest::Test
|
37
|
+
def test_defaults
|
38
|
+
$fb = Factbase.new
|
39
|
+
$global = {}
|
40
|
+
$options = Judges::Options.new
|
41
|
+
f = Fbe.fb(loog: Loog::NULL).insert
|
42
|
+
f.what = 'pmp'
|
43
|
+
f.area = 'hr'
|
44
|
+
f.days_to_reward = 55
|
45
|
+
$loog = Loog::NULL
|
46
|
+
assert_equal(55, Fbe.pmp(loog: Loog::NULL).hr.days_to_reward)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_fail_on_wrong_area
|
50
|
+
$global = {}
|
51
|
+
$loog = Loog::NULL
|
52
|
+
assert_raises { Fbe.pmp(Factbase.new, loog: Loog::NULL).something }
|
53
|
+
end
|
54
|
+
end
|
@@ -37,22 +37,25 @@ class TestUnmaskRepos < Minitest::Test
|
|
37
37
|
opts = Judges::Options.new(
|
38
38
|
{
|
39
39
|
'testing' => true,
|
40
|
-
'repositories' => 'yegor256/tacit,zerocracy/*,-zerocracy/judges-action'
|
40
|
+
'repositories' => 'yegor256/tacit,zerocracy/*,-zerocracy/judges-action,zerocracy/datum'
|
41
41
|
}
|
42
42
|
)
|
43
|
-
|
43
|
+
list = Fbe.unmask_repos(options: opts, global: {}, loog: Loog::NULL)
|
44
|
+
assert(list.size.positive?)
|
45
|
+
refute_includes(list, 'zerocracy/datum')
|
44
46
|
end
|
45
47
|
|
46
48
|
def test_live_usage
|
47
49
|
skip('Run it only manually, since it touches GitHub API')
|
48
|
-
Judges::Options.new(
|
50
|
+
opts = Judges::Options.new(
|
49
51
|
{
|
50
|
-
'repositories' => 'zerocracy/*,-zerocracy/judges-action'
|
52
|
+
'repositories' => 'zerocracy/*,-zerocracy/judges-action,zerocracy/datum'
|
51
53
|
}
|
52
54
|
)
|
53
55
|
list = Fbe.unmask_repos(options: opts, global: {}, loog: Loog::NULL)
|
54
56
|
assert(list.size.positive?)
|
55
57
|
assert(list.include?('zerocracy/pages-action'))
|
56
58
|
assert(!list.include?('zerocracy/judges-action'))
|
59
|
+
refute_includes(list, 'zerocracy/datum')
|
57
60
|
end
|
58
61
|
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.37
|
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-
|
11
|
+
date: 2024-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backtrace
|
@@ -233,6 +233,7 @@ files:
|
|
233
233
|
- lib/fbe/middleware.rb
|
234
234
|
- lib/fbe/middleware/quota.rb
|
235
235
|
- lib/fbe/octo.rb
|
236
|
+
- lib/fbe/pmp.rb
|
236
237
|
- lib/fbe/sec.rb
|
237
238
|
- lib/fbe/unmask_repos.rb
|
238
239
|
- lib/fbe/who.rb
|
@@ -246,6 +247,7 @@ files:
|
|
246
247
|
- test/fbe/test_issue.rb
|
247
248
|
- test/fbe/test_iterate.rb
|
248
249
|
- test/fbe/test_octo.rb
|
250
|
+
- test/fbe/test_pmp.rb
|
249
251
|
- test/fbe/test_sec.rb
|
250
252
|
- test/fbe/test_unmask_repos.rb
|
251
253
|
- test/fbe/test_who.rb
|