judges 0.0.33 → 0.0.35

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: 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