judges 0.22.1 → 0.23.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: cbef0d45d39354c46895af943ef6180bed47a28b4738bcca9755f9b66a282756
4
- data.tar.gz: 8dec5ca451e4499509f7158f9c1b115f301713d3e065becd53be78fc82e75c87
3
+ metadata.gz: e8e8b3c462c8c85767f611787af11de8c7966829c43866c31bab6626101e9762
4
+ data.tar.gz: 0c87fba4ce9a6f8c79149acecc07b3036804e2b51941fef4bf676ef1c2c79ef5
5
5
  SHA512:
6
- metadata.gz: 074313a259b93c9979a941231251335481cca8212ecea88df3a25d8c70eefed71b55064e11f48e9f63b2c3d8f15982d9647193515a4ec57a1b6120afdf302485
7
- data.tar.gz: 3b5628e0ae419cb8197ab4845165ddcde7de4e02bd6174ca6057dd76b3982475bc036d74a778dbca7f6c0b97f605a836e824d1fd1377d0e92a47212cde879db0
6
+ metadata.gz: 217b87a1d9154652a255377e1a8919e1841895aa6d3b86c1f2e24eb66cda198a931ad3fb91062962234bea707c0af90ceaf7c1da6eccd6cbc4af37de33f67379
7
+ data.tar.gz: f0dfac8980ba3588b52f0aa38175bba961b7f786d1d567878e394e901b644edeef99446ebab1e41af8ce3e29d49ff4e7727c1e017b35fba6e05e821735cb20c2
@@ -28,7 +28,7 @@ name: actionlint
28
28
  - master
29
29
  jobs:
30
30
  actionlint:
31
- runs-on: ubuntu-22.04
31
+ runs-on: ubuntu-24.04
32
32
  steps:
33
33
  - uses: actions/checkout@v4
34
34
  - name: Download actionlint
@@ -25,12 +25,12 @@ name: codecov
25
25
  - master
26
26
  jobs:
27
27
  codecov:
28
- runs-on: ubuntu-22.04
28
+ runs-on: ubuntu-24.04
29
29
  steps:
30
30
  - uses: actions/checkout@v4
31
31
  - uses: ruby/setup-ruby@v1
32
32
  with:
33
- ruby-version: 3.2
33
+ ruby-version: 3.3
34
34
  bundler-cache: true
35
35
  - run: bundle install
36
36
  - run: bundle exec rake
@@ -28,7 +28,7 @@ name: copyrights
28
28
  - master
29
29
  jobs:
30
30
  copyrights:
31
- runs-on: ubuntu-22.04
31
+ runs-on: ubuntu-24.04
32
32
  steps:
33
33
  - uses: actions/checkout@v4
34
34
  - uses: yegor256/copyrights-action@0.0.5
@@ -32,7 +32,7 @@ concurrency:
32
32
  cancel-in-progress: true
33
33
  jobs:
34
34
  markdown-lint:
35
- runs-on: ubuntu-22.04
35
+ runs-on: ubuntu-24.04
36
36
  steps:
37
37
  - uses: actions/checkout@v4
38
38
  - uses: articulate/actions-markdownlint@v1
@@ -28,7 +28,7 @@ on:
28
28
  - master
29
29
  jobs:
30
30
  pdd:
31
- runs-on: ubuntu-22.04
31
+ runs-on: ubuntu-24.04
32
32
  steps:
33
33
  - uses: actions/checkout@v4
34
34
  - uses: volodya-lombrozo/pdd-action@master
@@ -31,8 +31,8 @@ jobs:
31
31
  name: test
32
32
  strategy:
33
33
  matrix:
34
- os: [ubuntu-20.04, macos-12]
35
- ruby: [3.2]
34
+ os: [ubuntu-22.04, macos-12]
35
+ ruby: [3.3]
36
36
  runs-on: ${{ matrix.os }}
37
37
  steps:
38
38
  - uses: actions/checkout@v4
@@ -28,7 +28,7 @@ name: xcop
28
28
  - master
29
29
  jobs:
30
30
  xcop:
31
- runs-on: ubuntu-22.04
31
+ runs-on: ubuntu-24.04
32
32
  steps:
33
33
  - uses: actions/checkout@v4
34
34
  - uses: g4s8/xcop-action@master
@@ -28,7 +28,7 @@ name: yamllint
28
28
  - master
29
29
  jobs:
30
30
  yamllint:
31
- runs-on: ubuntu-22.04
31
+ runs-on: ubuntu-24.04
32
32
  steps:
33
33
  - uses: actions/checkout@v4
34
34
  - uses: ibiqlik/action-yamllint@v3
data/Gemfile CHANGED
@@ -32,7 +32,7 @@ gem 'random-port', '~>0.0', require: false
32
32
  gem 'rspec-rails', '6.1.3', require: false
33
33
  gem 'rubocop', '1.65.1', require: false
34
34
  gem 'rubocop-performance', '1.21.1', require: false
35
- gem 'rubocop-rspec', '3.0.3', require: false
35
+ gem 'rubocop-rspec', '3.0.4', require: false
36
36
  gem 'simplecov', '0.22.0', require: false
37
37
  gem 'simplecov-cobertura', '2.1.0', require: false
38
38
  gem 'webmock', '3.23.1', require: false
data/Gemfile.lock CHANGED
@@ -3,6 +3,7 @@ PATH
3
3
  specs:
4
4
  judges (0.0.0)
5
5
  backtrace (~> 0)
6
+ baza.rb (~> 0)
6
7
  concurrent-ruby (~> 1.2)
7
8
  factbase (~> 0)
8
9
  gli (~> 2.21)
@@ -50,6 +51,16 @@ GEM
50
51
  ast (2.4.2)
51
52
  backtrace (0.4.0)
52
53
  base64 (0.2.0)
54
+ baza.rb (0.0.1)
55
+ backtrace (> 0)
56
+ faraday (> 0)
57
+ faraday-http-cache (> 0)
58
+ faraday-multipart (> 0)
59
+ faraday-retry (> 0)
60
+ iri (> 0)
61
+ loog (> 0)
62
+ retries (~> 0)
63
+ typhoeus (~> 1.3)
53
64
  bigdecimal (3.1.8)
54
65
  builder (3.3.0)
55
66
  concurrent-ruby (1.3.3)
@@ -79,7 +90,7 @@ GEM
79
90
  bigdecimal
80
91
  cucumber-gherkin (27.0.0)
81
92
  cucumber-messages (>= 19.1.4, < 23)
82
- cucumber-html-formatter (21.5.0)
93
+ cucumber-html-formatter (21.6.0)
83
94
  cucumber-messages (> 19, < 25)
84
95
  cucumber-messages (22.0.0)
85
96
  cucumber-tag-expressions (6.1.0)
@@ -90,7 +101,7 @@ GEM
90
101
  erubi (1.13.0)
91
102
  ethon (0.16.0)
92
103
  ffi (>= 1.15.0)
93
- factbase (0.2.1)
104
+ factbase (0.3.0)
94
105
  backtrace (> 0)
95
106
  decoor (> 0)
96
107
  json (~> 2.7)
@@ -99,6 +110,17 @@ GEM
99
110
  others (> 0)
100
111
  tago (> 0)
101
112
  yaml (~> 0.3)
113
+ faraday (2.10.1)
114
+ faraday-net_http (>= 2.0, < 3.2)
115
+ logger
116
+ faraday-http-cache (2.5.1)
117
+ faraday (>= 0.8)
118
+ faraday-multipart (1.0.4)
119
+ multipart-post (~> 2)
120
+ faraday-net_http (3.1.1)
121
+ net-http
122
+ faraday-retry (2.2.1)
123
+ faraday (~> 2.0)
102
124
  ffi (1.17.0-aarch64-linux-gnu)
103
125
  ffi (1.17.0-arm-linux-gnu)
104
126
  ffi (1.17.0-arm64-darwin)
@@ -117,6 +139,7 @@ GEM
117
139
  iri (0.8.0)
118
140
  json (2.7.2)
119
141
  language_server-protocol (3.17.0.3)
142
+ logger (1.6.0)
120
143
  loofah (2.22.0)
121
144
  crass (~> 1.0.2)
122
145
  nokogiri (>= 1.12.0)
@@ -130,7 +153,10 @@ GEM
130
153
  ruby-progressbar
131
154
  moments (0.3.0)
132
155
  multi_test (1.1.0)
156
+ multipart-post (2.4.1)
133
157
  mutex_m (0.2.0)
158
+ net-http (0.4.1)
159
+ uri
134
160
  net-ping (2.0.8)
135
161
  nokogiri (1.16.7-aarch64-linux)
136
162
  racc (~> 1.4)
@@ -147,8 +173,8 @@ GEM
147
173
  nokogiri (1.16.7-x86_64-linux)
148
174
  racc (~> 1.4)
149
175
  others (0.0.3)
150
- parallel (1.25.1)
151
- parser (3.3.4.0)
176
+ parallel (1.26.1)
177
+ parser (3.3.4.2)
152
178
  ast (~> 2.4.1)
153
179
  racc
154
180
  psych (5.1.2)
@@ -217,12 +243,12 @@ GEM
217
243
  rubocop-ast (>= 1.31.1, < 2.0)
218
244
  ruby-progressbar (~> 1.7)
219
245
  unicode-display_width (>= 2.4.0, < 3.0)
220
- rubocop-ast (1.31.3)
246
+ rubocop-ast (1.32.0)
221
247
  parser (>= 3.3.1.0)
222
248
  rubocop-performance (1.21.1)
223
249
  rubocop (>= 1.48.1, < 2.0)
224
250
  rubocop-ast (>= 1.31.1, < 2.0)
225
- rubocop-rspec (3.0.3)
251
+ rubocop-rspec (3.0.4)
226
252
  rubocop (~> 1.61)
227
253
  ruby-progressbar (1.13.0)
228
254
  simplecov (0.22.0)
@@ -245,6 +271,7 @@ GEM
245
271
  tzinfo (2.0.6)
246
272
  concurrent-ruby (~> 1.0)
247
273
  unicode-display_width (2.5.0)
274
+ uri (0.13.0)
248
275
  webmock (3.23.1)
249
276
  addressable (>= 2.8.0)
250
277
  crack (>= 0.3.2)
@@ -274,7 +301,7 @@ DEPENDENCIES
274
301
  rspec-rails (= 6.1.3)
275
302
  rubocop (= 1.65.1)
276
303
  rubocop-performance (= 1.21.1)
277
- rubocop-rspec (= 3.0.3)
304
+ rubocop-rspec (= 3.0.4)
278
305
  simplecov (= 0.22.0)
279
306
  simplecov-cobertura (= 2.1.0)
280
307
  webmock (= 3.23.1)
data/assets/index.xsl CHANGED
@@ -22,7 +22,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
22
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
23
  SOFTWARE.
24
24
  -->
25
- <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
25
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
26
26
  <xsl:output method="xml" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes"/>
27
27
  <xsl:param name="title"/>
28
28
  <xsl:param name="date"/>
@@ -65,13 +65,15 @@ SOFTWARE.
65
65
  section { width: 100%; }
66
66
  article { border: none; }
67
67
  header img { width: 3em; height: 3em; }
68
+ table { table-layout: fixed; }
69
+ td { word-wrap: break-word; }
68
70
  .sorter { cursor: pointer; }
69
- .S { color: #196F3D; }
71
+ .S { color: #4A5240; }
70
72
  .T { color: #2471A3; }
71
- .I { color: #212F3C; }
72
- .F { color: #E74C3C; }
73
- .BR { color: gray; }
74
- .hidden { color: gray; }
73
+ .I { color: #61304B; }
74
+ .F { color: #5C0029; }
75
+ .BR { color: #B6C649; }
76
+ .hidden { color: #C1C1C1; }
75
77
  </style>
76
78
  <script type="text/javascript">
77
79
  $(function() {
@@ -131,6 +133,11 @@ SOFTWARE.
131
133
  </xsl:template>
132
134
  <xsl:template match="fb">
133
135
  <table id="facts">
136
+ <colgroup>
137
+ <xsl:call-template name="col">
138
+ <xsl:with-param name="cols" select="$columns"/>
139
+ </xsl:call-template>
140
+ </colgroup>
134
141
  <thead>
135
142
  <tr>
136
143
  <xsl:call-template name="th">
@@ -151,6 +158,20 @@ SOFTWARE.
151
158
  </xsl:call-template>
152
159
  </tr>
153
160
  </xsl:template>
161
+ <xsl:template name="col">
162
+ <xsl:param name="cols"/>
163
+ <xsl:choose>
164
+ <xsl:when test="string-length($cols) &gt; 0">
165
+ <col style="width: 10em;"/>
166
+ <xsl:call-template name="col">
167
+ <xsl:with-param name="cols" select="substring-after($cols, ',')"/>
168
+ </xsl:call-template>
169
+ </xsl:when>
170
+ <xsl:otherwise>
171
+ <col style=""/>
172
+ </xsl:otherwise>
173
+ </xsl:choose>
174
+ </xsl:template>
154
175
  <xsl:template name="th">
155
176
  <xsl:param name="cols"/>
156
177
  <xsl:choose>
@@ -190,7 +211,7 @@ SOFTWARE.
190
211
  <xsl:for-each select="$f/*">
191
212
  <xsl:text> </xsl:text>
192
213
  <xsl:variable name="visible" select="string-length(substring-before(concat(' ,', $hidden, ','), concat(',', name(), ','))) = 0"/>
193
- <xsl:if test="string-length(substring-before(concat(',', $columns, ','), concat(',', name(), ','))) = 0">
214
+ <xsl:if test="string-length(substring-before(concat(' ,', $columns, ','), concat(',', name(), ','))) = 0">
194
215
  <xsl:choose>
195
216
  <xsl:when test="$visible">
196
217
  <xsl:value-of select="name()"/>
@@ -233,28 +254,9 @@ SOFTWARE.
233
254
  <xsl:attribute name="class">
234
255
  <xsl:value-of select="$v/@t"/>
235
256
  </xsl:attribute>
236
- <xsl:call-template name="just-value">
237
- <xsl:with-param name="v" select="$v"/>
238
- </xsl:call-template>
239
- </span>
240
- </xsl:otherwise>
241
- </xsl:choose>
242
- </xsl:template>
243
- <xsl:template name="just-value">
244
- <xsl:param name="v"/>
245
- <xsl:choose>
246
- <xsl:when test="string-length($v) &gt; 64">
247
- <xsl:value-of select="substring($v, 0, 64)"/>
248
- <span class="BR">
249
- <xsl:text>-</xsl:text>
257
+ <xsl:value-of select="$v"/>
250
258
  </span>
251
- <xsl:call-template name="just-value">
252
- <xsl:with-param name="v" select="substring($v, 64)"/>
253
- </xsl:call-template>
254
- </xsl:when>
255
- <xsl:otherwise>
256
- <xsl:value-of select="$v"/>
257
259
  </xsl:otherwise>
258
260
  </xsl:choose>
259
261
  </xsl:template>
260
- </xsl:stylesheet>
262
+ </xsl:stylesheet>
data/bin/judges CHANGED
@@ -155,7 +155,7 @@ class JudgesGLI extend GLI::App
155
155
  c.desc 'Authentication token'
156
156
  c.flag([:token])
157
157
  c.desc 'The IP/hostname of the server'
158
- c.flag([:host], default_value: 'www.zerocracy.com')
158
+ c.flag([:host], default_value: 'api.zerocracy.com')
159
159
  c.desc 'The TCP port number of the server'
160
160
  c.flag([:port], default_value: 443, type: Integer)
161
161
  c.desc 'Connection and read time in seconds'
@@ -180,7 +180,7 @@ class JudgesGLI extend GLI::App
180
180
  c.desc 'How many seconds to wait'
181
181
  c.flag([:wait], default_value: 10 * 60, arg_name: '<seconds>', type: Integer)
182
182
  c.desc 'The IP/hostname of the server'
183
- c.flag([:host], default_value: 'www.zerocracy.com')
183
+ c.flag([:host], default_value: 'api.zerocracy.com')
184
184
  c.desc 'The TCP port number of the server'
185
185
  c.flag([:port], default_value: 443, type: Integer)
186
186
  c.desc 'Connection and read time in seconds'
@@ -5,6 +5,6 @@ Feature: Pull
5
5
  Given We are online
6
6
  Given I make a temp directory
7
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"
8
+ Then Stdout contains "doesn't exist at api.zerocracy.com"
9
9
  And Exit code is zero
10
10
 
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.22.1'
29
+ s.version = '0.23.0'
30
30
  s.license = 'MIT'
31
31
  s.summary = 'Command-Line Tool for a Factbase'
32
32
  s.description =
@@ -43,6 +43,7 @@ Gem::Specification.new do |s|
43
43
  s.rdoc_options = ['--charset=UTF-8']
44
44
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
45
45
  s.add_dependency 'backtrace', '~>0'
46
+ s.add_dependency 'baza.rb', '~>0'
46
47
  s.add_dependency 'concurrent-ruby', '~>1.2'
47
48
  s.add_dependency 'factbase', '~>0'
48
49
  s.add_dependency 'gli', '~>2.21'
@@ -22,9 +22,9 @@
22
22
 
23
23
  require 'typhoeus'
24
24
  require 'iri'
25
+ require 'baza'
25
26
  require_relative '../../judges'
26
27
  require_relative '../../judges/impex'
27
- require_relative '../../judges/baza'
28
28
 
29
29
  # The +pull+ command.
30
30
  #
@@ -42,7 +42,7 @@ class Judges::Pull
42
42
  def run(opts, args)
43
43
  raise 'Exactly two arguments required' unless args.size == 2
44
44
  fb = Factbase.new
45
- baza = Judges::Baza.new(
45
+ baza = Baza.new(
46
46
  opts['host'], opts['port'].to_i, opts['token'],
47
47
  ssl: opts['ssl'],
48
48
  timeout: (opts['timeout'] || 30).to_i,
@@ -22,9 +22,9 @@
22
22
 
23
23
  require 'typhoeus'
24
24
  require 'iri'
25
+ require 'baza'
25
26
  require_relative '../../judges'
26
27
  require_relative '../../judges/impex'
27
- require_relative '../../judges/baza'
28
28
 
29
29
  # The +push+ command.
30
30
  #
@@ -43,7 +43,7 @@ class Judges::Push
43
43
  raise 'Exactly two arguments required' unless args.size == 2
44
44
  name = args[0]
45
45
  fb = Judges::Impex.new(@loog, args[1]).import
46
- baza = Judges::Baza.new(
46
+ baza = Baza.new(
47
47
  opts['host'], opts['port'].to_i, opts['token'],
48
48
  ssl: opts['ssl'],
49
49
  timeout: (opts['timeout'] || 30).to_i,
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.22.1'
28
+ VERSION = '0.23.0'
29
29
  end
@@ -24,6 +24,7 @@ require 'minitest/autorun'
24
24
  require 'loog'
25
25
  require 'factbase'
26
26
  require 'yaml'
27
+ require 'fileutils'
27
28
  require 'securerandom'
28
29
  require_relative '../../lib/judges'
29
30
  require_relative '../../lib/judges/commands/print'
@@ -56,14 +57,17 @@ class TestPrint < Minitest::Test
56
57
  f.details = 'hey, друг'
57
58
  f.ticket = 42
58
59
  f.ticket = 55
60
+ f.pi = 3.1416
59
61
  f.long_property = 'test_' * 100
60
62
  end
63
+ html = File.join(__dir__, '../../temp/base.html')
64
+ FileUtils.rm_f(html)
61
65
  Dir.mktmpdir do |d|
62
66
  f = File.join(d, 'base.fb')
63
67
  File.binwrite(f, fb.export)
64
68
  Judges::Print.new(Loog::NULL).run(
65
69
  { 'format' => 'html', 'columns' => 'what,when,ticket' },
66
- [f, File.join(__dir__, '../../temp/base.html')]
70
+ [f, html]
67
71
  )
68
72
  end
69
73
  end
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.22.1
4
+ version: 0.23.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-08-05 00:00:00.000000000 Z
11
+ date: 2024-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: baza.rb
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: concurrent-ruby
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -231,7 +245,6 @@ files:
231
245
  - fixtures/try/try.rb
232
246
  - judges.gemspec
233
247
  - lib/judges.rb
234
- - lib/judges/baza.rb
235
248
  - lib/judges/categories.rb
236
249
  - lib/judges/churn.rb
237
250
  - lib/judges/commands/eval.rb
@@ -262,7 +275,6 @@ files:
262
275
  - test/commands/test_trim.rb
263
276
  - test/commands/test_update.rb
264
277
  - test/test__helper.rb
265
- - test/test_baza.rb
266
278
  - test/test_bin.rb
267
279
  - test/test_categories.rb
268
280
  - test/test_churn.rb
data/lib/judges/baza.rb DELETED
@@ -1,327 +0,0 @@
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 'retries'
25
- require 'iri'
26
- require 'loog'
27
- require 'base64'
28
- require_relative '../judges'
29
- require_relative '../judges/elapsed'
30
-
31
- # Interface to the API of zerocracy.com.
32
- #
33
- # You make an instance of this class and then call one of its methods.
34
- # The object will make HTTP request to www.zerocracy.com and interpret the
35
- # results returned.
36
- #
37
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
38
- # Copyright:: Copyright (c) 2024 Yegor Bugayenko
39
- # License:: MIT
40
- class Judges::Baza
41
- def initialize(host, port, token, ssl: true, timeout: 30, retries: 3, loog: Loog::NULL, compression: true)
42
- @host = host
43
- @port = port
44
- @ssl = ssl
45
- @token = token
46
- @timeout = timeout
47
- @loog = loog
48
- @retries = retries
49
- @compression = compression
50
- end
51
-
52
- # Push factbase to the server.
53
- # @param [String] name The name of the job on the server
54
- # @param [Bytes] data The data to push to the server (binary)
55
- # @param [Array<String>] meta List of metas, possibly empty
56
- # @return [Integer] Job ID on the server
57
- def push(name, data, meta)
58
- id = 0
59
- hdrs = headers.merge(
60
- 'Content-Type' => 'application/octet-stream',
61
- 'Content-Length' => data.size
62
- )
63
- unless meta.empty?
64
- hdrs = hdrs.merge('X-Zerocracy-Meta' => meta.map { |v| Base64.encode64(v).gsub("\n", '') }.join(' '))
65
- end
66
- params = {
67
- connecttimeout: @timeout,
68
- timeout: @timeout,
69
- body: data,
70
- headers: hdrs
71
- }
72
- elapsed(@loog) do
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
- )
80
- )
81
- end
82
- id = ret.body.to_i
83
- throw :"Pushed #{data.size} bytes to #{@host}, job ID is ##{id}"
84
- end
85
- id
86
- end
87
-
88
- # Pull factbase from the server.
89
- # @param [Integer] id The ID of the job on the server
90
- # @return [Bytes] Binary data pulled
91
- def pull(id)
92
- data = 0
93
- elapsed(@loog) do
94
- Tempfile.open do |file|
95
- File.open(file, 'wb') do |f|
96
- request = Typhoeus::Request.new(
97
- home.append('pull').append("#{id}.fb").to_s,
98
- headers: headers.merge(
99
- 'Accept' => 'application/octet-stream'
100
- ),
101
- connecttimeout: @timeout,
102
- timeout: @timeout
103
- )
104
- request.on_body do |chunk|
105
- f.write(chunk)
106
- end
107
- with_retries(max_tries: @retries) do
108
- request.run
109
- end
110
- checked(request.response)
111
- end
112
- data = File.binread(file)
113
- throw :"Pulled #{data.size} bytes of job ##{id} factbase at #{@host}"
114
- end
115
- end
116
- data
117
- end
118
-
119
- # The job with this ID is finished already?
120
- # @param [Integer] id The ID of the job on the server
121
- # @return [Boolean] TRUE if the job is already finished
122
- def finished?(id)
123
- finished = false
124
- elapsed(@loog) do
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
- )
132
- )
133
- end
134
- finished = ret.body == 'yes'
135
- throw :"The job ##{id} is #{finished ? '' : 'not yet '}finished at #{@host}"
136
- end
137
- finished
138
- end
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}.txt").to_s,
151
- headers:
152
- )
153
- )
154
- end
155
- stdout = 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}.txt").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
-
182
- # Lock the name.
183
- # @param [String] name The name of the job on the server
184
- # @param [String] owner The owner of the lock (any string)
185
- def lock(name, owner)
186
- elapsed(@loog) do
187
- with_retries(max_tries: @retries) do
188
- checked(
189
- Typhoeus::Request.get(
190
- home.append('lock').append(name).add(owner:).to_s,
191
- headers:
192
- ),
193
- 302
194
- )
195
- end
196
- end
197
- end
198
-
199
- # Unlock the name.
200
- # @param [String] name The name of the job on the server
201
- # @param [String] owner The owner of the lock (any string)
202
- def unlock(name, owner)
203
- elapsed(@loog) do
204
- with_retries(max_tries: @retries) do
205
- checked(
206
- Typhoeus::Request.get(
207
- home.append('unlock').append(name).add(owner:).to_s,
208
- headers:
209
- ),
210
- 302
211
- )
212
- end
213
- end
214
- end
215
-
216
- # Get the ID of the job by the name.
217
- # @param [String] name The name of the job on the server
218
- # @return [Integer] The ID of the job on the server
219
- def recent(name)
220
- job = 0
221
- elapsed(@loog) do
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
- )
229
- )
230
- end
231
- job = ret.body.to_i
232
- throw :"The recent \"#{name}\" job's ID is ##{job} at #{@host}"
233
- end
234
- job
235
- end
236
-
237
- # Check whether the name of the job exists on the server.
238
- # @param [String] name The name of the job on the server
239
- # @return [Boolean] TRUE if such name exists
240
- def name_exists?(name)
241
- exists = 0
242
- elapsed(@loog) do
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
- )
250
- )
251
- end
252
- exists = ret.body == 'yes'
253
- throw :"The name \"#{name}\" #{exists ? 'exists' : "doesn't exist"} at #{@host}"
254
- end
255
- exists
256
- end
257
-
258
- private
259
-
260
- def headers
261
- {
262
- 'User-Agent' => "judges #{Judges::VERSION}",
263
- 'Connection' => 'close',
264
- 'X-Zerocracy-Token' => @token
265
- }
266
- end
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
-
289
- def home
290
- Iri.new('')
291
- .host(@host)
292
- .port(@port)
293
- .scheme(@ssl ? 'https' : 'http')
294
- end
295
-
296
- def checked(ret, allowed = [200])
297
- allowed = [allowed] unless allowed.is_a?(Array)
298
- mtd = (ret.request.original_options[:method] || '???').upcase
299
- url = ret.effective_url
300
- log = "#{mtd} #{url} -> #{ret.code}"
301
- if allowed.include?(ret.code)
302
- @loog.debug(log)
303
- return ret
304
- end
305
- @loog.debug("#{log}\n #{(ret.headers || {}).map { |k, v| "#{k}: #{v}" }.join("\n ")}")
306
- msg =
307
- "Invalid response code ##{ret.code} " \
308
- "at #{mtd} #{url} (#{ret.headers['X-Zerocracy-Flash'].inspect})"
309
- case ret.code
310
- when 500
311
- msg +=
312
- ', most probably it\'s an internal error on the server, ' \
313
- 'please report this to https://github.com/zerocracy/baza'
314
- when 503
315
- msg +=
316
- ", most probably it's an internal error on the server (#{ret.headers['X-Zerocracy-Failure'].inspect}), " \
317
- 'please report this to https://github.com/yegor256/judges'
318
- when 404
319
- msg +=
320
- ', most probably you are trying to reach a wrong server, which doesn\'t ' \
321
- 'have the URL that it is expected to have'
322
- when 0
323
- msg += ', most likely an internal error'
324
- end
325
- raise msg
326
- end
327
- end
data/test/test_baza.rb DELETED
@@ -1,175 +0,0 @@
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 'minitest/autorun'
24
- require 'webmock/minitest'
25
- require 'webrick'
26
- require 'loog'
27
- require 'socket'
28
- require 'stringio'
29
- require 'random-port'
30
- require_relative '../lib/judges'
31
- require_relative '../lib/judges/baza'
32
-
33
- # Test.
34
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
35
- # Copyright:: Copyright (c) 2024 Yegor Bugayenko
36
- # License:: MIT
37
- class TestBaza < Minitest::Test
38
- def test_simple_push
39
- WebMock.disable_net_connect!
40
- stub_request(:put, 'https://example.org/push/simple').to_return(
41
- status: 200, body: '42'
42
- )
43
- assert_equal(
44
- 42,
45
- Judges::Baza.new('example.org', 443, '000').push('simple', 'hello, world!', [])
46
- )
47
- end
48
-
49
- def test_simple_recent_check
50
- WebMock.disable_net_connect!
51
- stub_request(:get, 'https://example.org/recent/simple.txt')
52
- .with(body: '', headers: { 'User-Agent' => /^judges .*$/ })
53
- .to_return(status: 200, body: '42')
54
- assert_equal(
55
- 42,
56
- Judges::Baza.new('example.org', 443, '000').recent('simple')
57
- )
58
- end
59
-
60
- def test_simple_exists_check
61
- WebMock.disable_net_connect!
62
- stub_request(:get, 'https://example.org/exists/simple').to_return(
63
- status: 200, body: 'yes'
64
- )
65
- assert(
66
- Judges::Baza.new('example.org', 443, '000').name_exists?('simple')
67
- )
68
- end
69
-
70
- def test_exit_code_check
71
- WebMock.disable_net_connect!
72
- stub_request(:get, 'https://example.org/exit/42.txt').to_return(
73
- status: 200, body: '0'
74
- )
75
- assert(
76
- Judges::Baza.new('example.org', 443, '000').exit_code(42).zero?
77
- )
78
- end
79
-
80
- def test_stdout_read
81
- WebMock.disable_net_connect!
82
- stub_request(:get, 'https://example.org/stdout/42.txt').to_return(
83
- status: 200, body: 'hello!'
84
- )
85
- assert(
86
- !Judges::Baza.new('example.org', 443, '000').stdout(42).empty?
87
- )
88
- end
89
-
90
- def test_simple_pull
91
- WebMock.disable_net_connect!
92
- stub_request(:get, 'https://example.org/pull/333.fb').to_return(
93
- status: 200, body: 'hello, world!'
94
- )
95
- assert(
96
- Judges::Baza.new('example.org', 443, '000').pull(333).start_with?('hello')
97
- )
98
- end
99
-
100
- def test_real_http
101
- req =
102
- with_http_server(200, 'yes') do |baza|
103
- baza.name_exists?('simple')
104
- end
105
- assert_equal("judges #{Judges::VERSION}", req['user-agent'])
106
- end
107
-
108
- def test_push_with_meta
109
- req =
110
- with_http_server(200, 'yes') do |baza|
111
- baza.push('simple', 'hello, world!', ['boom!', 'хей!'])
112
- end
113
- assert_equal('Ym9vbSE= 0YXQtdC5IQ==', req['x-zerocracy-meta'])
114
- end
115
-
116
- def test_push_with_big_meta
117
- req =
118
- with_http_server(200, 'yes') do |baza|
119
- baza.push(
120
- 'simple',
121
- 'hello, world!',
122
- [
123
- 'pages_url:https://zerocracy.github.io/zerocracy.html',
124
- 'others:https://zerocracy.github.io/zerocracy.html',
125
- 'duration:59595'
126
- ]
127
- )
128
- end
129
- assert(req['x-zerocracy-meta'])
130
- end
131
-
132
- def test_push_compressed_content
133
- skip # this test is not stable, see https://github.com/yegor256/judges/issues/105
134
- req =
135
- with_http_server(200, 'yes') do |baza|
136
- baza.push('simple', 'hello, world!', %w[meta1 meta2 meta3])
137
- end
138
- assert_equal('application/zip', req.content_type)
139
- assert_equal('gzip', req['content-encoding'])
140
- body = Zlib::GzipReader.zcat(StringIO.new(req.body))
141
- assert_equal('hello, world!', body)
142
- end
143
-
144
- def test_push_compression_disabled
145
- req =
146
- with_http_server(200, 'yes', compression: false) do |baza|
147
- baza.push('simple', 'hello, world!', %w[meta1 meta2 meta3])
148
- end
149
- assert_equal('application/octet-stream', req.content_type)
150
- assert_equal('hello, world!', req.body)
151
- end
152
-
153
- private
154
-
155
- def with_http_server(code, response, opts = {})
156
- opts = { ssl: false, timeout: 1 }.merge(opts)
157
- WebMock.enable_net_connect!
158
- req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
159
- host = '127.0.0.1'
160
- RandomPort::Pool::SINGLETON.acquire do |port|
161
- server = TCPServer.new(host, port)
162
- t =
163
- Thread.new do
164
- socket = server.accept
165
- req.parse(socket)
166
- req.body
167
- socket.puts "HTTP/1.1 #{code} OK\r\nContent-Length: #{response.length}\r\n\r\n#{response}"
168
- socket.close
169
- end
170
- yield Judges::Baza.new(host, port, '0000', **opts)
171
- t.join
172
- end
173
- req
174
- end
175
- end