judges 0.20.0 → 0.22.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: 1661542d2bb953029d98b55aee247ee5067488e67e7fa4debd8a35d7278bce55
4
- data.tar.gz: 79803f9f17983970b404abd8c8619e08ad3d5587156f4cedd477f295c98ab2bb
3
+ metadata.gz: 17df0b6c88dd19b576bc701737985db26986e9818eb3c87b36180be92fca54f6
4
+ data.tar.gz: 48ef9ea5656a6bd78264f0b1f7021555ffa92eaf5be71d311d60e59ab0d3c0c8
5
5
  SHA512:
6
- metadata.gz: 60bc48ba4d2532ce4d7960d132a5bc59674794c6b8495ada4852ea83745cdd6cdf1064ff9f76440573c34564c73057a19306f55b23fdddd783bd240517f23099
7
- data.tar.gz: 528812bef0c9f6ba6225210a1130cfd03aea5816eb7c75da99adf323aaf09932cb18d6c0e9e057096212e353b85bf551a65b3144ba86504ff2d1930cdc1dcdaa
6
+ metadata.gz: 722ef79a6af057ba1f4cf37860212b6a3c08f7aff838dfb4e8034e7970e27c4efe98e66da9c774e45707999b9e70966eacd19e4a1478a54a798d12b1d03b662b
7
+ data.tar.gz: c9551f302a6f0f02ef81e4a2ef5631c98bc2ad08a39982563749b29867d0bf06258a5e7a167179f70f899031cf2ffe097a014e9480a0a767192915d68f78479a
@@ -21,7 +21,11 @@
21
21
  name: copyrights
22
22
  'on':
23
23
  push:
24
+ branches:
25
+ - master
24
26
  pull_request:
27
+ branches:
28
+ - master
25
29
  jobs:
26
30
  copyrights:
27
31
  runs-on: ubuntu-22.04
@@ -19,9 +19,13 @@
19
19
  # SOFTWARE.
20
20
  ---
21
21
  name: xcop
22
- on:
22
+ 'on':
23
23
  push:
24
+ branches:
25
+ - master
24
26
  pull_request:
27
+ branches:
28
+ - master
25
29
  jobs:
26
30
  xcop:
27
31
  runs-on: ubuntu-22.04
data/.rubocop.yml CHANGED
@@ -58,3 +58,7 @@ Naming/MethodParameterName:
58
58
  MinNameLength: 2
59
59
  Layout/EndOfLine:
60
60
  EnforcedStyle: lf
61
+ Layout/MultilineAssignmentLayout:
62
+ Enabled: true
63
+ Layout/FirstHashElementIndentation:
64
+ EnforcedStyle: consistent
data/Gemfile CHANGED
@@ -30,7 +30,7 @@ gem 'net-ping', '2.0.8', require: false
30
30
  gem 'rake', '13.2.1', require: false
31
31
  gem 'random-port', '~>0.0', require: false
32
32
  gem 'rspec-rails', '6.1.3', require: false
33
- gem 'rubocop', '1.65.0', require: false
33
+ gem 'rubocop', '1.65.1', require: false
34
34
  gem 'rubocop-performance', '1.21.1', require: false
35
35
  gem 'rubocop-rspec', '3.0.3', require: false
36
36
  gem 'simplecov', '0.22.0', require: false
data/Gemfile.lock CHANGED
@@ -71,7 +71,7 @@ GEM
71
71
  multi_test (~> 1.1)
72
72
  sys-uname (~> 1.2)
73
73
  cucumber-ci-environment (10.0.1)
74
- cucumber-core (13.0.2)
74
+ cucumber-core (13.0.3)
75
75
  cucumber-gherkin (>= 27, < 28)
76
76
  cucumber-messages (>= 20, < 23)
77
77
  cucumber-tag-expressions (> 5, < 7)
@@ -85,12 +85,12 @@ GEM
85
85
  cucumber-tag-expressions (6.1.0)
86
86
  decoor (0.0.1)
87
87
  diff-lcs (1.5.1)
88
- docile (1.4.0)
88
+ docile (1.4.1)
89
89
  drb (2.2.1)
90
90
  erubi (1.13.0)
91
91
  ethon (0.16.0)
92
92
  ffi (>= 1.15.0)
93
- factbase (0.2.0)
93
+ factbase (0.2.1)
94
94
  backtrace (> 0)
95
95
  decoor (> 0)
96
96
  json (~> 2.7)
@@ -120,7 +120,7 @@ GEM
120
120
  loofah (2.22.0)
121
121
  crass (~> 1.0.2)
122
122
  nokogiri (>= 1.12.0)
123
- loog (0.5.2)
123
+ loog (0.5.3)
124
124
  mini_mime (1.1.5)
125
125
  minitest (5.24.1)
126
126
  minitest-reporters (1.7.1)
@@ -132,19 +132,19 @@ GEM
132
132
  multi_test (1.1.0)
133
133
  mutex_m (0.2.0)
134
134
  net-ping (2.0.8)
135
- nokogiri (1.16.6-aarch64-linux)
135
+ nokogiri (1.16.7-aarch64-linux)
136
136
  racc (~> 1.4)
137
- nokogiri (1.16.6-arm-linux)
137
+ nokogiri (1.16.7-arm-linux)
138
138
  racc (~> 1.4)
139
- nokogiri (1.16.6-arm64-darwin)
139
+ nokogiri (1.16.7-arm64-darwin)
140
140
  racc (~> 1.4)
141
- nokogiri (1.16.6-x64-mingw-ucrt)
141
+ nokogiri (1.16.7-x64-mingw-ucrt)
142
142
  racc (~> 1.4)
143
- nokogiri (1.16.6-x86-linux)
143
+ nokogiri (1.16.7-x86-linux)
144
144
  racc (~> 1.4)
145
- nokogiri (1.16.6-x86_64-darwin)
145
+ nokogiri (1.16.7-x86_64-darwin)
146
146
  racc (~> 1.4)
147
- nokogiri (1.16.6-x86_64-linux)
147
+ nokogiri (1.16.7-x86_64-linux)
148
148
  racc (~> 1.4)
149
149
  others (0.0.3)
150
150
  parallel (1.25.1)
@@ -153,8 +153,8 @@ GEM
153
153
  racc
154
154
  psych (5.1.2)
155
155
  stringio
156
- public_suffix (6.0.0)
157
- racc (1.8.0)
156
+ public_suffix (6.0.1)
157
+ racc (1.8.1)
158
158
  rack (3.1.7)
159
159
  rack-session (2.0.0)
160
160
  rack (>= 3.0.0)
@@ -187,7 +187,7 @@ GEM
187
187
  reline (0.5.9)
188
188
  io-console (~> 0.5)
189
189
  retries (0.0.5)
190
- rexml (3.3.2)
190
+ rexml (3.3.4)
191
191
  strscan
192
192
  rspec-core (3.13.0)
193
193
  rspec-support (~> 3.13.0)
@@ -206,7 +206,7 @@ GEM
206
206
  rspec-mocks (~> 3.13)
207
207
  rspec-support (~> 3.13)
208
208
  rspec-support (3.13.1)
209
- rubocop (1.65.0)
209
+ rubocop (1.65.1)
210
210
  json (~> 2.3)
211
211
  language_server-protocol (>= 3.17.0)
212
212
  parallel (~> 1.10)
@@ -252,7 +252,7 @@ GEM
252
252
  webrick (1.8.1)
253
253
  yaml (0.3.0)
254
254
  yard (0.9.36)
255
- zeitwerk (2.6.16)
255
+ zeitwerk (2.6.17)
256
256
 
257
257
  PLATFORMS
258
258
  aarch64-linux
@@ -272,7 +272,7 @@ DEPENDENCIES
272
272
  rake (= 13.2.1)
273
273
  random-port (~> 0.0)
274
274
  rspec-rails (= 6.1.3)
275
- rubocop (= 1.65.0)
275
+ rubocop (= 1.65.1)
276
276
  rubocop-performance (= 1.21.1)
277
277
  rubocop-rspec (= 3.0.3)
278
278
  simplecov (= 0.22.0)
@@ -281,4 +281,4 @@ DEPENDENCIES
281
281
  yard (= 0.9.36)
282
282
 
283
283
  BUNDLED WITH
284
- 2.5.6
284
+ 2.5.16
data/README.md CHANGED
@@ -48,6 +48,9 @@ options:
48
48
  max: 100
49
49
  expected:
50
50
  - /fb[count(f)=1]
51
+ after:
52
+ - first.rb
53
+ - second.rb
51
54
  ```
52
55
 
53
56
  Here, the `input` is an array of facts to be placed into the Factbase before
@@ -65,6 +68,10 @@ be executed. After each execution, all expected XPath expressions are validated.
65
68
  The `before` (default: `[]`) is a list of judges that must be executed before
66
69
  the current one.
67
70
 
71
+ The `after` (default: `[]`) is a list of relative file names
72
+ of Ruby scripts that are executed after the judge
73
+ (`$fb` and `$loog` are passed into them).
74
+
68
75
  ## How to contribute
69
76
 
70
77
  Read
data/bin/judges CHANGED
@@ -32,7 +32,15 @@ Encoding.default_internal = Encoding::UTF_8
32
32
 
33
33
  class JudgesGLI extend GLI::App
34
34
 
35
- loog = Loog::REGULAR
35
+ def self.run_it(cmd, ruby)
36
+ cmd.action do |global, options, args|
37
+ require_relative "../lib/judges/commands/#{ruby}"
38
+ @@loog.debug("Running '#{ruby}' command...")
39
+ Object.const_get("Judges::#{ruby.capitalize}").new(@@loog).run(options, args)
40
+ end
41
+ end
42
+
43
+ @@loog = Loog::REGULAR
36
44
 
37
45
  program_desc('Automated executor of judges for a factbase')
38
46
 
@@ -48,13 +56,13 @@ class JudgesGLI extend GLI::App
48
56
 
49
57
  pre do |global, command, options, args|
50
58
  if global[:verbose]
51
- loog = Loog::VERBOSE
59
+ @@loog = Loog::VERBOSE
52
60
  end
53
- loog.debug("Judges #{Judges::VERSION}")
54
- loog.debug("Factbase #{Factbase::VERSION}")
55
- loog.debug("Ruby: #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}")
56
- loog.debug("Current directory: #{Dir.getwd}")
57
- loog.debug("Time: #{Time.now.utc.iso8601}")
61
+ @@loog.debug("Judges #{Judges::VERSION}")
62
+ @@loog.debug("Factbase #{Factbase::VERSION}")
63
+ @@loog.debug("Ruby: #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}")
64
+ @@loog.debug("Current directory: #{Dir.getwd}")
65
+ @@loog.debug("Time: #{Time.now.utc.iso8601}")
58
66
  true
59
67
  end
60
68
 
@@ -72,44 +80,29 @@ class JudgesGLI extend GLI::App
72
80
  c.switch([:summary], default_value: false)
73
81
  c.desc 'Use default logging facility'
74
82
  c.switch([:log], default_value: true)
75
- c.action do |global, options, args|
76
- require_relative '../lib/judges/commands/update'
77
- Judges::Update.new(loog).run(options, args)
78
- end
83
+ run_it(c, 'update')
79
84
  end
80
85
 
81
86
  desc 'Evaluate a single Ruby expression on the factbase'
82
87
  command :eval do |c|
83
- c.action do |global, options, args|
84
- require_relative '../lib/judges/commands/eval'
85
- Judges::Eval.new(loog).run(options, args)
86
- end
88
+ run_it(c, 'eval')
87
89
  end
88
90
 
89
91
  desc 'Join two factbases'
90
92
  command :join do |c|
91
- c.action do |global, options, args|
92
- require_relative '../lib/judges/commands/join'
93
- Judges::Join.new(loog).run(options, args)
94
- end
93
+ run_it(c, 'join')
95
94
  end
96
95
 
97
96
  desc 'Import YAML into a factbase'
98
97
  command :import do |c|
99
- c.action do |global, options, args|
100
- require_relative '../lib/judges/commands/import'
101
- Judges::Import.new(loog).run(options, args)
102
- end
98
+ run_it(c, 'import')
103
99
  end
104
100
 
105
101
  desc 'Remove the facts that are too old'
106
102
  command :trim do |c|
107
103
  c.desc 'Only the facts that match the expression are deleted'
108
104
  c.flag([:query], default_value: '(never)')
109
- c.action do |global, options, args|
110
- require_relative '../lib/judges/commands/trim'
111
- Judges::Trim.new(loog).run(options, args)
112
- end
105
+ run_it(c, 'trim')
113
106
  end
114
107
 
115
108
  desc 'Print the factbase into a human-readable format (YAML, JSON, etc.)'
@@ -128,18 +121,12 @@ class JudgesGLI extend GLI::App
128
121
  c.flag([:hidden], default_value: '_id,_time,_version')
129
122
  c.desc 'Print even if target file already exists and is older than the factbase'
130
123
  c.switch([:force], default_value: false)
131
- c.action do |global, options, args|
132
- require_relative '../lib/judges/commands/print'
133
- Judges::Print.new(loog).run(options, args)
134
- end
124
+ run_it(c, 'print')
135
125
  end
136
126
 
137
127
  desc 'Inspect the factbase and print all its possible meta-data'
138
128
  command :inspect do |c|
139
- c.action do |global, options, args|
140
- require_relative '../lib/judges/commands/inspect'
141
- Judges::Inspect.new(loog).run(options, args)
142
- end
129
+ run_it(c, 'inspect')
143
130
  end
144
131
 
145
132
  desc 'Run automated tests for all judges'
@@ -160,10 +147,7 @@ class JudgesGLI extend GLI::App
160
147
  c.switch([:quiet], default_value: false)
161
148
  c.desc 'Use default logging facility'
162
149
  c.switch([:log], default_value: true)
163
- c.action do |global, options, args|
164
- require_relative '../lib/judges/commands/test'
165
- Judges::Test.new(loog).run(options, args)
166
- end
150
+ run_it(c, 'test')
167
151
  end
168
152
 
169
153
  desc 'Push the factbase to the server'
@@ -184,10 +168,9 @@ class JudgesGLI extend GLI::App
184
168
  c.flag([:meta], type: String, multiple: true)
185
169
  c.desc 'How many times to retry'
186
170
  c.flag([:retries], type: Integer, default_value: 3)
187
- c.action do |global, options, args|
188
- require_relative '../lib/judges/commands/push'
189
- Judges::Push.new(loog).run(options, args)
190
- end
171
+ c.desc 'Turn on the package compression'
172
+ c.switch([:zip], default_value: true)
173
+ run_it(c, 'push')
191
174
  end
192
175
 
193
176
  desc 'Pull the factbase from the server'
@@ -208,10 +191,7 @@ class JudgesGLI extend GLI::App
208
191
  c.flag([:owner], default_value: 'default', type: String)
209
192
  c.desc 'How many times to retry'
210
193
  c.flag([:retries], type: Integer, default_value: 3)
211
- c.action do |global, options, args|
212
- require_relative '../lib/judges/commands/pull'
213
- Judges::Pull.new(loog).run(options, args)
214
- end
194
+ run_it(c, 'pull')
215
195
  end
216
196
  end
217
197
 
@@ -1,12 +1,10 @@
1
1
  Feature: Pull
2
2
  I want to pull a factbase
3
3
 
4
- Scenario: Pull a small factbase
4
+ Scenario: Pull a small factbase, which is absent on the server
5
5
  Given We are online
6
6
  Given I make a temp directory
7
- Then I run bin/judges with "--verbose pull --token 00000000-0000-0000-0000-000000000000 --wait=15 simple simple.fb"
8
- Then Stdout contains "Pulled"
9
- And Exit code is zero
10
- Then I run bin/judges with "inspect simple.fb"
7
+ Then I run bin/judges with "--verbose pull --token 00000000-0000-0000-0000-000000000000 --wait=15 {FAKE-NAME} simple.fb"
8
+ Then Stdout contains "doesn't exist at www.zerocracy.com"
11
9
  And Exit code is zero
12
10
 
@@ -6,6 +6,6 @@ Feature: Push
6
6
  Given I make a temp directory
7
7
  Then I run bin/judges with "--verbose eval simple.fb '(0..1000).each { $fb.insert.foo = 42 }'"
8
8
  And Exit code is zero
9
- Then I run bin/judges with "push --token 00000000-0000-0000-0000-000000000000 --meta a:b --meta foo:bar --meta=pages_url:https://zerocracy.github.io/zerocracy.html --meta=duration:1055 simple simple.fb"
9
+ Then I run bin/judges with "push --token 00000000-0000-0000-0000-000000000000 --meta a:b --meta foo:bar --meta=pages_url:https://zerocracy.github.io/zerocracy.html --meta=duration:1055 {FAKE-NAME} simple.fb"
10
10
  Then Stdout contains "Pushed"
11
11
  And Exit code is zero
@@ -23,6 +23,7 @@
23
23
  require 'tmpdir'
24
24
  require 'net/ping'
25
25
  require 'English'
26
+ require 'securerandom'
26
27
 
27
28
  Before do
28
29
  @cwd = Dir.pwd
@@ -52,6 +53,7 @@ end
52
53
 
53
54
  When(%r{^I run bin/judges with "([^"]*)"$}) do |arg|
54
55
  home = File.join(File.dirname(__FILE__), '../..')
56
+ arg.gsub!('{FAKE-NAME}') { "fake#{SecureRandom.hex(8)}" }
55
57
  cmd = "ruby -I#{home}/lib #{home}/bin/judges #{arg}"
56
58
  cmd = "GLI_DEBUG=true #{cmd}" unless Gem.win_platform?
57
59
  @stdout = `#{cmd} 2>&1`
@@ -28,14 +28,14 @@ Feature: Test
28
28
 
29
29
  Scenario: Simple test of a few judges, with a lib
30
30
  Given I make a temp directory
31
- Then I have a "myjudges/myjudge/simple_judge.rb" file with content:
31
+ Then I have a "myjudges/good/good.rb" file with content:
32
32
  """
33
33
  $valve.enter('boom', 'some reason') do
34
34
  n = $fb.insert
35
35
  n.foo = $foo
36
36
  end
37
37
  """
38
- Then I have a "myjudges/myjudge/good.yml" file with content:
38
+ Then I have a "myjudges/good/good.yml" file with content:
39
39
  """
40
40
  ---
41
41
  category: good
@@ -51,7 +51,7 @@ Feature: Test
51
51
 
52
52
  Scenario: Simple test with many runs
53
53
  Given I make a temp directory
54
- Then I have a "foo/simple.rb" file with content:
54
+ Then I have a "foo/foo.rb" file with content:
55
55
  """
56
56
  n = $fb.insert
57
57
  n.foo = $fb.size
@@ -70,7 +70,7 @@ Feature: Test
70
70
 
71
71
  Scenario: Simple test with many runs and many asserts
72
72
  Given I make a temp directory
73
- Then I have a "foo/simple.rb" file with content:
73
+ Then I have a "foo/foo.rb" file with content:
74
74
  """
75
75
  n = $fb.insert
76
76
  n.foo = $fb.size
@@ -141,3 +141,25 @@ Feature: Test
141
141
  """
142
142
  Then I run bin/judges with "test mine"
143
143
  And Exit code is zero
144
+
145
+ Scenario: Test with a post-assert
146
+ Given I make a temp directory
147
+ Then I have a "mine/foo/foo.rb" file with content:
148
+ """
149
+ n = $fb.insert
150
+ n.foo = 42
151
+ """
152
+ Then I have a "mine/foo/assert.rb" file with content:
153
+ """
154
+ raise unless $fb.size == 1
155
+ """
156
+ Then I have a "mine/foo/simple.yml" file with content:
157
+ """
158
+ ---
159
+ expected:
160
+ - /fb[count(f)=1]
161
+ after:
162
+ - assert.rb
163
+ """
164
+ Then I run bin/judges with "test mine"
165
+ And Exit code is zero
@@ -3,7 +3,7 @@ Feature: Update
3
3
 
4
4
  Scenario: Simple run of a few judges
5
5
  Given I make a temp directory
6
- Then I have a "simple/simple_judge.rb" file with content:
6
+ Then I have a "simple/simple.rb" file with content:
7
7
  """
8
8
  n = $fb.insert
9
9
  n.kind = 'yes!'
@@ -17,7 +17,7 @@ Feature: Update
17
17
 
18
18
  Scenario: Simple run of a few judges, with a lib
19
19
  Given I make a temp directory
20
- Then I have a "mine/judge1/simple_judge.rb" file with content:
20
+ Then I have a "mine/judge1/judge1.rb" file with content:
21
21
  """
22
22
  $valve.enter('boom', 'for no particular reason') do
23
23
  n = $fb.insert
@@ -35,7 +35,7 @@ Feature: Update
35
35
 
36
36
  Scenario: The update fails when a bug in a judge
37
37
  Given I make a temp directory
38
- Then I have a "mine/judge1/broken.rb" file with content:
38
+ Then I have a "mine/broken/broken.rb" file with content:
39
39
  """
40
40
  a < 1
41
41
  """
@@ -45,7 +45,7 @@ Feature: Update
45
45
 
46
46
  Scenario: The update fails when a broken Ruby syntax in a judge
47
47
  Given I make a temp directory
48
- Then I have a "mine/judge1/broken.rb" file with content:
48
+ Then I have a "mine/broken/broken.rb" file with content:
49
49
  """
50
50
  invalid$ruby$syntax$here
51
51
  """
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.20.0'
29
+ s.version = '0.22.0'
30
30
  s.license = 'MIT'
31
31
  s.summary = 'Command-Line Tool for a Factbase'
32
32
  s.description =
data/lib/judges/baza.rb CHANGED
@@ -38,7 +38,7 @@ require_relative '../judges/elapsed'
38
38
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
39
39
  # License:: MIT
40
40
  class Judges::Baza
41
- def initialize(host, port, token, ssl: true, timeout: 30, retries: 3, loog: Loog::NULL)
41
+ def initialize(host, port, token, ssl: true, timeout: 30, retries: 3, loog: Loog::NULL, compression: true)
42
42
  @host = host
43
43
  @port = port
44
44
  @ssl = ssl
@@ -46,6 +46,7 @@ class Judges::Baza
46
46
  @timeout = timeout
47
47
  @loog = loog
48
48
  @retries = retries
49
+ @compression = compression
49
50
  end
50
51
 
51
52
  # Push factbase to the server.
@@ -62,18 +63,22 @@ class Judges::Baza
62
63
  unless meta.empty?
63
64
  hdrs = hdrs.merge('X-Zerocracy-Meta' => meta.map { |v| Base64.encode64(v).gsub("\n", '') }.join(' '))
64
65
  end
66
+ params = {
67
+ connecttimeout: @timeout,
68
+ timeout: @timeout,
69
+ body: data,
70
+ headers: hdrs
71
+ }
65
72
  elapsed(@loog) do
66
- ret = with_retries(max_tries: @retries) do
67
- checked(
68
- Typhoeus::Request.put(
69
- home.append('push').append(name).to_s,
70
- body: data,
71
- headers: hdrs,
72
- connecttimeout: @timeout,
73
- timeout: @timeout
73
+ ret =
74
+ with_retries(max_tries: @retries) do
75
+ checked(
76
+ Typhoeus::Request.put(
77
+ home.append('push').append(name).to_s,
78
+ @compression ? zipped(params) : params
79
+ )
74
80
  )
75
- )
76
- end
81
+ end
77
82
  id = ret.body.to_i
78
83
  throw :"Pushed #{data.size} bytes to #{@host}, job ID is ##{id}"
79
84
  end
@@ -117,20 +122,63 @@ class Judges::Baza
117
122
  def finished?(id)
118
123
  finished = false
119
124
  elapsed(@loog) do
120
- ret = with_retries(max_tries: @retries) do
121
- checked(
122
- Typhoeus::Request.get(
123
- home.append('finished').append(id).to_s,
124
- headers:
125
+ ret =
126
+ with_retries(max_tries: @retries) do
127
+ checked(
128
+ Typhoeus::Request.get(
129
+ home.append('finished').append(id).to_s,
130
+ headers:
131
+ )
125
132
  )
126
- )
127
- end
133
+ end
128
134
  finished = ret.body == 'yes'
129
135
  throw :"The job ##{id} is #{finished ? '' : 'not yet '}finished at #{@host}"
130
136
  end
131
137
  finished
132
138
  end
133
139
 
140
+ # Read and return the stdout of the job.
141
+ # @param [Integer] id The ID of the job on the server
142
+ # @return [String] The stdout, as a text
143
+ def stdout(id)
144
+ stdout = ''
145
+ elapsed(@loog) do
146
+ ret =
147
+ with_retries(max_tries: @retries) do
148
+ checked(
149
+ Typhoeus::Request.get(
150
+ home.append('stdout').append(id).to_s,
151
+ headers:
152
+ )
153
+ )
154
+ end
155
+ ret.body
156
+ throw :"The stdout of the job ##{id} has #{stdout.split("\n")} lines"
157
+ end
158
+ stdout
159
+ end
160
+
161
+ # Read and return the exit code of the job.
162
+ # @param [Integer] id The ID of the job on the server
163
+ # @return [Integer] The exit code
164
+ def exit_code(id)
165
+ code = 0
166
+ elapsed(@loog) do
167
+ ret =
168
+ with_retries(max_tries: @retries) do
169
+ checked(
170
+ Typhoeus::Request.get(
171
+ home.append('exit').append(id).to_s,
172
+ headers:
173
+ )
174
+ )
175
+ end
176
+ code = ret.body.to_i
177
+ throw :"The exit code of the job ##{id} is #{code}"
178
+ end
179
+ code
180
+ end
181
+
134
182
  # Lock the name.
135
183
  # @param [String] name The name of the job on the server
136
184
  # @param [String] owner The owner of the lock (any string)
@@ -171,14 +219,15 @@ class Judges::Baza
171
219
  def recent(name)
172
220
  job = 0
173
221
  elapsed(@loog) do
174
- ret = with_retries(max_tries: @retries) do
175
- checked(
176
- Typhoeus::Request.get(
177
- home.append('recent').append("#{name}.txt").to_s,
178
- headers:
222
+ ret =
223
+ with_retries(max_tries: @retries) do
224
+ checked(
225
+ Typhoeus::Request.get(
226
+ home.append('recent').append("#{name}.txt").to_s,
227
+ headers:
228
+ )
179
229
  )
180
- )
181
- end
230
+ end
182
231
  job = ret.body.to_i
183
232
  throw :"The recent \"#{name}\" job's ID is ##{job} at #{@host}"
184
233
  end
@@ -191,14 +240,15 @@ class Judges::Baza
191
240
  def name_exists?(name)
192
241
  exists = 0
193
242
  elapsed(@loog) do
194
- ret = with_retries(max_tries: @retries) do
195
- checked(
196
- Typhoeus::Request.get(
197
- home.append('exists').append(name).to_s,
198
- headers:
243
+ ret =
244
+ with_retries(max_tries: @retries) do
245
+ checked(
246
+ Typhoeus::Request.get(
247
+ home.append('exists').append(name).to_s,
248
+ headers:
249
+ )
199
250
  )
200
- )
201
- end
251
+ end
202
252
  exists = ret.body == 'yes'
203
253
  throw :"The name \"#{name}\" #{exists ? 'exists' : "doesn't exist"} at #{@host}"
204
254
  end
@@ -215,6 +265,27 @@ class Judges::Baza
215
265
  }
216
266
  end
217
267
 
268
+ def zipped(params)
269
+ body = gzip(params.fetch(:body))
270
+ headers = params
271
+ .fetch(:headers)
272
+ .merge({
273
+ 'Content-Type' => 'application/zip',
274
+ 'Content-Encoding' => 'gzip',
275
+ 'Content-Length' => body.size
276
+ })
277
+ params.merge(body:, headers:)
278
+ end
279
+
280
+ def gzip(data)
281
+ ''.dup.tap do |result|
282
+ io = StringIO.new(result)
283
+ gz = Zlib::GzipWriter.new(io)
284
+ gz.write(data)
285
+ gz.close
286
+ end
287
+ end
288
+
218
289
  def home
219
290
  Iri.new('')
220
291
  .host(@host)