judges 0.28.1 ā†’ 0.29.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 341626c0bc376f735ba16fccda467dfb3fe1fa9d8b4740e1a61704538cf989c8
4
- data.tar.gz: d1ca8113d163559cc8df9e073c40dc54e02aae046f57793f8e983c92d880b0c7
3
+ metadata.gz: ef7c67730c179f98b6f395fbad9be1df9229984b380c52ac6c64767b74ce241e
4
+ data.tar.gz: bf6b63a2acd86e3c8b411f069367aebaed64f5c36a85997038bf31f19cded3c1
5
5
  SHA512:
6
- metadata.gz: 2cc1c7207eae7e3cc59be1c634cc821f55c527f51014f1164f473c1d34d861302e596cf394900e869cd0304fbb5593eb9e333ffb87db6409dbbb999e6d372890
7
- data.tar.gz: e8d9ff08a6238b2bf580bf7c45ce47330f62d3d3174ad52e44a3fa2289aaf22bb1cfe69997fed2bcd0719c029f4597cc375cc48e09cb017b72deee67b3736689
6
+ metadata.gz: e8c2dd385af7ec0e2f80080e27ddec8479812521efe16ae754726adfce6593c62396fae72d6a635ed9e925aa1dee1f2382f0cdedde24abcfb1a805da925f23f4
7
+ data.tar.gz: 4597927deaf3e416a86083a2aab8db341469c604aa935e145119da1ad7bbb83319ffceaa6ac50778d33cada2cf5cd5209a5227aa5826c2febb4726b7efc36c28
data/Gemfile.lock CHANGED
@@ -15,6 +15,7 @@ PATH
15
15
  others (~> 0)
16
16
  retries (~> 0)
17
17
  tago (~> 0)
18
+ timeout (~> 0)
18
19
  typhoeus (~> 1.3)
19
20
 
20
21
  GEM
@@ -195,7 +196,7 @@ GEM
195
196
  rack (3.1.8)
196
197
  rack-session (2.0.0)
197
198
  rack (>= 3.0.0)
198
- rack-test (2.1.0)
199
+ rack-test (2.2.0)
199
200
  rack (>= 1.3)
200
201
  rackup (2.2.1)
201
202
  rack (>= 3)
@@ -274,6 +275,7 @@ GEM
274
275
  ffi (~> 1.1)
275
276
  tago (0.0.2)
276
277
  thor (1.3.2)
278
+ timeout (0.4.3)
277
279
  typhoeus (1.4.1)
278
280
  ethon (>= 0.9.0)
279
281
  tzinfo (2.0.6)
data/bin/judges CHANGED
@@ -72,6 +72,8 @@ class JudgesGLI extend GLI::App
72
72
  c.flag([:o, :option], multiple: true, arg_name: '<key=value>')
73
73
  c.desc 'The location of a Ruby library (directory with .rb files to include)'
74
74
  c.flag([:lib])
75
+ c.desc 'Maximum time in seconds to spend on every judge (forcefully terminate if over time)'
76
+ c.flag([:'timeout'], default_value: 30, type: Integer)
75
77
  c.desc 'Maximum number of update cycles to run'
76
78
  c.flag([:'max-cycles'], default_value: 8, type: Integer)
77
79
  c.desc 'Stay quiet even if some judges fail'
@@ -15,6 +15,19 @@ Feature: Update
15
15
  Then Stdout contains "Update finished in 3 cycle(s), modified 3/0 fact(s)"
16
16
  And Exit code is zero
17
17
 
18
+ Scenario: Simple run with a timeout for a judge
19
+ Given I make a temp directory
20
+ Then I have a "slow/slow.rb" file with content:
21
+ """
22
+ sleep(10)
23
+ $fb.insert.foo = 1
24
+ """
25
+ Then I run bin/judges with "--verbose update --timeout 1 --quiet . foo.fb"
26
+ Then Stdout contains "timed out"
27
+ Then Stdout contains "1 judge(s) processed"
28
+ Then Stdout contains "Update finished in 1 cycle(s), modified 0/0 fact(s)"
29
+ And Exit code is zero
30
+
18
31
  Scenario: Simple run of a few judges, with a lib
19
32
  Given I make a temp directory
20
33
  Then I have a "mine/judge1/judge1.rb" file with content:
data/judges.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
27
27
  s.required_ruby_version = '>=3.2'
28
28
  s.name = 'judges'
29
- s.version = '0.28.1'
29
+ s.version = '0.29.0'
30
30
  s.license = 'MIT'
31
31
  s.summary = 'Command-Line Tool for a Factbase'
32
32
  s.description =
@@ -55,6 +55,7 @@ Gem::Specification.new do |s|
55
55
  s.add_dependency 'others', '~>0'
56
56
  s.add_dependency 'retries', '~>0'
57
57
  s.add_dependency 'tago', '~>0'
58
+ s.add_dependency 'timeout', '~>0'
58
59
  s.add_dependency 'typhoeus', '~>1.3'
59
60
  s.metadata['rubygems_mfa_required'] = 'true'
60
61
  end
@@ -24,6 +24,7 @@ require 'backtrace'
24
24
  require 'elapsed'
25
25
  require 'factbase/looged'
26
26
  require 'tago'
27
+ require 'timeout'
27
28
  require_relative '../../judges'
28
29
  require_relative '../../judges/to_rel'
29
30
  require_relative '../../judges/judges'
@@ -45,6 +46,7 @@ class Judges::Update
45
46
  end
46
47
 
47
48
  # Run it (it is supposed to be called by the +bin/judges+ script.
49
+ #
48
50
  # @param [Hash] opts Command line options (start with '--')
49
51
  # @param [Array] args List of command line arguments
50
52
  def run(opts, args)
@@ -117,9 +119,9 @@ class Judges::Update
117
119
  judges.each_with_index do |p, i|
118
120
  @loog.info("\nšŸ‘‰ Running #{p.name} (##{i}) at #{p.dir.to_rel} (#{start.ago} already)...")
119
121
  elapsed(@loog, level: Logger::INFO) do
120
- c = one_judge(fb, p, global, options)
122
+ c = one_judge(opts, fb, p, global, options)
121
123
  churn += c
122
- throw :"šŸ‘ The judge #{p.name} modified #{c} facts out of #{fb.size}"
124
+ throw :"šŸ‘ The '#{p.name}' judge modified #{c} facts out of #{fb.size}"
123
125
  end
124
126
  rescue StandardError, SyntaxError => e
125
127
  @loog.warn(Backtrace.new(e))
@@ -136,11 +138,23 @@ class Judges::Update
136
138
  end
137
139
 
138
140
  # Run a single judge.
141
+ #
142
+ # @param [Hash] opts The command line options
143
+ # @param [Factbase] fb The factbase
144
+ # @param [Judges::Judge] judge The judge
145
+ # @param [Hash] global Global options
146
+ # @param [Judges::Options] options The options
139
147
  # @return [Churn] How many modifications have been made
140
- def one_judge(fb, judge, global, options)
148
+ def one_judge(opts, fb, judge, global, options)
141
149
  local = {}
142
150
  before = fb.size
143
- judge.run(fb, global, local, options)
151
+ begin
152
+ Timeout.timeout(opts['timeout']) do
153
+ judge.run(fb, global, local, options)
154
+ end
155
+ rescue Timeout::Error => e
156
+ throw :"šŸ‘Ž The '#{judge.name}' judge timed out: #{e.message}"
157
+ end
144
158
  after = fb.size
145
159
  diff = after - before
146
160
  if diff.positive?
data/lib/judges/judge.rb CHANGED
@@ -67,7 +67,7 @@ class Judges::Judge
67
67
  end
68
68
  s = File.join(@dir, script)
69
69
  raise "Can't load '#{s}'" unless File.exist?(s)
70
- elapsed(@loog, intro: "#{$judge} finished (#{@start.ago} already)", level: Logger::INFO) do
70
+ elapsed(@loog, intro: "#{$judge} finished", level: Logger::INFO) do
71
71
  load(s, true)
72
72
  ensure
73
73
  $fb = $judge = $options = $loog = nil
data/lib/judges.rb CHANGED
@@ -25,5 +25,5 @@
25
25
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Judges
28
- VERSION = '0.28.1'
28
+ VERSION = '0.29.0'
29
29
  end
@@ -45,6 +45,18 @@ class TestUpdate < Minitest::Test
45
45
  end
46
46
  end
47
47
 
48
+ def test_cancels_slow_judge
49
+ Dir.mktmpdir do |d|
50
+ save_it(File.join(d, 'foo/foo.rb'), 'sleep 10; $fb.insert.foo = 1')
51
+ file = File.join(d, 'base.fb')
52
+ Judges::Update.new(Loog::NULL).run({ 'timeout' => 0.1 }, [d, file])
53
+ fb = Factbase.new
54
+ fb.import(File.binread(file))
55
+ xml = Nokogiri::XML.parse(Factbase::ToXML.new(fb).xml)
56
+ assert(xml.xpath('/fb/f').empty?, xml)
57
+ end
58
+ end
59
+
48
60
  def test_extend_existing_factbase
49
61
  Dir.mktmpdir do |d|
50
62
  file = File.join(d, 'base.fb')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: judges
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.28.1
4
+ version: 0.29.0
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-12-19 00:00:00.000000000 Z
11
+ date: 2024-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -192,6 +192,20 @@ dependencies:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: timeout
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: typhoeus
197
211
  requirement: !ruby/object:Gem::Requirement