judges 0.0.33 → 0.0.35

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: 9cdbff8b28d803f0ce0c0c8e8a934ea9af5b6d65b6396f04f94572bc21bb515e
4
- data.tar.gz: 856504a44bf49b36ee64f3d304d14861965682df9257b6bbdb1284b71330d32d
3
+ metadata.gz: 410f436fd79010f188d3768f992bef64ddc4a445773e2c790aacc059597ea227
4
+ data.tar.gz: d9eeba81aa97bb9f62ab370aee3e9a3fbaee752f5b1e41df5d33387aece0a151
5
5
  SHA512:
6
- metadata.gz: ddb58a1c8443ed4d61c3f55d155c34f0ba9e164d731167e7069169ac3ee7dbe9734fd7c4bd5a9e90a98787136b43d44966a3662fe3d13014298dcf1e770dd5d4
7
- data.tar.gz: 9c8fe18c4bebae1ceeb56611b71862d5cda792d292e6ba33f6f1e6b0700483ab385281d00e6ca1a5f3e134d644f065706e547cc3d9b56c4e634dd7c46afac0dd
6
+ metadata.gz: 37e8c527a61456b50afba302d2747f43f97804a3831dd310543a3f3eacf810a985be3693d3219bbb0a8a12f8bc24c0e4f4ede6524afbfd5be7e7701a5783e453
7
+ data.tar.gz: 9e5be6b00df4e5decac97299579c3805b6f008a405213ab78f336df2bc272aec2a98c356ca605d7849dea34e2596c0b67ce43d04de727936948bf3ed07f64e81
data/.rubocop.yml CHANGED
@@ -40,6 +40,8 @@ Layout/MultilineMethodCallIndentation:
40
40
  Enabled: false
41
41
  Metrics/AbcSize:
42
42
  Enabled: false
43
+ Metrics/ClassLength:
44
+ Enabled: false
43
45
  Metrics/BlockLength:
44
46
  Enabled: false
45
47
  Metrics/CyclomaticComplexity:
data/.rultor.yml CHANGED
@@ -33,8 +33,8 @@ release:
33
33
  rm -rf *.gem
34
34
  sed -i "s/0\.0\.0/${tag}/g" judges.gemspec
35
35
  git add judges.gemspec
36
- sed -i "s/0\.0\.0/${tag}/g" bin/judges
37
- git add bin/judges
36
+ sed -i "s/0\.0\.0/${tag}/g" lib/judges.rb
37
+ git add lib/judges.rb
38
38
  git commit -m "version set to ${tag}"
39
39
  gem build judges.gemspec
40
40
  chmod 0600 ../rubygems.yml
data/Gemfile CHANGED
@@ -25,6 +25,7 @@ gemspec
25
25
 
26
26
  gem 'cucumber', '9.2.0', require: false
27
27
  gem 'minitest', '5.23.1', require: false
28
+ gem 'net-ping', '2.0.8', require: false
28
29
  gem 'rake', '13.2.1', require: false
29
30
  gem 'rspec-rails', '6.1.2', require: false
30
31
  gem 'rubocop', '1.64.0', require: false
@@ -32,4 +33,5 @@ gem 'rubocop-performance', '1.21.0', require: false
32
33
  gem 'rubocop-rspec', '2.29.2', require: false
33
34
  gem 'simplecov', '0.22.0', require: false
34
35
  gem 'simplecov-cobertura', '2.1.0', require: false
36
+ gem 'webmock', '3.19.1', require: false
35
37
  gem 'yard', '0.9.36', require: false
data/Gemfile.lock CHANGED
@@ -3,10 +3,13 @@ PATH
3
3
  specs:
4
4
  judges (0.0.0)
5
5
  backtrace (~> 0.3)
6
- factbase (~> 0.0.32)
6
+ concurrent-ruby (= 1.2.3)
7
+ factbase (~> 0.0.38)
7
8
  gli (~> 2.21)
9
+ iri (~> 0.8)
8
10
  loog (~> 0.2)
9
11
  nokogiri (~> 1.10)
12
+ typhoeus (~> 1.3)
10
13
 
11
14
  GEM
12
15
  remote: https://rubygems.org/
@@ -37,6 +40,8 @@ GEM
37
40
  minitest (>= 5.1)
38
41
  mutex_m
39
42
  tzinfo (~> 2.0)
43
+ addressable (2.8.6)
44
+ public_suffix (>= 2.0.2, < 6.0)
40
45
  ast (2.4.2)
41
46
  backtrace (0.4.0)
42
47
  base64 (0.2.0)
@@ -44,6 +49,9 @@ GEM
44
49
  builder (3.2.4)
45
50
  concurrent-ruby (1.2.3)
46
51
  connection_pool (2.4.1)
52
+ crack (1.0.0)
53
+ bigdecimal
54
+ rexml
47
55
  crass (1.0.6)
48
56
  cucumber (9.2.0)
49
57
  builder (~> 3.2)
@@ -74,7 +82,9 @@ GEM
74
82
  docile (1.4.0)
75
83
  drb (2.2.1)
76
84
  erubi (1.12.0)
77
- factbase (0.0.32)
85
+ ethon (0.16.0)
86
+ ffi (>= 1.15.0)
87
+ factbase (0.0.38)
78
88
  json (~> 2.7)
79
89
  loog (~> 0.2)
80
90
  nokogiri (~> 1.10)
@@ -82,12 +92,14 @@ GEM
82
92
  ffi (1.16.3)
83
93
  ffi (1.16.3-x64-mingw-ucrt)
84
94
  gli (2.21.1)
95
+ hashdiff (1.1.0)
85
96
  i18n (1.14.5)
86
97
  concurrent-ruby (~> 1.0)
87
98
  io-console (0.7.2)
88
99
  irb (1.13.1)
89
100
  rdoc (>= 4.0.0)
90
101
  reline (>= 0.4.2)
102
+ iri (0.8.0)
91
103
  json (2.7.2)
92
104
  language_server-protocol (3.17.0.3)
93
105
  loofah (2.22.0)
@@ -98,6 +110,7 @@ GEM
98
110
  minitest (5.23.1)
99
111
  multi_test (1.1.0)
100
112
  mutex_m (0.2.0)
113
+ net-ping (2.0.8)
101
114
  nokogiri (1.16.5-arm64-darwin)
102
115
  racc (~> 1.4)
103
116
  nokogiri (1.16.5-x64-mingw-ucrt)
@@ -112,6 +125,7 @@ GEM
112
125
  racc
113
126
  psych (5.1.2)
114
127
  stringio
128
+ public_suffix (5.0.5)
115
129
  racc (1.8.0)
116
130
  rack (3.0.11)
117
131
  rack-session (2.0.0)
@@ -204,13 +218,19 @@ GEM
204
218
  sys-uname (1.2.3)
205
219
  ffi (~> 1.1)
206
220
  thor (1.3.1)
221
+ typhoeus (1.4.1)
222
+ ethon (>= 0.9.0)
207
223
  tzinfo (2.0.6)
208
224
  concurrent-ruby (~> 1.0)
209
225
  unicode-display_width (2.5.0)
226
+ webmock (3.19.1)
227
+ addressable (>= 2.8.0)
228
+ crack (>= 0.3.2)
229
+ hashdiff (>= 0.4.0, < 2.0.0)
210
230
  webrick (1.8.1)
211
231
  yaml (0.3.0)
212
232
  yard (0.9.36)
213
- zeitwerk (2.6.14)
233
+ zeitwerk (2.6.15)
214
234
 
215
235
  PLATFORMS
216
236
  arm64-darwin-22
@@ -222,6 +242,7 @@ DEPENDENCIES
222
242
  cucumber (= 9.2.0)
223
243
  judges!
224
244
  minitest (= 5.23.1)
245
+ net-ping (= 2.0.8)
225
246
  rake (= 13.2.1)
226
247
  rspec-rails (= 6.1.2)
227
248
  rubocop (= 1.64.0)
@@ -229,6 +250,7 @@ DEPENDENCIES
229
250
  rubocop-rspec (= 2.29.2)
230
251
  simplecov (= 0.22.0)
231
252
  simplecov-cobertura (= 2.1.0)
253
+ webmock (= 3.19.1)
232
254
  yard (= 0.9.36)
233
255
 
234
256
  BUNDLED WITH
data/bin/judges CHANGED
@@ -32,13 +32,12 @@ Encoding.default_internal = Encoding::UTF_8
32
32
  class App
33
33
  extend GLI::App
34
34
 
35
- ver = '0.0.33'
36
-
37
35
  loog = Loog::REGULAR
38
36
 
39
37
  program_desc('Automated executor of judges for a factbase')
40
38
 
41
- version(ver)
39
+ require_relative '../lib/judges'
40
+ version(Judges::VERSION)
42
41
 
43
42
  synopsis_format(:full)
44
43
 
@@ -51,7 +50,7 @@ class App
51
50
  if global[:verbose]
52
51
  loog = Loog::VERBOSE
53
52
  end
54
- loog.debug("judges #{ver}")
53
+ loog.debug("judges #{Judges::VERSION}")
55
54
  true
56
55
  end
57
56
 
@@ -131,6 +130,12 @@ class App
131
130
 
132
131
  desc 'Run automated tests for all judges'
133
132
  command :test do |c|
133
+ c.desc 'Options to pass to every judge (may be overwritten by YAML)'
134
+ c.flag([:o, :option], multiple: true, arg_name: '<key=value>')
135
+ c.desc 'Categories of tests to disable'
136
+ c.flag([:disable], multiple: true)
137
+ c.desc 'Categories of tests to enable'
138
+ c.flag([:enable], multiple: true)
134
139
  c.desc 'Name of the test pack to run'
135
140
  c.flag([:pack], multiple: true)
136
141
  c.desc 'The location of a Ruby library (directory with .rb files to include)'
@@ -142,6 +147,42 @@ class App
142
147
  Judges::Test.new(loog).run(options, args)
143
148
  end
144
149
  end
150
+
151
+ desc 'Push the factbase to the server'
152
+ command :push do |c|
153
+ c.desc 'Authentication token'
154
+ c.flag([:token])
155
+ c.desc 'The IP/hostname of the server'
156
+ c.flag([:host], default_value: 'www.zerocracy.com')
157
+ c.desc 'The TCP port number of the server'
158
+ c.flag([:port], default_value: 443)
159
+ c.desc 'Connection and read time in seconds'
160
+ c.flag([:timeout], default_value: 30)
161
+ c.desc 'Shall SSL be used?'
162
+ c.switch([:ssl], default_value: true)
163
+ c.action do |global, options, args|
164
+ require_relative '../lib/judges/commands/push'
165
+ Judges::Push.new(loog).run(options, args)
166
+ end
167
+ end
168
+
169
+ desc 'Pull the factbase from the server'
170
+ command :pull do |c|
171
+ c.desc 'Authentication token'
172
+ c.flag([:token])
173
+ c.desc 'The IP/hostname of the server'
174
+ c.flag([:host], default_value: 'www.zerocracy.com')
175
+ c.desc 'The TCP port number of the server'
176
+ c.flag([:port], default_value: 443)
177
+ c.desc 'Connection and read time in seconds'
178
+ c.flag([:timeout], default_value: 30)
179
+ c.desc 'Shall SSL be used?'
180
+ c.switch([:ssl], default_value: true)
181
+ c.action do |global, options, args|
182
+ require_relative '../lib/judges/commands/pull'
183
+ Judges::Pull.new(loog).run(options, args)
184
+ end
185
+ end
145
186
  end
146
187
 
147
188
  exit App.run(ARGV)
@@ -0,0 +1,12 @@
1
+ Feature: Pull
2
+ I want to pull a factbase
3
+
4
+ Scenario: Pull a small factbase
5
+ Given We are online
6
+ Given I make a temp directory
7
+ Then I run bin/judges with "--verbose pull --token 00000000-0000-0000-0000-000000000000 simple simple.fb"
8
+ Then Stdout contains "Pulled"
9
+ And Exit code is zero
10
+ Then I run bin/judges with "inspect simple.fb"
11
+ And Exit code is zero
12
+
@@ -0,0 +1,11 @@
1
+ Feature: Push
2
+ I want to push a factbase
3
+
4
+ Scenario: Push a small factbase
5
+ Given We are online
6
+ Given I make a temp directory
7
+ Then I run bin/judges with "--verbose eval simple.fb '$fb.insert.foo = 42'"
8
+ Then I run bin/judges with "push --token 00000000-0000-0000-0000-000000000000 simple simple.fb"
9
+ Then Stdout contains "Pushed"
10
+ And Exit code is zero
11
+
@@ -21,6 +21,7 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'tmpdir'
24
+ require 'net/ping'
24
25
  require 'English'
25
26
 
26
27
  Before do
@@ -34,6 +35,10 @@ After do
34
35
  end
35
36
  end
36
37
 
38
+ Given(/^We are online$/) do
39
+ pending unless Net::Ping::External.new('8.8.8.8').ping?
40
+ end
41
+
37
42
  Given(/^I make a temp directory$/) do
38
43
  @tmp = Dir.mktmpdir('test')
39
44
  FileUtils.mkdir_p(@tmp)
@@ -4,12 +4,12 @@ Feature: Test
4
4
  Scenario: Simple test of a few judges
5
5
  Given I run bin/judges with "test ./fixtures"
6
6
  Then Stdout contains "👉 Testing"
7
- Then Stdout contains "judge(s) tested successfully"
7
+ Then Stdout contains "All 2 judge(s) and 2 tests passed"
8
8
  And Exit code is zero
9
9
 
10
10
  Scenario: Simple test of just one pack
11
11
  Given I run bin/judges with "test --pack guess ./fixtures"
12
- Then Stdout contains "judge(s) tested successfully"
12
+ Then Stdout contains "All 1 judge(s) and 1 tests passed"
13
13
  And Exit code is zero
14
14
 
15
15
  Scenario: Simple test of no packs
@@ -28,5 +28,36 @@ Feature: Test
28
28
  $foo = 42
29
29
  """
30
30
  Then I run bin/judges with "test --lib mylib mypacks"
31
- Then Stdout contains "All 1 judge(s) tested successfully"
31
+ Then Stdout contains "All 1 judge(s) and 0 tests passed"
32
32
  And Exit code is zero
33
+
34
+ Scenario: Enable only one category
35
+ Given I make a temp directory
36
+ Then I have a "mypacks/good/good.rb" file with content:
37
+ """
38
+ n = $fb.insert
39
+ """
40
+ Then I have a "mypacks/good/good.yml" file with content:
41
+ """
42
+ ---
43
+ category: good
44
+ input: []
45
+ """
46
+ Then I have a "mypacks/bad/bad.rb" file with content:
47
+ """
48
+ broken$ruby$syntax
49
+ """
50
+ Then I have a "mypacks/bad/bad.yml" file with content:
51
+ """
52
+ ---
53
+ category: bad
54
+ """
55
+ Then I run bin/judges with "test --enable good mypacks"
56
+ Then Stdout contains "All 2 judge(s) and 1 tests passed"
57
+ And Exit code is zero
58
+ Then I run bin/judges with "test --disable bad mypacks"
59
+ Then Stdout contains "All 2 judge(s) and 1 tests passed"
60
+ And Exit code is zero
61
+ Then I run bin/judges with "test --enable bad mypacks"
62
+ Then Stdout contains "Testing mypacks/bad/bad.yml"
63
+ And Exit code is not zero
data/fixtures/try/try.rb CHANGED
@@ -20,7 +20,7 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- once($fb).query("(and (exists number) (lt time #{Time.now.utc.iso8601}))").each do |f|
23
+ each_once($fb, "(and (exists number) (lt time #{Time.now.utc.iso8601}))") do |f|
24
24
  n = $fb.insert
25
25
  n.guess = f.number
26
26
  end
data/judges.gemspec CHANGED
@@ -26,14 +26,15 @@ 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.0.33'
29
+ s.version = '0.0.35'
30
30
  s.license = 'MIT'
31
31
  s.summary = 'Command-Line Tool for a Factbase'
32
- s.description = '
33
- Runs a collection of \"judges\" against a \"factbase,\" modifying it and updating.
34
- Also, helps printing a factbase, merge with another one, inspect, and so on.
35
- Also, helps run automated tests for a set of judges.
36
- '
32
+ s.description =
33
+ 'A command-line tool that runs a collection of \"judges\" ' \
34
+ 'against a \"factbase,\" modifying ' \
35
+ 'it and updating. Also, helps printing a factbase, merge with ' \
36
+ 'another one, inspect, and so on. Also, helps run automated tests ' \
37
+ 'for a set of judges.'
37
38
  s.authors = ['Yegor Bugayenko']
38
39
  s.email = 'yegor256@gmail.com'
39
40
  s.homepage = 'http://github.com/yegor256/judges'
@@ -42,9 +43,12 @@ Gem::Specification.new do |s|
42
43
  s.rdoc_options = ['--charset=UTF-8']
43
44
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
44
45
  s.add_runtime_dependency 'backtrace', '~> 0.3'
45
- s.add_runtime_dependency 'factbase', '~>0.0.32'
46
+ s.add_runtime_dependency 'concurrent-ruby', '1.2.3'
47
+ s.add_runtime_dependency 'factbase', '~>0.0.38'
46
48
  s.add_runtime_dependency 'gli', '~>2.21'
49
+ s.add_runtime_dependency 'iri', '~>0.8'
47
50
  s.add_runtime_dependency 'loog', '~>0.2'
48
51
  s.add_runtime_dependency 'nokogiri', '~> 1.10'
52
+ s.add_runtime_dependency 'typhoeus', '~>1.3'
49
53
  s.metadata['rubygems_mfa_required'] = 'true'
50
54
  end
@@ -0,0 +1,171 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'typhoeus'
24
+ require 'iri'
25
+ require 'loog'
26
+ require_relative '../judges'
27
+ require_relative '../judges/elapsed'
28
+
29
+ # Baza.
30
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
31
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
32
+ # License:: MIT
33
+ class Judges::Baza
34
+ # rubocop:disable Metrics/ParameterLists
35
+ def initialize(host, port, token, ssl: true, timeout: 5, loog: Loog::NULL)
36
+ # rubocop:enable Metrics/ParameterLists
37
+ @host = host
38
+ @port = port
39
+ @ssl = ssl
40
+ @token = token
41
+ @timeout = timeout
42
+ @loog = loog
43
+ end
44
+
45
+ def push(name, data)
46
+ id = 0
47
+ elapsed(@loog) do
48
+ ret = Typhoeus::Request.put(
49
+ home.append('push').append(name).to_s,
50
+ body: data,
51
+ headers: headers.merge(
52
+ 'Content-type' => 'application/x-www-form-urlencoded'
53
+ ),
54
+ connecttimeout: @timeout,
55
+ timeout: @timeout
56
+ )
57
+ check_code(ret)
58
+ id = ret.body.to_i
59
+ throw :"Pushed #{data.size} bytes to #{@host}, job ID is ##{id}"
60
+ end
61
+ id
62
+ end
63
+
64
+ def pull(id)
65
+ data = 0
66
+ elapsed(@loog) do
67
+ Tempfile.open do |file|
68
+ File.open(file, 'wb') do |f|
69
+ request = Typhoeus::Request.new(
70
+ home.append('pull').append("#{id}.fb").to_s,
71
+ headers:,
72
+ connecttimeout: @timeout,
73
+ timeout: @timeout
74
+ )
75
+ request.on_body do |chunk|
76
+ f.write(chunk)
77
+ end
78
+ request.run
79
+ check_code(request.response)
80
+ end
81
+ data = File.binread(file)
82
+ throw :"Pulled #{data.size} bytes of job ##{id} factbase at #{@host}"
83
+ end
84
+ end
85
+ data
86
+ end
87
+
88
+ # The job with this ID is finished already?
89
+ def finished?(id)
90
+ finished = false
91
+ elapsed(@loog) do
92
+ ret = Typhoeus::Request.get(
93
+ home.append('finished').append(id).to_s,
94
+ headers:
95
+ )
96
+ check_code(ret)
97
+ finished = ret.body == 'yes'
98
+ throw :"The job ##{id} is #{finished ? '' : 'not yet '}finished at #{@host}"
99
+ end
100
+ finished
101
+ end
102
+
103
+ def recent(name)
104
+ job = 0
105
+ elapsed(@loog) do
106
+ ret = Typhoeus::Request.get(
107
+ home.append('recent').append("#{name}.txt").to_s,
108
+ headers:
109
+ )
110
+ check_code(ret)
111
+ job = ret.body.to_i
112
+ throw :"The recent \"#{name}\" job's ID is ##{job} at #{@host}"
113
+ end
114
+ job
115
+ end
116
+
117
+ def name_exists?(name)
118
+ exists = 0
119
+ elapsed(@loog) do
120
+ ret = Typhoeus::Request.get(
121
+ home.append('exists').append(name).to_s,
122
+ headers:
123
+ )
124
+ check_code(ret)
125
+ exists = ret.body == 'yes'
126
+ throw :"The name \"#{name}\" #{exists ? 'exists' : "doesn't exist"} at #{@host}"
127
+ end
128
+ exists
129
+ end
130
+
131
+ private
132
+
133
+ def headers
134
+ {
135
+ 'User-Agent': "judges #{Judges::VERSION}",
136
+ Connection: 'close',
137
+ 'X-Zerocracy-Token': @token
138
+ }
139
+ end
140
+
141
+ def home
142
+ Iri.new('')
143
+ .host(@host)
144
+ .port(@port)
145
+ .scheme(@ssl ? 'https' : 'http')
146
+ end
147
+
148
+ def check_code(ret, allowed = [200])
149
+ allowed = [allowed] unless allowed.is_a?(Array)
150
+ mtd = (ret.request.original_options[:method] || '???').upcase
151
+ url = ret.effective_url
152
+ @loog.debug(
153
+ "#{mtd} #{url} -> #{ret.code}\n " \
154
+ "#{(ret.headers || {}).map { |k, v| "#{k}: #{v}" }.join("\n ")}"
155
+ )
156
+ return if allowed.include?(ret.code)
157
+ msg =
158
+ "Invalid response code ##{ret.code} " \
159
+ "at #{mtd} #{url} (#{ret.headers['X-Zerocracy-Flash']})"
160
+ if ret.code == 503
161
+ msg +=
162
+ ', most probably it\'s an internal error on the server, ' \
163
+ 'please report this to https://github.com/yegor256/judges'
164
+ elsif ret.code == 404
165
+ msg +=
166
+ ', most probably you are trying to reach a wrong server, which doesn\'t ' \
167
+ 'have the URL that it is expected to have'
168
+ end
169
+ raise msg
170
+ end
171
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require_relative '../judges'
24
+
25
+ # Categories of tests.
26
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
27
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
28
+ # License:: MIT
29
+ class Judges::Categories
30
+ # Ctor.
31
+ # @param [Array<String>] enable List of categories to enable
32
+ # @param [Array<String>] disable List of categories to enable
33
+ def initialize(enable, disable)
34
+ @enable = enable.is_a?(Array) ? enable : []
35
+ @disable = disable.is_a?(Array) ? disable : []
36
+ end
37
+
38
+ # This test is good to go, with this list of categories?
39
+ # @param [Array<String>] cats List of them
40
+ # @return [Boolean] True if yes
41
+ def ok?(cats)
42
+ cats = [] if cats.nil?
43
+ cats = [cats] unless cats.is_a?(Array)
44
+ cats.each do |c|
45
+ return false if @disable.any? { |d| d == c }
46
+ return true if @enable.any? { |d| d == c }
47
+ end
48
+ return true if @enable.empty?
49
+ false
50
+ end
51
+ end
@@ -48,7 +48,7 @@ class Judges::Print
48
48
  end
49
49
  FileUtils.mkdir_p(File.dirname(o))
50
50
  if !opts['force'] && File.exist?(o)
51
- if File.mtime(f) < File.mtime(o)
51
+ if File.mtime(f) <= File.mtime(o)
52
52
  @loog.info("No need to print to #{o.to_rel}, since it's up to date (#{File.size(o)} bytes)")
53
53
  return
54
54
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'typhoeus'
24
+ require 'iri'
25
+ require_relative '../../judges'
26
+ require_relative '../../judges/impex'
27
+ require_relative '../../judges/baza'
28
+
29
+ # Pull.
30
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
31
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
32
+ # License:: MIT
33
+ class Judges::Pull
34
+ def initialize(loog)
35
+ @loog = loog
36
+ end
37
+
38
+ def run(opts, args)
39
+ raise 'Exactly two arguments required' unless args.size == 2
40
+ fb = Factbase.new
41
+ baza = Judges::Baza.new(
42
+ opts['host'], opts['port'].to_i, opts['token'],
43
+ ssl: opts['ssl'],
44
+ timeout: (opts['timeout'] || 5).to_i,
45
+ loog: @loog
46
+ )
47
+ name = args[0]
48
+ elapsed(@loog) do
49
+ if baza.name_exists?(name)
50
+ fb.import(baza.pull(wait(baza, baza.recent(name))))
51
+ Judges::Impex.new(@loog, args[1]).export(fb)
52
+ throw :"Pulled #{fb.size} facts by the name '#{name}'"
53
+ else
54
+ throw :"There is nothing to pull, the name '#{name}' is absent on the server"
55
+ end
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def wait(baza, id)
62
+ start = Time.now
63
+ loop do
64
+ break if baza.finished?(id)
65
+ sleep 1
66
+ raise 'Time is over, the job is still not finished' if Time.now - start > 10 * 60
67
+ end
68
+ id
69
+ end
70
+ end