judges 0.55.0 → 0.56.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: eb2df3f4875124734e1fc6698c45a9bae82e187a73ae6632bc31906ec8039452
4
- data.tar.gz: 14639995b236e8f4ce02fb794b4050b9fc578a1816e09510312f78c3811a09da
3
+ metadata.gz: c1bce8cfaa9c1567d94332da48e35b303ec5b963198d72a82bf69164cbd1928d
4
+ data.tar.gz: 467ab5d5bab974f97be24720c3e44f15d353c38f2ecf553648431facb603864f
5
5
  SHA512:
6
- metadata.gz: f0b6906cfe65ed01d7d7d3af2677ba45fb6dc875060bcad82d055c18ceccc69973d510a7448748caf1f1bc01680d68fabbe9a223294b0707ddf721a2e1b66d3e
7
- data.tar.gz: 7d92dfe3ea479bfef86366efe451ed415bb8a54d6c8fe9cddb99348408975282dee4e061b7b89c988221177eefecc3b8a228fb3bb08710a2d34c8004403f6a78
6
+ metadata.gz: dfd3eb005e029e442b5c924620a897df19c974599122e6ae20f0369718f02b8b6171b852e32d408c5a27c766dac92260ad59e4420e14c5d8ccdcc5c8b4ca38b5
7
+ data.tar.gz: 66fbdd630846645475cab1daa36b326d92e37eeb08cf41c176b1a710e93d25acc3565b8bd4c43f6905e0bdb2752ac03dc609d6d5152e93b08b993b34463be0b2
data/Gemfile.lock CHANGED
@@ -78,8 +78,9 @@ GEM
78
78
  loog (~> 0.6)
79
79
  tago (~> 0.1)
80
80
  ellipsized (0.3.0)
81
- ethon (0.17.0)
81
+ ethon (0.18.0)
82
82
  ffi (>= 1.15.0)
83
+ logger
83
84
  factbase (0.16.8)
84
85
  backtrace (~> 0.4)
85
86
  decoor (~> 0.1)
@@ -99,8 +100,8 @@ GEM
99
100
  faraday (>= 0.8)
100
101
  faraday-multipart (1.1.1)
101
102
  multipart-post (~> 2.0)
102
- faraday-net_http (3.4.1)
103
- net-http (>= 0.5.0)
103
+ faraday-net_http (3.4.2)
104
+ net-http (~> 0.5)
104
105
  faraday-retry (2.3.2)
105
106
  faraday (~> 2.0)
106
107
  ffi (1.17.2-aarch64-linux-gnu)
@@ -116,7 +117,7 @@ GEM
116
117
  ostruct
117
118
  hashdiff (1.2.1)
118
119
  iri (0.11.2)
119
- json (2.15.1)
120
+ json (2.16.0)
120
121
  language_server-protocol (3.17.0.5)
121
122
  lint_roller (1.1.0)
122
123
  logger (1.7.0)
@@ -124,7 +125,7 @@ GEM
124
125
  logger (~> 1.0)
125
126
  memoist3 (1.0.0)
126
127
  mini_mime (1.1.5)
127
- minitest (5.26.0)
128
+ minitest (5.26.1)
128
129
  minitest-reporters (1.7.1)
129
130
  ansi
130
131
  builder
@@ -135,7 +136,7 @@ GEM
135
136
  moments (0.3.0)
136
137
  multi_test (1.1.0)
137
138
  multipart-post (2.4.1)
138
- net-http (0.6.0)
139
+ net-http (0.7.0)
139
140
  uri
140
141
  nokogiri (1.18.10-aarch64-linux-gnu)
141
142
  racc (~> 1.4)
@@ -161,25 +162,25 @@ GEM
161
162
  ostruct (0.6.3)
162
163
  others (0.1.1)
163
164
  parallel (1.27.0)
164
- parser (3.3.9.0)
165
+ parser (3.3.10.0)
165
166
  ast (~> 2.4.1)
166
167
  racc
167
168
  prism (1.6.0)
168
169
  public_suffix (6.0.2)
169
- qbash (0.4.5)
170
+ qbash (0.4.7)
170
171
  backtrace (> 0)
171
172
  elapsed (> 0)
172
173
  loog (> 0)
173
174
  tago (> 0)
174
175
  racc (1.8.1)
175
176
  rainbow (3.1.1)
176
- rake (13.3.0)
177
+ rake (13.3.1)
177
178
  random-port (0.7.6)
178
179
  tago (~> 0.0)
179
180
  regexp_parser (2.11.3)
180
181
  retries (0.0.5)
181
182
  rexml (3.4.4)
182
- rubocop (1.81.6)
183
+ rubocop (1.81.7)
183
184
  json (~> 2.3)
184
185
  language_server-protocol (~> 3.17.0.2)
185
186
  lint_roller (~> 1.1.0)
@@ -190,7 +191,7 @@ GEM
190
191
  rubocop-ast (>= 1.47.1, < 2.0)
191
192
  ruby-progressbar (~> 1.7)
192
193
  unicode-display_width (>= 2.4.0, < 4.0)
193
- rubocop-ast (1.47.1)
194
+ rubocop-ast (1.48.0)
194
195
  parser (>= 3.3.7.2)
195
196
  prism (~> 1.4)
196
197
  rubocop-minitest (0.38.2)
@@ -217,20 +218,20 @@ GEM
217
218
  sys-uname (1.4.1)
218
219
  ffi (~> 1.1)
219
220
  memoist3 (~> 1.0.0)
220
- tago (0.3.0)
221
- timeout (0.4.3)
221
+ tago (0.4.0)
222
+ timeout (0.4.4)
222
223
  total (0.4.1)
223
224
  typhoeus (1.4.1)
224
225
  ethon (>= 0.9.0)
225
226
  unicode-display_width (3.2.0)
226
227
  unicode-emoji (~> 4.1)
227
228
  unicode-emoji (4.1.0)
228
- uri (1.0.4)
229
+ uri (1.1.1)
229
230
  w3c_validators (1.3.7)
230
231
  json (>= 1.8)
231
232
  nokogiri (~> 1.6)
232
233
  rexml (~> 3.2)
233
- webmock (3.25.1)
234
+ webmock (3.26.1)
234
235
  addressable (>= 2.8.0)
235
236
  crack (>= 0.3.2)
236
237
  hashdiff (>= 0.4.0, < 2.0.0)
data/README.md CHANGED
@@ -20,10 +20,10 @@ of `.yml` files. A script in the Ruby file is executed with the following
20
20
  global variables available to it:
21
21
 
22
22
  * `$fb` — an instance
23
- of [`Factbase`](https://www.rubydoc.info/gems/factbase/0.0.22/Factbase),
23
+ of [Factbase](https://www.rubydoc.info/gems/factbase/0.0.22/Factbase),
24
24
  where facts may be added/updated;
25
25
  * `$loog` — an instance
26
- of [`Loog`](https://www.rubydoc.info/gems/loog/0.5.1/Loog),
26
+ of [Loog](https://www.rubydoc.info/gems/loog/0.5.1/Loog),
27
27
  where `.info` and `.debug` logs are welcome;
28
28
  * `$options` — a holder of options coming from either the `--option` command
29
29
  line flag or the `.yml` file during testing;
data/Rakefile CHANGED
@@ -56,6 +56,7 @@ require 'yard'
56
56
  desc 'Build Yard documentation'
57
57
  YARD::Rake::YardocTask.new do |t|
58
58
  t.files = ['lib/**/*.rb']
59
+ t.options = ['--fail-on-warning']
59
60
  end
60
61
 
61
62
  require 'rubocop/rake_task'
data/bin/judges CHANGED
@@ -13,6 +13,7 @@ require 'tago'
13
13
  require 'time'
14
14
  require 'total'
15
15
  require_relative '../lib/judges'
16
+ require_relative '../lib/judges/ascii_loog'
16
17
 
17
18
  Encoding.default_external = Encoding::UTF_8
18
19
  Encoding.default_internal = Encoding::UTF_8
@@ -57,11 +58,16 @@ class JudgesGLI extend GLI::App
57
58
  switch([:echo])
58
59
  desc 'Stay strictly offline, never attempt to reach Internet resources'
59
60
  switch([:offline])
61
+ desc 'Suppress all Unicode symbols in the output'
62
+ switch([:ascii])
60
63
 
61
64
  pre do |global, command, options, args|
62
65
  if global[:verbose]
63
66
  @@loog = Loog::VERBOSE
64
67
  end
68
+ if global[:ascii]
69
+ @@loog = Judges::AsciiLoog.new(@@loog)
70
+ end
65
71
  if global[:echo]
66
72
  @@loog.info("+ #{File.absolute_path($0)} #{@@args.join(' ')}")
67
73
  end
@@ -73,15 +79,20 @@ class JudgesGLI extend GLI::App
73
79
  end
74
80
  require 'factbase'
75
81
  if global[:hello]
76
- [
82
+ info = [
77
83
  "Judges #{Judges::VERSION}",
78
84
  "Factbase #{Factbase::VERSION}",
79
85
  "Baza-rb #{BazaRb::VERSION}",
80
86
  "Ruby: #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}",
81
87
  "Current directory: #{Dir.getwd}",
82
- "Time: #{Time.now.utc.iso8601}",
83
- "Total memory: #{Total::Mem.new.bytes / (1024 * 1024)}Mb"
84
- ].each { |m| @@loog.info(m) }
88
+ "Time: #{Time.now.utc.iso8601}"
89
+ ]
90
+ begin
91
+ info << "Total memory: #{Total::Mem.new.bytes / (1024 * 1024)}Mb"
92
+ rescue Total::CantDetect => e
93
+ @@loog.debug("Can't detect memory: #{e.message}")
94
+ end
95
+ info.each { |m| @@loog.info(m) }
85
96
  end
86
97
  true
87
98
  end
@@ -94,6 +105,7 @@ class JudgesGLI extend GLI::App
94
105
  end
95
106
 
96
107
  desc 'Update the factbase by executing all judges sequentially'
108
+ arg_name '<dir> <factbase>'
97
109
  command :update do |c|
98
110
  c.desc 'Options to pass to each judge'
99
111
  c.flag([:o, :option], multiple: true, arg_name: '<key=value>')
@@ -129,6 +141,7 @@ class JudgesGLI extend GLI::App
129
141
  end
130
142
 
131
143
  desc 'Evaluate a single Ruby expression against the factbase'
144
+ arg_name '<factbase> <expression>'
132
145
  command :eval do |c|
133
146
  c.desc 'Use default logging facility'
134
147
  c.switch([:log], default_value: true)
@@ -136,11 +149,13 @@ class JudgesGLI extend GLI::App
136
149
  end
137
150
 
138
151
  desc 'Join two factbases'
152
+ arg_name '<first> <second>'
139
153
  command :join do |c|
140
154
  run_it(c, 'join')
141
155
  end
142
156
 
143
157
  desc 'Import YAML into a factbase'
158
+ arg_name '<factbase> <yaml>'
144
159
  command :import do |c|
145
160
  c.desc 'Use default logging facility'
146
161
  c.switch([:log], default_value: true)
@@ -148,6 +163,7 @@ class JudgesGLI extend GLI::App
148
163
  end
149
164
 
150
165
  desc 'Remove outdated facts from the factbase'
166
+ arg_name 'factbase'
151
167
  command :trim do |c|
152
168
  c.desc 'Delete only facts matching the specified expression'
153
169
  c.flag([:query], default_value: '(never)')
@@ -155,6 +171,7 @@ class JudgesGLI extend GLI::App
155
171
  end
156
172
 
157
173
  desc 'Convert the factbase to a human-readable format (YAML, JSON, etc.)'
174
+ arg_name '<factbase> [<output>]'
158
175
  command :print do |c|
159
176
  c.desc 'Output format (xml, json, or yaml)'
160
177
  c.flag([:format], default_value: 'yaml')
@@ -174,11 +191,13 @@ class JudgesGLI extend GLI::App
174
191
  end
175
192
 
176
193
  desc 'Inspect the factbase and display all available metadata'
194
+ arg_name '<factbase>'
177
195
  command :inspect do |c|
178
196
  run_it(c, 'inspect')
179
197
  end
180
198
 
181
199
  desc 'Run automated tests for all judges'
200
+ arg_name '<dir>'
182
201
  command :test do |c|
183
202
  c.desc 'Options to pass to each judge (may be overridden by YAML)'
184
203
  c.flag([:o, :option], multiple: true, arg_name: '<key=value>')
@@ -200,6 +219,7 @@ class JudgesGLI extend GLI::App
200
219
  end
201
220
 
202
221
  desc 'Push the factbase to the server and unlock it remotely'
222
+ arg_name '<name> <factbase>'
203
223
  command :push do |c|
204
224
  c.desc 'Authentication token'
205
225
  c.flag([:token])
@@ -223,6 +243,7 @@ class JudgesGLI extend GLI::App
223
243
  end
224
244
 
225
245
  desc 'Pull the factbase from the server and lock it remotely'
246
+ arg_name '<name> <factbase>'
226
247
  command :pull do |c|
227
248
  c.desc 'Authentication token'
228
249
  c.flag([:token])
@@ -244,6 +265,7 @@ class JudgesGLI extend GLI::App
244
265
  end
245
266
 
246
267
  desc 'Download a durable from the server by ID'
268
+ arg_name '<id> <factbase>'
247
269
  command :download do |c|
248
270
  c.desc 'Authentication token'
249
271
  c.flag([:token])
@@ -263,6 +285,7 @@ class JudgesGLI extend GLI::App
263
285
  end
264
286
 
265
287
  desc 'Upload a file as a durable to the server'
288
+ arg_name '<file> <path>'
266
289
  command :upload do |c|
267
290
  c.desc 'Authentication token'
268
291
  c.flag([:token])
@@ -55,14 +55,14 @@ Feature: Update
55
55
  """
56
56
  n = $fb.insert
57
57
  n.type = 'first'
58
- sleep 1.9
58
+ sleep 1.91
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 2 --timeout 1 --max-cycles 5 . simple.fb"
65
+ Then I run bin/judges with "--verbose update --quiet --lifetime 4 --timeout 3 --max-cycles 5 . simple.fb"
66
66
  Then Stdout contains "Update completed in 2 cycle(s), did 3i/0d/3a"
67
67
  And Exit code is zero
68
68
 
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.55.0'
12
+ s.version = '0.56.0'
13
13
  s.license = 'MIT'
14
14
  s.summary = 'Command-Line Tool for a Factbase'
15
15
  s.description =
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
+ # SPDX-License-Identifier: MIT
5
+
6
+ require_relative '../judges'
7
+
8
+ # ASCII wrapper for Loog logging facility.
9
+ #
10
+ # This class wraps any Loog logger and converts Unicode symbols to ASCII
11
+ # equivalents when the --ascii option is enabled.
12
+ #
13
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
14
+ # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
15
+ # License:: MIT
16
+ class Judges::AsciiLoog
17
+ # Unicode to ASCII symbol mapping
18
+ UNICODE_TO_ASCII = {
19
+ '👍' => '+',
20
+ '👎' => '-',
21
+ '❌' => '!',
22
+ '👉' => '>',
23
+ '✓' => '+',
24
+ '✗' => '!',
25
+ '►' => '>',
26
+ '◄' => '<',
27
+ '▼' => 'v',
28
+ '▲' => '^'
29
+ }.freeze
30
+
31
+ # Initialize the ASCII wrapper.
32
+ # @param [Loog] loog The original logging facility to wrap
33
+ def initialize(loog)
34
+ @loog = loog
35
+ end
36
+
37
+ # Convert Unicode symbols to ASCII equivalents.
38
+ # @param [String] message The message to convert
39
+ # @return [String] The converted message with ASCII symbols
40
+ def to_ascii(message)
41
+ result = message.to_s
42
+ UNICODE_TO_ASCII.each do |unicode, ascii|
43
+ result = result.gsub(unicode, ascii)
44
+ end
45
+ result
46
+ end
47
+
48
+ # Log an info message, converting Unicode to ASCII.
49
+ # @param [String] message The message to log
50
+ def info(message)
51
+ @loog.info(to_ascii(message))
52
+ end
53
+
54
+ # Log a warning message, converting Unicode to ASCII.
55
+ # @param [String] message The message to log
56
+ def warn(message)
57
+ @loog.warn(to_ascii(message))
58
+ end
59
+
60
+ # Log an error message, converting Unicode to ASCII.
61
+ # @param [String] message The message to log
62
+ def error(message)
63
+ @loog.error(to_ascii(message))
64
+ end
65
+
66
+ # Log a debug message, converting Unicode to ASCII.
67
+ # @param [String] message The message to log
68
+ def debug(message)
69
+ @loog.debug(to_ascii(message))
70
+ end
71
+
72
+ # Delegate all other methods to the original logger.
73
+ def method_missing(method, *, &)
74
+ @loog.send(method, *, &)
75
+ end
76
+
77
+ # Check if the original logger responds to a method.
78
+ def respond_to_missing?(method, include_private = false)
79
+ @loog.respond_to?(method, include_private) || super
80
+ end
81
+ end
@@ -186,7 +186,7 @@ class Judges::Update
186
186
  end
187
187
  if opts['lifetime'] && opts['timeout']
188
188
  remained = @start + opts['lifetime'] - Time.now
189
- if remained < opts['timeout'] / 16
189
+ if remained < opts['timeout'].to_f / 16
190
190
  @loog.info("Not running #{judge.name.inspect}, not enough time left (just #{remained.seconds})")
191
191
  next
192
192
  end
@@ -45,10 +45,15 @@ class Judges::Upload
45
45
  id = baza.durable_find(jname, name)
46
46
  size = File.size(path)
47
47
  if id.nil? || id.to_s.strip.empty?
48
- Tempfile.create do |f|
48
+ f = Tempfile.new('placeholder')
49
+ begin
49
50
  File.write(f.path, 'placeholder')
51
+ f.close
50
52
  id = baza.durable_place(jname, f.path)
51
53
  @loog.info("Placed a placeholder to new durable '#{name}' in '#{jname}' (ID: #{id})")
54
+ ensure
55
+ f.close unless f.closed?
56
+ f.unlink
52
57
  end
53
58
  end
54
59
  id = id.to_i
@@ -144,8 +144,11 @@ class Judges::Options
144
144
  # Method names are automatically converted to uppercase symbols to match
145
145
  # the keys in the options hash.
146
146
  #
147
- # @param [Symbol, String] method_name The option name to retrieve
148
- # @return [Object, nil] The value of the option, or nil if not found
147
+ # @!method method_missing(method_name, *args)
148
+ # Dynamic method to access option values
149
+ # @param [Symbol] method_name The name of the option to retrieve
150
+ # @param [Array] args Additional arguments (unused)
151
+ # @return [Object, nil] The value of the option, or nil if not found
149
152
  # @example Access options as methods
150
153
  # options = Judges::Options.new(["token=abc123", "max_speed=100"])
151
154
  # options.token # => "abc123"
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.55.0' unless const_defined?(:VERSION)
11
+ VERSION = '0.56.0' unless const_defined?(:VERSION)
12
12
  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.55.0
4
+ version: 0.56.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -280,6 +280,7 @@ files:
280
280
  - fixtures/try/try.rb
281
281
  - judges.gemspec
282
282
  - lib/judges.rb
283
+ - lib/judges/ascii_loog.rb
283
284
  - lib/judges/categories.rb
284
285
  - lib/judges/commands/download.rb
285
286
  - lib/judges/commands/eval.rb