judges 0.53.0 ā 0.53.2
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/.github/workflows/rake.yml +1 -1
- data/.github/workflows/typos.yml +1 -1
- data/Gemfile +0 -1
- data/Gemfile.lock +8 -10
- data/features/test.feature +2 -2
- data/features/update.feature +3 -4
- data/judges.gemspec +1 -1
- data/lib/judges/commands/update.rb +24 -15
- data/lib/judges/options.rb +9 -3
- data/lib/judges.rb +1 -1
- data/test/commands/test_update.rb +24 -0
- data/test/test_options.rb +6 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa86305c49cd5701b671c3e8a6705e07971e7000ea5c327ad6db9e0aa688f4c8
|
4
|
+
data.tar.gz: 9f9445c8c832b285b75d6b816127bb504e6bb3e548616c6cc999dda56dbe15c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b07a315a2bbd216ce359b6f81b1a04993929dc58feaa315413254ef0d72335a6fca76ef1716e597b39e81c8d5cc9f4a03f2d9de365b0e614f9420425afa9c81b
|
7
|
+
data.tar.gz: 9732e62b8e45b852b6eaa673a5924d61f7d6f67e0fae1f4bd76f0ecc996337236c3b52e2212a1b7efe2a31a701aae2f874f1be1bf15f814131dea9f90f4c3761
|
data/.github/workflows/rake.yml
CHANGED
data/.github/workflows/typos.yml
CHANGED
data/Gemfile
CHANGED
@@ -12,7 +12,6 @@ gem 'diff-lcs', '1.6.2', require: false # GPL
|
|
12
12
|
gem 'minitest', '~>5.25', require: false
|
13
13
|
gem 'minitest-reporters', '~>1.7', require: false
|
14
14
|
gem 'minitest-retry', '~>0.2', require: false
|
15
|
-
gem 'net-ping', '~>2.0', require: false
|
16
15
|
gem 'online', '~>0.0', require: false
|
17
16
|
gem 'os', '~>1.1', require: false
|
18
17
|
gem 'qbash', '~>0.4', require: false
|
data/Gemfile.lock
CHANGED
@@ -46,7 +46,7 @@ GEM
|
|
46
46
|
crack (1.0.0)
|
47
47
|
bigdecimal
|
48
48
|
rexml
|
49
|
-
cucumber (10.
|
49
|
+
cucumber (10.1.0)
|
50
50
|
base64 (~> 0.2)
|
51
51
|
builder (~> 3.2)
|
52
52
|
cucumber-ci-environment (> 9, < 11)
|
@@ -59,7 +59,7 @@ GEM
|
|
59
59
|
multi_test (~> 1.1)
|
60
60
|
sys-uname (~> 1.3)
|
61
61
|
cucumber-ci-environment (10.0.1)
|
62
|
-
cucumber-core (15.2.
|
62
|
+
cucumber-core (15.2.1)
|
63
63
|
cucumber-gherkin (> 27, < 33)
|
64
64
|
cucumber-messages (> 26, < 30)
|
65
65
|
cucumber-tag-expressions (> 5, < 7)
|
@@ -78,18 +78,18 @@ GEM
|
|
78
78
|
loog (~> 0.6)
|
79
79
|
tago (~> 0.1)
|
80
80
|
ellipsized (0.3.0)
|
81
|
-
ethon (0.
|
81
|
+
ethon (0.17.0)
|
82
82
|
ffi (>= 1.15.0)
|
83
|
-
factbase (0.15.
|
83
|
+
factbase (0.15.6)
|
84
84
|
backtrace (~> 0.4)
|
85
|
-
decoor (~> 0.
|
85
|
+
decoor (~> 0.1)
|
86
86
|
ellipsized (~> 0.3)
|
87
87
|
json (~> 2.7)
|
88
88
|
logger (~> 1.0)
|
89
89
|
loog (~> 0.6)
|
90
90
|
nokogiri (~> 1.10)
|
91
|
-
others (~> 0.
|
92
|
-
tago (~> 0.
|
91
|
+
others (~> 0.1)
|
92
|
+
tago (~> 0.1)
|
93
93
|
yaml (~> 0.3)
|
94
94
|
faraday (2.13.4)
|
95
95
|
faraday-net_http (>= 2.0, < 3.5)
|
@@ -136,7 +136,6 @@ GEM
|
|
136
136
|
multipart-post (2.4.1)
|
137
137
|
net-http (0.6.0)
|
138
138
|
uri
|
139
|
-
net-ping (2.0.8)
|
140
139
|
nokogiri (1.18.9-aarch64-linux-gnu)
|
141
140
|
racc (~> 1.4)
|
142
141
|
nokogiri (1.18.9-aarch64-linux-musl)
|
@@ -179,7 +178,7 @@ GEM
|
|
179
178
|
regexp_parser (2.11.2)
|
180
179
|
retries (0.0.5)
|
181
180
|
rexml (3.4.1)
|
182
|
-
rubocop (1.
|
181
|
+
rubocop (1.80.0)
|
183
182
|
json (~> 2.3)
|
184
183
|
language_server-protocol (~> 3.17.0.2)
|
185
184
|
lint_roller (~> 1.1.0)
|
@@ -255,7 +254,6 @@ DEPENDENCIES
|
|
255
254
|
minitest (~> 5.25)
|
256
255
|
minitest-reporters (~> 1.7)
|
257
256
|
minitest-retry (~> 0.2)
|
258
|
-
net-ping (~> 2.0)
|
259
257
|
online (~> 0.0)
|
260
258
|
os (~> 1.1)
|
261
259
|
qbash (~> 0.4)
|
data/features/test.feature
CHANGED
@@ -16,9 +16,9 @@ Feature: Test
|
|
16
16
|
And Exit code is zero
|
17
17
|
|
18
18
|
Scenario: Factbase version can be set
|
19
|
-
When I run bin/judges with "--factbase 0.15.
|
19
|
+
When I run bin/judges with "--factbase 0.15.6 --verbose test --judge guess ./fixtures"
|
20
20
|
Then Exit code is zero
|
21
|
-
And Stdout contains "Factbase version to be used: '0.15.
|
21
|
+
And Stdout contains "Factbase version to be used: '0.15.6'"
|
22
22
|
|
23
23
|
Scenario: Simple test of no judges
|
24
24
|
Given I run bin/judges with "test --judge absent_for_sure ./fixtures"
|
data/features/update.feature
CHANGED
@@ -55,16 +55,15 @@ Feature: Update
|
|
55
55
|
"""
|
56
56
|
n = $fb.insert
|
57
57
|
n.type = 'first'
|
58
|
-
sleep 1
|
58
|
+
sleep 1.9
|
59
59
|
"""
|
60
60
|
Then I have a "second/second.rb" file with content:
|
61
61
|
"""
|
62
62
|
n = $fb.insert
|
63
63
|
n.type = 'second'
|
64
64
|
"""
|
65
|
-
Then I run bin/judges with "--verbose update --quiet --lifetime 1 --max-cycles 5 . simple.fb"
|
66
|
-
Then Stdout contains "
|
67
|
-
Then Stdout contains "Update completed in 1 cycle(s), did 1i/0d/1a"
|
65
|
+
Then I run bin/judges with "--verbose update --quiet --lifetime 2 --timeout 1 --max-cycles 5 . simple.fb"
|
66
|
+
Then Stdout contains "Update completed in 2 cycle(s), did 1i/0d/1a"
|
68
67
|
And Exit code is zero
|
69
68
|
|
70
69
|
Scenario: Use options from a file
|
data/judges.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
|
10
10
|
s.required_ruby_version = '>=3.2'
|
11
11
|
s.name = 'judges'
|
12
|
-
s.version = '0.53.
|
12
|
+
s.version = '0.53.2'
|
13
13
|
s.license = 'MIT'
|
14
14
|
s.summary = 'Command-Line Tool for a Factbase'
|
15
15
|
s.description =
|
@@ -42,11 +42,13 @@ class Judges::Update
|
|
42
42
|
raise 'Exactly two arguments required' unless args.size == 2
|
43
43
|
dir = args[0]
|
44
44
|
raise "The directory is absent: #{dir.to_rel}" unless File.exist?(dir)
|
45
|
-
start = Time.now
|
46
45
|
impex = Judges::Impex.new(@loog, args[1])
|
47
46
|
fb = impex.import(strict: false)
|
48
47
|
fb = Factbase::Logged.new(fb, @loog) if opts['log']
|
49
|
-
options = Judges::Options.new(timeout: opts['timeout'], lifetime: opts['lifetime'])
|
48
|
+
options = Judges::Options.new(timeout: opts['timeout']&.to_i, lifetime: opts['lifetime']&.to_i)
|
49
|
+
if options.lifetime && options.timeout && options.lifetime < options.timeout * 1.1
|
50
|
+
raise "The --timeout=#{options.timeout} must be at least 10 percent smaller than --lifetime=#{options.lifetime}"
|
51
|
+
end
|
50
52
|
options += Judges::Options.new(opts['option'])
|
51
53
|
if opts['options-file']
|
52
54
|
options += Judges::Options.new(
|
@@ -62,8 +64,19 @@ class Judges::Update
|
|
62
64
|
else
|
63
65
|
@loog.debug("The following options provided:\n\t#{options.to_s.gsub("\n", "\n\t")}")
|
64
66
|
end
|
65
|
-
judges = Judges::Judges.new(
|
66
|
-
|
67
|
+
judges = Judges::Judges.new(
|
68
|
+
dir, opts['lib'], @loog,
|
69
|
+
start: @start, shuffle: opts['shuffle'], boost: opts['boost'],
|
70
|
+
demote: opts['demote']
|
71
|
+
)
|
72
|
+
Timeout.timeout(opts['lifetime']) do
|
73
|
+
loop_them(impex, judges, fb, opts, options)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def loop_them(impex, judges, fb, opts, options)
|
67
80
|
c = 0
|
68
81
|
churn = Factbase::Churn.new
|
69
82
|
errors = []
|
@@ -80,14 +93,14 @@ class Judges::Update
|
|
80
93
|
loop do
|
81
94
|
c += 1
|
82
95
|
if c > 1
|
83
|
-
if opts['lifetime'] && Time.now - @start > opts['lifetime']
|
96
|
+
if opts['lifetime'] && Time.now - @start > opts['lifetime'] * 0.51
|
84
97
|
@loog.info("Not starting cycle ##{c}, no time left")
|
85
98
|
c -= 1
|
86
99
|
break
|
87
100
|
end
|
88
101
|
@loog.info("\nStarting cycle ##{c}#{" (out of #{opts['max-cycles']})" if opts['max-cycles']}...")
|
89
102
|
end
|
90
|
-
delta = cycle(opts, judges, fb, options,
|
103
|
+
delta = cycle(opts, judges, fb, options, errors)
|
91
104
|
churn += delta
|
92
105
|
impex.export(fb)
|
93
106
|
if delta.zero?
|
@@ -107,26 +120,23 @@ class Judges::Update
|
|
107
120
|
throw :"š Update completed in #{c} cycle(s), did #{churn}"
|
108
121
|
end
|
109
122
|
return unless %w[add append].include?(opts['summary'])
|
110
|
-
summarize(fb, churn, errors,
|
123
|
+
summarize(fb, churn, errors, c)
|
111
124
|
impex.export(fb)
|
112
125
|
end
|
113
126
|
|
114
|
-
private
|
115
|
-
|
116
127
|
# Update the summary.
|
117
128
|
# @param [Factbase] fb The factbase
|
118
129
|
# @param [Churn] churn The churn
|
119
130
|
# @param [Array<String>] errors List of errors
|
120
|
-
# @param [Time] start When we started
|
121
131
|
# @param [Integer] cycles How many cycles
|
122
|
-
def summarize(fb, churn, errors,
|
132
|
+
def summarize(fb, churn, errors, cycles)
|
123
133
|
before = fb.query('(eq what "judges-summary")').each.to_a
|
124
134
|
if before.empty?
|
125
135
|
s = fb.insert
|
126
136
|
s.what = 'judges-summary'
|
127
137
|
s.when = Time.now
|
128
138
|
s.version = Judges::VERSION
|
129
|
-
s.seconds = Time.now - start
|
139
|
+
s.seconds = Time.now - @start
|
130
140
|
s.cycles = cycles
|
131
141
|
s.inserted = churn.inserted.size
|
132
142
|
s.deleted = churn.deleted.size
|
@@ -153,10 +163,9 @@ class Judges::Update
|
|
153
163
|
# @param [Judges::Judges] judges The judges
|
154
164
|
# @param [Factbase] fb The factbase
|
155
165
|
# @param [Judges::Options] options The options
|
156
|
-
# @param [Float] start When we started
|
157
166
|
# @param [Array<String>] errors List of errors
|
158
167
|
# @return [Factbase::Churn] How many modifications have been made
|
159
|
-
def cycle(opts, judges, fb, options,
|
168
|
+
def cycle(opts, judges, fb, options, errors)
|
160
169
|
churn = Factbase::Churn.new
|
161
170
|
global = {}
|
162
171
|
used = 0
|
@@ -168,7 +177,7 @@ class Judges::Update
|
|
168
177
|
next
|
169
178
|
end
|
170
179
|
next unless include?(opts, judge.name)
|
171
|
-
@loog.info("\nš Running #{judge.name} (##{i}) at #{judge.dir.to_rel} (#{start.ago} already)...")
|
180
|
+
@loog.info("\nš Running #{judge.name} (##{i}) at #{judge.dir.to_rel} (#{@start.ago} already)...")
|
172
181
|
used += 1
|
173
182
|
elapsed(@loog, level: Logger::INFO) do
|
174
183
|
c = one_judge(opts, fb, judge, global, options, errors)
|
data/lib/judges/options.rb
CHANGED
@@ -86,9 +86,14 @@ class Judges::Options
|
|
86
86
|
# # token ā "supe****oken"
|
87
87
|
def to_s
|
88
88
|
to_h.map do |k, v|
|
89
|
-
v = v.
|
90
|
-
v =
|
91
|
-
|
89
|
+
v = "#{v[0..3]}#{'*' * (v.length - 8)}#{v[-4..]}" if v.is_a?(String) && v.length > 8
|
90
|
+
v =
|
91
|
+
if v.is_a?(String)
|
92
|
+
"\"#{v}\""
|
93
|
+
else
|
94
|
+
"#{v} (#{v.class.name})"
|
95
|
+
end
|
96
|
+
"#{k} ā #{v}"
|
92
97
|
end.sort.join("\n")
|
93
98
|
end
|
94
99
|
|
@@ -122,6 +127,7 @@ class Judges::Options
|
|
122
127
|
end
|
123
128
|
pp
|
124
129
|
.reject { |k, _| k.nil? }
|
130
|
+
.compact
|
125
131
|
.reject { |k, _| k.is_a?(String) && k.empty? }
|
126
132
|
.to_h
|
127
133
|
.transform_values { |v| v.nil? ? 'true' : v }
|
data/lib/judges.rb
CHANGED
@@ -51,6 +51,18 @@ class TestUpdate < Minitest::Test
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
def test_accepts_changes_from_slow_judge
|
55
|
+
Dir.mktmpdir do |d|
|
56
|
+
save_it(File.join(d, 'foo/foo.rb'), '$fb.insert.foo = 1; sleep 10')
|
57
|
+
file = File.join(d, 'base.fb')
|
58
|
+
Judges::Update.new(Loog::NULL).run({ 'timeout' => 0.1, 'quiet' => true }, [d, file])
|
59
|
+
fb = Factbase.new
|
60
|
+
fb.import(File.binread(file))
|
61
|
+
xml = Nokogiri::XML.parse(Factbase::ToXML.new(fb).xml)
|
62
|
+
refute_empty(xml.xpath('/fb/f[foo]'), xml)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
54
66
|
def test_extend_existing_factbase
|
55
67
|
Dir.mktmpdir do |d|
|
56
68
|
file = File.join(d, 'base.fb')
|
@@ -89,6 +101,18 @@ class TestUpdate < Minitest::Test
|
|
89
101
|
end
|
90
102
|
end
|
91
103
|
|
104
|
+
def test_terminates_on_lifetime
|
105
|
+
Dir.mktmpdir do |d|
|
106
|
+
save_it(File.join(d, 'foo/foo.rb'), 'sleep 999')
|
107
|
+
file = File.join(d, 'base.fb')
|
108
|
+
log = Loog::Buffer.new
|
109
|
+
assert_raises(StandardError) do
|
110
|
+
Judges::Update.new(Loog::Tee.new(log, Loog::NULL)).run({ 'lifetime' => 0.1 }, [d, file])
|
111
|
+
end
|
112
|
+
assert_includes(log.to_s, 'execution expired')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
92
116
|
def test_passes_timeout_and_lifetime_through
|
93
117
|
%w[lifetime timeout].each do |o|
|
94
118
|
Dir.mktmpdir do |d|
|
data/test/test_options.rb
CHANGED
@@ -60,10 +60,15 @@ class TestOptions < Minitest::Test
|
|
60
60
|
assert_nil(opts.xxx)
|
61
61
|
end
|
62
62
|
|
63
|
+
def test_with_nil_values
|
64
|
+
opts = Judges::Options.new('foo' => nil)
|
65
|
+
assert_nil(opts.foo)
|
66
|
+
end
|
67
|
+
|
63
68
|
def test_converts_to_string
|
64
69
|
opts = Judges::Options.new('foo' => 44, 'bar' => 'long-string-maybe-secret')
|
65
70
|
s = opts.to_s
|
66
|
-
assert_includes(s, 'FOO ā
|
71
|
+
assert_includes(s, 'FOO ā 44 (Integer)', s)
|
67
72
|
assert_includes(s, '"long****************cret"', s)
|
68
73
|
end
|
69
74
|
|