judges 0.45.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cedd1c3c1a22769b72837c4a238cd3f7a3d5be8d24c7e09ad70fc3ed2f5ce884
4
- data.tar.gz: 56a03cbd46bb9679b9b2736cc1855728c26e78447588ab77226507b8fd0657ee
3
+ metadata.gz: 5480ce66a6fbce4d6748a47f42240c77438ef09eed639f6744c762f94ce57ebe
4
+ data.tar.gz: a445e36911b5dcc457a188fb1ff7a50251f6e19b60313c1185b4af70a773acdc
5
5
  SHA512:
6
- metadata.gz: 0f4a3af460657642c16a2c47f3343795fe965f059b819b76e3cf3fa420d6178e1b6c9a26a396e9913590fdeca2b3c6fb1a444158ef60e1b5240cf4a463442f36
7
- data.tar.gz: 5158177fbc1dbc280aa1b69df6d3df805b676a7094e37686dc7cc22cf1a7ccfd375d300c78987ec31ab7997602828ed10cd8ca36c8d65647525a2ba320ab1961
6
+ metadata.gz: d4a52cb96f912acb0a97d842f132c2daf855771406253e9ff0bd5b2fa2ba17cbdb15b4e12919b8e41092b7ebc07c954c7fafbaaf4029eb57387075d9cd46e679
7
+ data.tar.gz: 59d5df2eea5c531989709a7e60c183a4f8f10723e6e0df320ca58ce2a6a2f167c236713a110814eab49d91996e659e2e3ac5fb255a95a6a8516ebec9f874351c
@@ -16,4 +16,4 @@ jobs:
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
18
  - uses: actions/checkout@v4
19
- - uses: yegor256/copyrights-action@0.0.10
19
+ - uses: yegor256/copyrights-action@0.0.12
@@ -16,4 +16,4 @@ jobs:
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
18
  - uses: actions/checkout@v4
19
- - uses: crate-ci/typos@v1.32.0
19
+ - uses: crate-ci/typos@v1.33.1
data/Gemfile.lock CHANGED
@@ -2,21 +2,21 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  judges (0.0.0)
5
- backtrace (~> 0)
6
- baza.rb (~> 0)
5
+ backtrace (~> 0.4)
6
+ baza.rb (~> 0.5)
7
7
  concurrent-ruby (~> 1.2)
8
- elapsed (~> 0)
9
- factbase (~> 0.9)
8
+ elapsed (~> 0.0)
9
+ factbase (~> 0.11)
10
10
  gli (~> 2.21)
11
- iri (~> 0)
12
- loog (~> 0)
11
+ iri (~> 0.11)
12
+ loog (~> 0.6)
13
13
  moments (~> 0.3)
14
14
  nokogiri (~> 1.10)
15
- others (~> 0)
16
- retries (~> 0)
17
- tago (~> 0)
18
- timeout (~> 0)
19
- total (~> 0)
15
+ others (~> 0.0)
16
+ retries (~> 0.0)
17
+ tago (~> 0.1)
18
+ timeout (~> 0.4)
19
+ total (~> 0.4)
20
20
  typhoeus (~> 1.3)
21
21
 
22
22
  GEM
@@ -26,9 +26,9 @@ GEM
26
26
  public_suffix (>= 2.0.2, < 7.0)
27
27
  ansi (1.5.0)
28
28
  ast (2.4.3)
29
- backtrace (0.4.0)
30
- base64 (0.2.0)
31
- baza.rb (0.5.0)
29
+ backtrace (0.4.1)
30
+ base64 (0.3.0)
31
+ baza.rb (0.5.1)
32
32
  backtrace (> 0)
33
33
  elapsed (> 0)
34
34
  faraday (> 0)
@@ -40,7 +40,7 @@ GEM
40
40
  retries (~> 0)
41
41
  tago (~> 0)
42
42
  typhoeus (~> 1.3)
43
- bigdecimal (3.1.9)
43
+ bigdecimal (3.2.2)
44
44
  builder (3.3.0)
45
45
  concurrent-ruby (1.3.5)
46
46
  crack (1.0.0)
@@ -81,7 +81,7 @@ GEM
81
81
  erb (5.0.1)
82
82
  ethon (0.16.0)
83
83
  ffi (>= 1.15.0)
84
- factbase (0.10.2)
84
+ factbase (0.11.0)
85
85
  backtrace (~> 0.4)
86
86
  decoor (~> 0.0)
87
87
  json (~> 2.7)
@@ -104,16 +104,17 @@ GEM
104
104
  faraday-retry (2.3.1)
105
105
  faraday (~> 2.0)
106
106
  ffi (1.17.2-aarch64-linux-gnu)
107
+ ffi (1.17.2-aarch64-linux-musl)
107
108
  ffi (1.17.2-arm-linux-gnu)
109
+ ffi (1.17.2-arm-linux-musl)
108
110
  ffi (1.17.2-arm64-darwin)
109
- ffi (1.17.2-x64-mingw-ucrt)
110
- ffi (1.17.2-x86-linux-gnu)
111
111
  ffi (1.17.2-x86_64-darwin)
112
112
  ffi (1.17.2-x86_64-linux-gnu)
113
+ ffi (1.17.2-x86_64-linux-musl)
113
114
  gli (2.22.2)
114
115
  ostruct
115
116
  hashdiff (1.2.0)
116
- iri (0.10.0)
117
+ iri (0.11.2)
117
118
  json (2.12.2)
118
119
  language_server-protocol (3.17.0.5)
119
120
  lint_roller (1.1.0)
@@ -121,7 +122,6 @@ GEM
121
122
  loog (0.6.1)
122
123
  logger (~> 1.0)
123
124
  mini_mime (1.1.5)
124
- mini_portile2 (2.8.9)
125
125
  minitest (5.25.5)
126
126
  minitest-reporters (1.7.1)
127
127
  ansi
@@ -136,21 +136,22 @@ GEM
136
136
  net-http (0.6.0)
137
137
  uri
138
138
  net-ping (2.0.8)
139
- nokogiri (1.18.8)
140
- mini_portile2 (~> 2.8.2)
141
- racc (~> 1.4)
142
139
  nokogiri (1.18.8-aarch64-linux-gnu)
143
140
  racc (~> 1.4)
141
+ nokogiri (1.18.8-aarch64-linux-musl)
142
+ racc (~> 1.4)
144
143
  nokogiri (1.18.8-arm-linux-gnu)
145
144
  racc (~> 1.4)
146
- nokogiri (1.18.8-arm64-darwin)
145
+ nokogiri (1.18.8-arm-linux-musl)
147
146
  racc (~> 1.4)
148
- nokogiri (1.18.8-x64-mingw-ucrt)
147
+ nokogiri (1.18.8-arm64-darwin)
149
148
  racc (~> 1.4)
150
149
  nokogiri (1.18.8-x86_64-darwin)
151
150
  racc (~> 1.4)
152
151
  nokogiri (1.18.8-x86_64-linux-gnu)
153
152
  racc (~> 1.4)
153
+ nokogiri (1.18.8-x86_64-linux-musl)
154
+ racc (~> 1.4)
154
155
  os (1.1.4)
155
156
  ostruct (0.6.1)
156
157
  others (0.0.3)
@@ -170,7 +171,7 @@ GEM
170
171
  tago (> 0)
171
172
  racc (1.8.1)
172
173
  rainbow (3.1.1)
173
- rake (13.2.1)
174
+ rake (13.3.0)
174
175
  random-port (0.7.5)
175
176
  tago (> 0)
176
177
  rdoc (6.14.0)
@@ -179,7 +180,7 @@ GEM
179
180
  regexp_parser (2.10.0)
180
181
  retries (0.0.5)
181
182
  rexml (3.4.1)
182
- rubocop (1.75.7)
183
+ rubocop (1.76.0)
183
184
  json (~> 2.3)
184
185
  language_server-protocol (~> 3.17.0.2)
185
186
  lint_roller (~> 1.1.0)
@@ -187,13 +188,13 @@ GEM
187
188
  parser (>= 3.3.0.2)
188
189
  rainbow (>= 2.2.2, < 4.0)
189
190
  regexp_parser (>= 2.9.3, < 3.0)
190
- rubocop-ast (>= 1.44.0, < 2.0)
191
+ rubocop-ast (>= 1.45.0, < 2.0)
191
192
  ruby-progressbar (~> 1.7)
192
193
  unicode-display_width (>= 2.4.0, < 4.0)
193
- rubocop-ast (1.44.1)
194
+ rubocop-ast (1.45.0)
194
195
  parser (>= 3.3.7.2)
195
196
  prism (~> 1.4)
196
- rubocop-minitest (0.38.0)
197
+ rubocop-minitest (0.38.1)
197
198
  lint_roller (~> 1.1)
198
199
  rubocop (>= 1.75.0, < 2.0)
199
200
  rubocop-ast (>= 1.38.0, < 2.0)
@@ -241,14 +242,14 @@ GEM
241
242
  yard (0.9.37)
242
243
 
243
244
  PLATFORMS
244
- aarch64-linux
245
- arm-linux
245
+ aarch64-linux-gnu
246
+ aarch64-linux-musl
247
+ arm-linux-gnu
248
+ arm-linux-musl
246
249
  arm64-darwin
247
- arm64-darwin-23
248
- x64-mingw-ucrt
249
- x86-linux
250
250
  x86_64-darwin
251
- x86_64-linux
251
+ x86_64-linux-gnu
252
+ x86_64-linux-musl
252
253
 
253
254
  DEPENDENCIES
254
255
  base64 (> 0)
@@ -275,4 +276,4 @@ DEPENDENCIES
275
276
  yard (~> 0.9)
276
277
 
277
278
  BUNDLED WITH
278
- 2.5.16
279
+ 2.6.8
data/bin/judges CHANGED
@@ -82,6 +82,8 @@ class JudgesGLI extend GLI::App
82
82
  c.flag([:shuffle], default_value: '')
83
83
  c.desc 'Prioritize a judge to run before all others'
84
84
  c.flag([:boost], multiple: true)
85
+ c.desc 'Demote a judge to run after all others'
86
+ c.flag([:demote], multiple: true)
85
87
  c.desc 'Maximum time in seconds for the entire update cycle'
86
88
  c.flag([:lifetime], default_value: 300, type: Integer)
87
89
  c.desc 'Maximum time in seconds for each judge (forcefully terminates if exceeded)'
@@ -93,7 +95,7 @@ class JudgesGLI extend GLI::App
93
95
  c.desc 'Stop processing immediately after the first error'
94
96
  c.switch([:'fail-fast'], default_value: false)
95
97
  c.desc 'Add a summary fact to the factbase'
96
- c.switch([:summary], default_value: false)
98
+ c.flag([:summary], must_match: %w[off add append], default_value: 'off')
97
99
  c.desc 'Use default logging facility'
98
100
  c.switch([:log], default_value: true)
99
101
  c.desc 'Expect at least one judge to be used (fail if none are used)'
@@ -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.10.2 --verbose test --judge guess ./fixtures"
19
+ When I run bin/judges with "--factbase 0.11.0 --verbose test --judge guess ./fixtures"
20
20
  Then Exit code is zero
21
- And Stdout contains "Factbase version to be used: '0.10.2'"
21
+ And Stdout contains "Factbase version to be used: '0.11.0'"
22
22
 
23
23
  Scenario: Simple test of no judges
24
24
  Given I run bin/judges with "test --judge absent_for_sure ./fixtures"
@@ -20,16 +20,35 @@ Feature: Update
20
20
 
21
21
  Scenario: Generate a summary fact, with errors
22
22
  Given I make a temp directory
23
- Then I have a "buggy/buggy.rb" file with content:
24
- """
25
- this is a bug
26
- """
27
- Then I run bin/judges with "update --quiet --summary --max-cycles 1 . simple.fb"
23
+ Then I have a "buggy/buggy.rb" file with content: "this is an intentional bug"
24
+ Then I run bin/judges with "update --quiet --summary=append --max-cycles 1 . simple.fb"
28
25
  Then Exit code is zero
29
26
  Then I run bin/judges with "inspect simple.fb"
30
27
  Then Stdout contains "Facts: 1"
31
28
  And Exit code is zero
32
29
 
30
+ Scenario: Append to existing summary fact, with errors
31
+ Given I make a temp directory
32
+ Then I have a "buggy/buggy.rb" file with content: "this is an intentional bug"
33
+ Then I run bin/judges with "update --quiet --summary=append --max-cycles 1 . simple.fb"
34
+ Then Exit code is zero
35
+ Then Stdout contains "Summary fact not found"
36
+ Then I run bin/judges with "update --quiet --summary=append --max-cycles 1 . simple.fb"
37
+ Then I run bin/judges with "inspect simple.fb"
38
+ Then Stdout contains "Summary fact found"
39
+ Then Stdout contains "errors:"
40
+ And Exit code is zero
41
+
42
+ Scenario: Delete a previous summary fact and create new one
43
+ Given I make a temp directory
44
+ Then I have a "buggy/buggy.rb" file with content: "this is an intentional bug"
45
+ Then I run bin/judges with "update --quiet --summary=add --max-cycles 1 . simple.fb"
46
+ Then Exit code is zero
47
+ Then Stdout contains "Summary fact added"
48
+ Then I run bin/judges with "update --quiet --summary=add --max-cycles 1 . simple.fb"
49
+ Then Exit code is zero
50
+ And Stdout contains "Summary fact deleted"
51
+
33
52
  Scenario: Skips the judge on lifetime running out
34
53
  Given I make a temp directory
35
54
  Then I have a "simple/simple.rb" file with content:
@@ -123,3 +142,71 @@ Feature: Update
123
142
  And Exit code is zero
124
143
  Then I run bin/judges with "inspect simple.fb"
125
144
  Then Stdout contains "Facts: 1"
145
+
146
+ Scenario: Simple demote of a single judge
147
+ Given I make a temp directory
148
+ Then I have a "alpha/alpha.rb" file with content:
149
+ """
150
+ $fb.insert.name = 'alpha'
151
+ """
152
+ Then I have a "beta/beta.rb" file with content:
153
+ """
154
+ $fb.insert.name = 'beta'
155
+ """
156
+ Then I have a "gamma/gamma.rb" file with content:
157
+ """
158
+ $fb.insert.name = 'gamma'
159
+ """
160
+ Then I run bin/judges with "--verbose update --quiet --max-cycles 1 --demote beta . demote.fb"
161
+ Then Stdout contains "Running alpha"
162
+ Then Stdout contains "Running gamma"
163
+ Then Stdout contains "Running beta"
164
+ Then Stdout contains "3 judge(s) processed"
165
+ And Exit code is zero
166
+
167
+ Scenario: Demote multiple judges
168
+ Given I make a temp directory
169
+ Then I have a "first/first.rb" file with content:
170
+ """
171
+ $fb.insert.order = 'first'
172
+ """
173
+ Then I have a "second/second.rb" file with content:
174
+ """
175
+ $fb.insert.order = 'second'
176
+ """
177
+ Then I have a "third/third.rb" file with content:
178
+ """
179
+ $fb.insert.order = 'third'
180
+ """
181
+ Then I have a "fourth/fourth.rb" file with content:
182
+ """
183
+ $fb.insert.order = 'fourth'
184
+ """
185
+ Then I run bin/judges with "--verbose update --quiet --max-cycles 1 --demote second --demote fourth . multi.fb"
186
+ Then Stdout contains "Running first"
187
+ Then Stdout contains "Running third"
188
+ Then Stdout contains "Running second"
189
+ Then Stdout contains "Running fourth"
190
+ Then Stdout contains "4 judge(s) processed"
191
+ And Exit code is zero
192
+
193
+ Scenario: Combine boost and demote
194
+ Given I make a temp directory
195
+ Then I have a "priority/priority.rb" file with content:
196
+ """
197
+ $fb.insert.type = 'priority'
198
+ """
199
+ Then I have a "normal/normal.rb" file with content:
200
+ """
201
+ $fb.insert.type = 'normal'
202
+ """
203
+ Then I have a "delayed/delayed.rb" file with content:
204
+ """
205
+ $fb.insert.type = 'delayed'
206
+ """
207
+ Then I run bin/judges with "--verbose update --quiet --max-cycles 1 --boost priority --demote delayed . combined.fb"
208
+ Then Stdout contains "Running priority"
209
+ Then Stdout contains "Running normal"
210
+ Then Stdout contains "Running delayed"
211
+ Then Stdout contains "3 judge(s) processed"
212
+ And Exit code is zero
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.45.0'
12
+ s.version = '0.46.0'
13
13
  s.license = 'MIT'
14
14
  s.summary = 'Command-Line Tool for a Factbase'
15
15
  s.description =
@@ -25,21 +25,21 @@ Gem::Specification.new do |s|
25
25
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
26
26
  s.rdoc_options = ['--charset=UTF-8']
27
27
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
28
- s.add_dependency 'backtrace', '~>0'
29
- s.add_dependency 'baza.rb', '~>0'
28
+ s.add_dependency 'backtrace', '~>0.4'
29
+ s.add_dependency 'baza.rb', '~>0.5'
30
30
  s.add_dependency 'concurrent-ruby', '~>1.2'
31
- s.add_dependency 'elapsed', '~>0'
32
- s.add_dependency 'factbase', '~>0.9'
31
+ s.add_dependency 'elapsed', '~>0.0'
32
+ s.add_dependency 'factbase', '~>0.11'
33
33
  s.add_dependency 'gli', '~>2.21'
34
- s.add_dependency 'iri', '~>0'
35
- s.add_dependency 'loog', '~>0'
34
+ s.add_dependency 'iri', '~>0.11'
35
+ s.add_dependency 'loog', '~>0.6'
36
36
  s.add_dependency 'moments', '~>0.3'
37
37
  s.add_dependency 'nokogiri', '~>1.10'
38
- s.add_dependency 'others', '~>0'
39
- s.add_dependency 'retries', '~>0'
40
- s.add_dependency 'tago', '~>0'
41
- s.add_dependency 'timeout', '~>0'
42
- s.add_dependency 'total', '~>0'
38
+ s.add_dependency 'others', '~>0.0'
39
+ s.add_dependency 'retries', '~>0.0'
40
+ s.add_dependency 'tago', '~>0.1'
41
+ s.add_dependency 'timeout', '~>0.4'
42
+ s.add_dependency 'total', '~>0.4'
43
43
  s.add_dependency 'typhoeus', '~>1.3'
44
44
  s.metadata['rubygems_mfa_required'] = 'true'
45
45
  end
@@ -3,6 +3,7 @@
3
3
  # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
+ require 'factbase/fact_as_yaml'
6
7
  require_relative '../../judges'
7
8
  require_relative '../../judges/impex'
8
9
 
@@ -29,5 +30,11 @@ class Judges::Inspect
29
30
  raise 'At least one argument required' if args.empty?
30
31
  fb = Judges::Impex.new(@loog, args[0]).import
31
32
  @loog.info("Facts: #{fb.size}")
33
+ sum = fb.query('(eq what "judges-summary")').each.to_a
34
+ if sum.empty?
35
+ @loog.info('Summary fact not found')
36
+ else
37
+ @loog.info("Summary fact found:\n\t#{Factbase::FactAsYaml.new(sum.first).gsub("\n", "\n\t")}")
38
+ end
32
39
  end
33
40
  end
@@ -8,6 +8,7 @@ require 'elapsed'
8
8
  require 'factbase'
9
9
  require 'factbase/churn'
10
10
  require 'factbase/logged'
11
+ require 'factbase/fact_as_yaml'
11
12
  require 'logger'
12
13
  require 'tago'
13
14
  require 'timeout'
@@ -60,15 +61,25 @@ class Judges::Update
60
61
  else
61
62
  @loog.debug("The following options provided:\n\t#{options.to_s.gsub("\n", "\n\t")}")
62
63
  end
63
- judges = Judges::Judges.new(dir, opts['lib'], @loog, start:, shuffle: opts['shuffle'], boost: opts['boost'])
64
+ judges = Judges::Judges.new(dir, opts['lib'], @loog, start:, shuffle: opts['shuffle'], boost: opts['boost'],
65
+ demote: opts['demote'])
64
66
  c = 0
65
67
  churn = Factbase::Churn.new
66
68
  errors = []
69
+ sum = fb.query('(eq what "judges-summary")').each.to_a
70
+ if sum.empty?
71
+ @loog.info('Summary fact not found') unless opts['summary'] == 'off'
72
+ else
73
+ @loog.info("Summary fact found:\n\t#{Factbase::FactAsYaml.new(sum.first).to_s.gsub("\n", "\n\t")}")
74
+ end
75
+ if !sum.empty? && opts['summary'] == 'add' && fb.query('(eq what "judges-summary")').delete!
76
+ @loog.info('Summary fact deleted')
77
+ end
67
78
  elapsed(@loog, level: Logger::INFO) do
68
79
  loop do
69
80
  c += 1
70
81
  if c > 1
71
- @loog.info("\nStarting cycle ##{c}#{opts['max-cycles'] ? " (out of #{opts['max-cycles']})" : ''}...")
82
+ @loog.info("\nStarting cycle ##{c}#{" (out of #{opts['max-cycles']})" if opts['max-cycles']}...")
72
83
  end
73
84
  delta = cycle(opts, judges, fb, options, start, errors)
74
85
  churn += delta
@@ -89,7 +100,7 @@ class Judges::Update
89
100
  end
90
101
  throw :"👍 Update completed in #{c} cycle(s), did #{churn}"
91
102
  end
92
- return unless opts['summary']
103
+ return unless %w[add append].include?(opts['summary'])
93
104
  summarize(fb, churn, errors, start, c)
94
105
  impex.export(fb)
95
106
  end
@@ -105,7 +116,6 @@ class Judges::Update
105
116
  def summarize(fb, churn, errors, start, cycles)
106
117
  before = fb.query('(eq what "judges-summary")').each.to_a
107
118
  if before.empty?
108
- @loog.info('A summary not found')
109
119
  s = fb.insert
110
120
  s.what = 'judges-summary'
111
121
  s.when = Time.now
@@ -119,16 +129,14 @@ class Judges::Update
119
129
  s = before.first
120
130
  errs = s['errors']&.size || 0
121
131
  @loog.info(
122
- "A summary found, with #{errs || 'no'} error#{'s' if errs > 1}: " \
132
+ "A summary found, with #{errs.positive? || 'no'} error#{'s' if errs > 1 || errs.zero?}: " \
123
133
  "#{%w[when cycles version inserted deleted added].map { |a| "#{a}=#{s[a]&.first}" }.join(', ')}"
124
134
  )
125
135
  end
126
- f =
127
- s
128
136
  if errors.empty?
129
137
  @loog.info('No errors added to the summary')
130
138
  else
131
- errors.each { |e| f.error = e }
139
+ errors.each { |e| s.error = e }
132
140
  @loog.info("#{errors.size} error#{'s' if errors.size > 1} added to the summary")
133
141
  end
134
142
  end
data/lib/judges/judges.rb CHANGED
@@ -33,13 +33,15 @@ class Judges::Judges
33
33
  # @param [Time] start Start time
34
34
  # @param [String] shuffle Prefix for names of judges to shuffle
35
35
  # @param [Array<String>] boost Names of judges to boost in priority
36
- def initialize(dir, lib, loog, start: Time.now, shuffle: '', boost: [])
36
+ # @param [Array<String>] demote Names of judges to demote in priority
37
+ def initialize(dir, lib, loog, start: Time.now, shuffle: '', boost: [], demote: [])
37
38
  @dir = dir
38
39
  @lib = lib
39
40
  @loog = loog
40
41
  @start = start
41
42
  @shuffle = shuffle || ''
42
43
  @boost = boost
44
+ @demote = demote
43
45
  end
44
46
 
45
47
  # Retrieves a specific judge by its name.
@@ -62,7 +64,8 @@ class Judges::Judges
62
64
  # determined by:
63
65
  # 1. Judges whose names match the boost list are placed first
64
66
  # 2. Judges whose names start with the shuffle prefix are randomly reordered
65
- # 3. All other judges maintain their alphabetical order
67
+ # 3. Judges whose names match the demote list are placed last
68
+ # 4. All other judges maintain their alphabetical order
66
69
  #
67
70
  # @yield [Judges::Judge] Yields each valid judge object
68
71
  # @return [Enumerator] Returns an enumerator if no block is given
@@ -87,14 +90,19 @@ class Judges::Judges
87
90
  mapping.keys.zip(positions).to_h.each do |before, after|
88
91
  good[after] = all[before]
89
92
  end
90
- ret = []
93
+ boosted = []
94
+ demoted = []
95
+ normal = []
91
96
  good.map { |a| a[0] }.each do |j|
92
97
  if @boost&.include?(j.name)
93
- ret.prepend(j)
98
+ boosted.append(j)
99
+ elsif @demote&.include?(j.name)
100
+ demoted.append(j)
94
101
  else
95
- ret.append(j)
102
+ normal.append(j)
96
103
  end
97
104
  end
105
+ ret = boosted + normal + demoted
98
106
  ret.each(&)
99
107
  end
100
108
 
data/lib/judges.rb CHANGED
@@ -8,5 +8,5 @@
8
8
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
9
9
  # License:: MIT
10
10
  module Judges
11
- VERSION = '0.45.0' unless const_defined?(:VERSION)
11
+ VERSION = '0.46.0' unless const_defined?(:VERSION)
12
12
  end
@@ -104,7 +104,7 @@ class TestUpdate < Minitest::Test
104
104
  file = File.join(d, 'base.fb')
105
105
  2.times do
106
106
  Judges::Update.new(Loog::NULL).run(
107
- { 'quiet' => true, 'summary' => true, 'max-cycles' => 2 },
107
+ { 'quiet' => true, 'summary' => 'add', 'max-cycles' => 2 },
108
108
  [d, file]
109
109
  )
110
110
  end
@@ -130,7 +130,7 @@ class TestUpdate < Minitest::Test
130
130
  end
131
131
  File.binwrite(file, fb.export)
132
132
  Judges::Update.new(Loog::NULL).run(
133
- { 'quiet' => true, 'summary' => true, 'max-cycles' => 2 },
133
+ { 'quiet' => true, 'summary' => 'append', 'max-cycles' => 2 },
134
134
  [d, file]
135
135
  )
136
136
  fb = Factbase.new
data/test/test_judges.rb CHANGED
@@ -104,4 +104,34 @@ class TestJudges < Minitest::Test
104
104
  assert_empty(list)
105
105
  end
106
106
  end
107
+
108
+ def test_demotes_judges
109
+ Dir.mktmpdir do |d|
110
+ names = %w[alpha beta gamma delta epsilon].sort
111
+ names.each do |n|
112
+ dir = File.join(d, n)
113
+ save_it(File.join(dir, "#{n}.rb"), 'puts 1')
114
+ end
115
+ list = Judges::Judges.new(d, nil, Loog::NULL, demote: %w[beta delta]).each.to_a
116
+ result = list.map(&:name)
117
+ assert_equal(%w[alpha epsilon gamma beta delta], result)
118
+ end
119
+ end
120
+
121
+ def test_boost_and_demote_together
122
+ Dir.mktmpdir do |d|
123
+ names = %w[one two three four five six].sort
124
+ names.each do |n|
125
+ dir = File.join(d, n)
126
+ save_it(File.join(dir, "#{n}.rb"), 'puts 1')
127
+ end
128
+ list = Judges::Judges.new(d, nil, Loog::NULL, boost: %w[six two], demote: %w[one four]).each.to_a
129
+ result = list.map(&:name)
130
+ assert_equal('six', result[0])
131
+ assert_equal('two', result[1])
132
+ demoted = result[-2..]
133
+ assert_includes(demoted, 'one')
134
+ assert_includes(demoted, 'four')
135
+ end
136
+ end
107
137
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: judges
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.45.0
4
+ version: 0.46.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '0'
18
+ version: '0.4'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '0'
25
+ version: '0.4'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: baza.rb
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '0'
32
+ version: '0.5'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '0'
39
+ version: '0.5'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: concurrent-ruby
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -57,28 +57,28 @@ dependencies:
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '0'
60
+ version: '0.0'
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '0'
67
+ version: '0.0'
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: factbase
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '0.9'
74
+ version: '0.11'
75
75
  type: :runtime
76
76
  prerelease: false
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '0.9'
81
+ version: '0.11'
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: gli
84
84
  requirement: !ruby/object:Gem::Requirement
@@ -99,28 +99,28 @@ dependencies:
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '0'
102
+ version: '0.11'
103
103
  type: :runtime
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: '0.11'
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: loog
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '0'
116
+ version: '0.6'
117
117
  type: :runtime
118
118
  prerelease: false
119
119
  version_requirements: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: '0'
123
+ version: '0.6'
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: moments
126
126
  requirement: !ruby/object:Gem::Requirement
@@ -155,70 +155,70 @@ dependencies:
155
155
  requirements:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
- version: '0'
158
+ version: '0.0'
159
159
  type: :runtime
160
160
  prerelease: false
161
161
  version_requirements: !ruby/object:Gem::Requirement
162
162
  requirements:
163
163
  - - "~>"
164
164
  - !ruby/object:Gem::Version
165
- version: '0'
165
+ version: '0.0'
166
166
  - !ruby/object:Gem::Dependency
167
167
  name: retries
168
168
  requirement: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
- version: '0'
172
+ version: '0.0'
173
173
  type: :runtime
174
174
  prerelease: false
175
175
  version_requirements: !ruby/object:Gem::Requirement
176
176
  requirements:
177
177
  - - "~>"
178
178
  - !ruby/object:Gem::Version
179
- version: '0'
179
+ version: '0.0'
180
180
  - !ruby/object:Gem::Dependency
181
181
  name: tago
182
182
  requirement: !ruby/object:Gem::Requirement
183
183
  requirements:
184
184
  - - "~>"
185
185
  - !ruby/object:Gem::Version
186
- version: '0'
186
+ version: '0.1'
187
187
  type: :runtime
188
188
  prerelease: false
189
189
  version_requirements: !ruby/object:Gem::Requirement
190
190
  requirements:
191
191
  - - "~>"
192
192
  - !ruby/object:Gem::Version
193
- version: '0'
193
+ version: '0.1'
194
194
  - !ruby/object:Gem::Dependency
195
195
  name: timeout
196
196
  requirement: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - "~>"
199
199
  - !ruby/object:Gem::Version
200
- version: '0'
200
+ version: '0.4'
201
201
  type: :runtime
202
202
  prerelease: false
203
203
  version_requirements: !ruby/object:Gem::Requirement
204
204
  requirements:
205
205
  - - "~>"
206
206
  - !ruby/object:Gem::Version
207
- version: '0'
207
+ version: '0.4'
208
208
  - !ruby/object:Gem::Dependency
209
209
  name: total
210
210
  requirement: !ruby/object:Gem::Requirement
211
211
  requirements:
212
212
  - - "~>"
213
213
  - !ruby/object:Gem::Version
214
- version: '0'
214
+ version: '0.4'
215
215
  type: :runtime
216
216
  prerelease: false
217
217
  version_requirements: !ruby/object:Gem::Requirement
218
218
  requirements:
219
219
  - - "~>"
220
220
  - !ruby/object:Gem::Version
221
- version: '0'
221
+ version: '0.4'
222
222
  - !ruby/object:Gem::Dependency
223
223
  name: typhoeus
224
224
  requirement: !ruby/object:Gem::Requirement