judges 0.42.0 → 0.43.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.
@@ -19,13 +19,16 @@ require_relative '../../judges/impex'
19
19
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
20
20
  # License:: MIT
21
21
  class Judges::Push
22
+ # Initialize.
23
+ # @param [Loog] loog Logging facility
22
24
  def initialize(loog)
23
25
  @loog = loog
24
26
  end
25
27
 
26
- # Run it (it is supposed to be called by the +bin/judges+ script.
28
+ # Run the push command (called by the +bin/judges+ script).
27
29
  # @param [Hash] opts Command line options (start with '--')
28
30
  # @param [Array] args List of command line arguments
31
+ # @raise [RuntimeError] If not exactly two arguments provided
29
32
  def run(opts, args)
30
33
  raise 'Exactly two arguments required' unless args.size == 2
31
34
  name = args[0]
@@ -42,7 +45,7 @@ class Judges::Push
42
45
  baza.lock(name, opts['owner'])
43
46
  begin
44
47
  id = baza.push(name, fb.export, opts['meta'] || [])
45
- throw :"Pushed #{fb.size} facts, job ID is #{id}"
48
+ throw :"šŸ‘ Pushed #{fb.size} facts, job ID is #{id}"
46
49
  ensure
47
50
  baza.unlock(name, opts['owner'])
48
51
  end
@@ -23,13 +23,16 @@ require_relative '../../judges/categories'
23
23
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  class Judges::Test
26
+ # Initialize.
27
+ # @param [Loog] loog Logging facility
26
28
  def initialize(loog)
27
29
  @loog = loog
28
30
  end
29
31
 
30
- # Run it (it is supposed to be called by the +bin/judges+ script.
32
+ # Run the test command (called by the +bin/judges+ script).
31
33
  # @param [Hash] opts Command line options (start with '--')
32
34
  # @param [Array] args List of command line arguments
35
+ # @raise [RuntimeError] If not exactly one argument provided
33
36
  def run(opts, args)
34
37
  raise 'Exactly one argument required' unless args.size == 1
35
38
  dir = args[0]
@@ -51,11 +54,11 @@ class Judges::Test
51
54
  next unless include?(opts, judge.name, tname)
52
55
  yaml = YAML.load_file(f, permitted_classes: [Time])
53
56
  if yaml['skip']
54
- @loog.info("Skippped #{f.to_rel}")
57
+ @loog.info("Skipped #{f.to_rel}")
55
58
  next
56
59
  end
57
60
  unless Judges::Categories.new(opts['enable'], opts['disable']).ok?(yaml['category'])
58
- @loog.info("Skippped #{f.to_rel} because of its category")
61
+ @loog.info("Skipped #{f.to_rel} because of its category")
59
62
  next
60
63
  end
61
64
  @loog.info("šŸ› ļø Testing #{f.to_rel}:")
@@ -122,8 +125,8 @@ class Judges::Test
122
125
  def include?(opts, name, tname = nil)
123
126
  judges = opts['judge'] || []
124
127
  return true if judges.empty?
125
- tre = tname.nil? ? '.+' : tname
126
- judges.any? { |n| n.match?(%r{^#{name}(/#{tre})?$}) }
128
+ re = tname.nil? ? '.+' : tname
129
+ judges.any? { |n| n.match?(%r{^#{name}(/#{re})?$}) }
127
130
  end
128
131
 
129
132
  def prepare(fb, yaml)
@@ -17,22 +17,25 @@ require_relative '../../judges/impex'
17
17
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
18
18
  # License:: MIT
19
19
  class Judges::Trim
20
+ # Initialize.
21
+ # @param [Loog] loog Logging facility
20
22
  def initialize(loog)
21
23
  @loog = loog
22
24
  end
23
25
 
24
- # Run it (it is supposed to be called by the +bin/judges+ script.
26
+ # Run the trim command (called by the +bin/judges+ script).
25
27
  # @param [Hash] opts Command line options (start with '--')
26
28
  # @param [Array] args List of command line arguments
29
+ # @raise [RuntimeError] If not exactly one argument provided
27
30
  def run(opts, args)
28
31
  raise 'Exactly one argument required' unless args.size == 1
29
32
  impex = Judges::Impex.new(@loog, args[0])
30
33
  fb = impex.import
31
34
  elapsed(@loog, level: Logger::INFO) do
32
35
  deleted = fb.query(opts['query']).delete!
33
- throw :'No facts deleted' if deleted.zero?
36
+ throw :'āš ļø No facts deleted' if deleted.zero?
34
37
  impex.export(fb)
35
- throw :"šŸ—‘ #{deleted} fact(s) deleted"
38
+ throw :"šŸ‘ #{deleted} fact(s) deleted"
36
39
  end
37
40
  end
38
41
  end
@@ -26,15 +26,17 @@ require_relative '../../judges/to_rel'
26
26
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
27
27
  # License:: MIT
28
28
  class Judges::Update
29
+ # Initialize.
30
+ # @param [Loog] loog Logging facility
29
31
  def initialize(loog)
30
32
  @loog = loog
31
33
  @start = Time.now
32
34
  end
33
35
 
34
- # Run it (it is supposed to be called by the +bin/judges+ script.
35
- #
36
+ # Run the update command (called by the +bin/judges+ script).
36
37
  # @param [Hash] opts Command line options (start with '--')
37
38
  # @param [Array] args List of command line arguments
39
+ # @raise [RuntimeError] If not exactly two arguments provided or directory is missing
38
40
  def run(opts, args)
39
41
  raise 'Exactly two arguments required' unless args.size == 2
40
42
  dir = args[0]
@@ -79,9 +81,13 @@ class Judges::Update
79
81
  @loog.info("Too many cycles already, as set by --max-cycles=#{opts['max-cycles']}, breaking")
80
82
  break
81
83
  end
84
+ if opts['fail-fast'] && !errors.empty?
85
+ @loog.info("Due to #{errors.count} errors we must stop at the update cycle ##{c}")
86
+ break
87
+ end
82
88
  @loog.info("The cycle #{c} did #{delta}")
83
89
  end
84
- throw :"Update finished in #{c} cycle(s), did #{churn}"
90
+ throw :"šŸ‘ Update completed in #{c} cycle(s), did #{churn}"
85
91
  end
86
92
  return unless opts['summary']
87
93
  summarize(fb, churn, errors, start, c)
@@ -94,7 +100,7 @@ class Judges::Update
94
100
  # @param [Factbase] fb The factbase
95
101
  # @param [Churn] churn The churn
96
102
  # @param [Array<String>] errors List of errors
97
- # @param [Time] start Whe we started
103
+ # @param [Time] start When we started
98
104
  # @param [Integer] cycles How many cycles
99
105
  def summarize(fb, churn, errors, start, cycles)
100
106
  before = fb.query('(eq what "judges-summary")').each.to_a
@@ -142,6 +148,10 @@ class Judges::Update
142
148
  elapsed(@loog, level: Logger::INFO) do
143
149
  done =
144
150
  judges.each_with_index do |judge, i|
151
+ if opts['fail-fast'] && !errors.empty?
152
+ @loog.info("Not running #{judge.name.inspect} due to #{errors.count} errors above, in --fail-fast mode")
153
+ next
154
+ end
145
155
  next unless include?(opts, judge.name)
146
156
  @loog.info("\nšŸ‘‰ Running #{judge.name} (##{i}) at #{judge.dir.to_rel} (#{start.ago} already)...")
147
157
  elapsed(@loog, level: Logger::INFO) do
data/lib/judges/impex.rb CHANGED
@@ -14,11 +14,17 @@ require_relative '../judges/to_rel'
14
14
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
15
15
  # License:: MIT
16
16
  class Judges::Impex
17
+ # Initialize.
18
+ # @param [Loog] loog Logging facility
19
+ # @param [String] file File path for import/export operations
17
20
  def initialize(loog, file)
18
21
  @loog = loog
19
22
  @file = file
20
23
  end
21
24
 
25
+ # Import factbase from file.
26
+ # @param [Boolean] strict Whether to raise error if file doesn't exist
27
+ # @return [Factbase] The imported factbase
22
28
  def import(strict: true)
23
29
  fb = Factbase.new
24
30
  if File.exist?(@file)
@@ -33,6 +39,9 @@ class Judges::Impex
33
39
  fb
34
40
  end
35
41
 
42
+ # Import factbase from file into existing factbase.
43
+ # @param [Factbase] fb The factbase to import into
44
+ # @raise [RuntimeError] If file doesn't exist
36
45
  def import_to(fb)
37
46
  raise "The factbase is absent at #{@file.to_rel}" unless File.exist?(@file)
38
47
  elapsed(@loog, level: Logger::INFO) do
@@ -41,6 +50,8 @@ class Judges::Impex
41
50
  end
42
51
  end
43
52
 
53
+ # Export factbase to file.
54
+ # @param [Factbase] fb The factbase to export
44
55
  def export(fb)
45
56
  elapsed(@loog, level: Logger::INFO) do
46
57
  FileUtils.mkdir_p(File.dirname(@file))
data/lib/judges/judge.rb CHANGED
@@ -59,7 +59,7 @@ class Judges::Judge
59
59
  end
60
60
  s = File.join(@dir, script)
61
61
  raise "Can't load '#{s}'" unless File.exist?(s)
62
- elapsed(@loog, intro: "#{$judge} finished", level: Logger::INFO) do
62
+ elapsed(@loog, intro: "#{$judge} completed", level: Logger::INFO) do
63
63
  load(s, true)
64
64
  $fb.churn
65
65
  # rubocop:disable Lint/RescueException
data/lib/judges/judges.rb CHANGED
@@ -26,6 +26,13 @@ require_relative 'judge'
26
26
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
27
27
  # License:: MIT
28
28
  class Judges::Judges
29
+ # Initialize.
30
+ # @param [String] dir Directory containing judges
31
+ # @param [String] lib Library directory
32
+ # @param [Loog] loog Logging facility
33
+ # @param [Time] start Start time
34
+ # @param [String] shuffle Prefix for names of judges to shuffle
35
+ # @param [Array<String>] boost Names of judges to boost in priority
29
36
  def initialize(dir, lib, loog, start: Time.now, shuffle: '', boost: [])
30
37
  @dir = dir
31
38
  @lib = lib
@@ -36,15 +43,18 @@ class Judges::Judges
36
43
  end
37
44
 
38
45
  # Get one judge by name.
39
- # @return [Judge]
46
+ # @param [String] name The name of the judge
47
+ # @return [Judge] The judge object
48
+ # @raise [RuntimeError] If judge doesn't exist
40
49
  def get(name)
41
50
  d = File.absolute_path(File.join(@dir, name))
42
51
  raise "Judge #{name} doesn't exist in #{@dir}" unless File.exist?(d)
43
52
  Judges::Judge.new(d, @lib, @loog, start: @start)
44
53
  end
45
54
 
46
- # Iterate over them all.
47
- # @yield [Judge]
55
+ # Iterate over all judges.
56
+ # @yield [Judge] Yields each judge
57
+ # @return [Enumerator] If no block given
48
58
  def each(&)
49
59
  return to_enum(__method__) unless block_given?
50
60
  list =
@@ -77,8 +87,9 @@ class Judges::Judges
77
87
  ret.each(&)
78
88
  end
79
89
 
80
- # Iterate over them all, with an index.
81
- # @yield [(Judge, Integer)]
90
+ # Iterate over all judges with index.
91
+ # @yield [Judge, Integer] Yields each judge with its index
92
+ # @return [Integer] The total count of judges
82
93
  def each_with_index
83
94
  idx = 0
84
95
  each do |p|
@@ -17,10 +17,15 @@ class Judges::Options
17
17
  @pairs = pairs
18
18
  end
19
19
 
20
+ # Check if options are empty.
21
+ # @return [Boolean] true if no options are set
20
22
  def empty?
21
23
  to_h.empty?
22
24
  end
23
25
 
26
+ # Merge with another Options object.
27
+ # @param [Judges::Options] other The other options to merge
28
+ # @return [Judges::Options] A new Options object with merged values
24
29
  def +(other)
25
30
  h = to_h
26
31
  other.to_h.each do |k, v|
@@ -38,6 +43,8 @@ class Judges::Options
38
43
  end.sort.join("\n")
39
44
  end
40
45
 
46
+ # Convert options to hash.
47
+ # @return [Hash] The options as a hash with symbol keys
41
48
  def to_h
42
49
  @to_h ||=
43
50
  begin
data/lib/judges/to_rel.rb CHANGED
@@ -11,6 +11,7 @@ require 'pathname'
11
11
  # License:: MIT
12
12
  class Object
13
13
  # Generates a relative name of a file (to the current dir).
14
+ # @return [String] Relative path to the file with optional quotes if it contains spaces
14
15
  def to_rel
15
16
  s = File.absolute_path(to_s)
16
17
  p = Pathname.new(s).relative_path_from(Dir.getwd)
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.42.0' unless const_defined?(:VERSION)
11
+ VERSION = '0.43.0' unless const_defined?(:VERSION)
12
12
  end