judges 0.11.0 → 0.13.0
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 +4 -4
- data/Gemfile.lock +3 -3
- data/bin/judges +6 -0
- data/judges.gemspec +2 -2
- data/lib/judges/baza.rb +30 -0
- data/lib/judges/churn.rb +14 -8
- data/lib/judges/commands/pull.rb +1 -0
- data/lib/judges/commands/push.rb +2 -0
- data/lib/judges/commands/update.rb +17 -7
- data/lib/judges.rb +1 -1
- data/test/commands/test_pull.rb +3 -1
- data/test/commands/test_push.rb +7 -2
- data/test/commands/test_update.rb +20 -1
- data/test/test_churn.rb +8 -0
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '098f6126af6c35b9ee74dca41bbfb5b8e6b1357aee5dcec215a2819929e859d5'
|
|
4
|
+
data.tar.gz: 139a4b55ea82a090e385c4f54be682dd74d0922c66d77824c8d33cecaa799a84
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0e173739bc5341c55f869375fef959ff9e6ca57c1e0b814a29d4920700f640fc788a948932221c9fbf6f9e7d9d90501e274645f3de213b7f9b3211549652ad1c
|
|
7
|
+
data.tar.gz: 52f4c44351e5f3c9efb873913f26c8a7c2c5c08dbf490434145cc691968eec240ef95bb5007568b623c043f48ab658624a573664598df587282cb1cfb43ef94b
|
data/Gemfile.lock
CHANGED
|
@@ -3,7 +3,7 @@ PATH
|
|
|
3
3
|
specs:
|
|
4
4
|
judges (0.0.0)
|
|
5
5
|
backtrace (~> 0.3)
|
|
6
|
-
concurrent-ruby (
|
|
6
|
+
concurrent-ruby (~> 1.2)
|
|
7
7
|
factbase (~> 0.0)
|
|
8
8
|
gli (~> 2.21)
|
|
9
9
|
iri (~> 0.8)
|
|
@@ -51,7 +51,7 @@ GEM
|
|
|
51
51
|
base64 (0.2.0)
|
|
52
52
|
bigdecimal (3.1.8)
|
|
53
53
|
builder (3.3.0)
|
|
54
|
-
concurrent-ruby (1.
|
|
54
|
+
concurrent-ruby (1.3.3)
|
|
55
55
|
connection_pool (2.4.1)
|
|
56
56
|
crack (1.0.0)
|
|
57
57
|
bigdecimal
|
|
@@ -180,7 +180,7 @@ GEM
|
|
|
180
180
|
reline (0.5.9)
|
|
181
181
|
io-console (~> 0.5)
|
|
182
182
|
retries (0.0.5)
|
|
183
|
-
rexml (3.3.
|
|
183
|
+
rexml (3.3.1)
|
|
184
184
|
strscan
|
|
185
185
|
rspec-core (3.13.0)
|
|
186
186
|
rspec-support (~> 3.13.0)
|
data/bin/judges
CHANGED
|
@@ -65,6 +65,8 @@ class App
|
|
|
65
65
|
c.flag([:'max-cycles'], default_value: 8, type: Integer)
|
|
66
66
|
c.desc 'Stay quiet even if some judges fail'
|
|
67
67
|
c.switch([:q, :quiet], default_value: false)
|
|
68
|
+
c.desc 'Place a summarization fact into the factbase'
|
|
69
|
+
c.switch([:summary], default_value: false)
|
|
68
70
|
c.desc 'Use default logging facility'
|
|
69
71
|
c.switch([:log], default_value: true)
|
|
70
72
|
c.action do |global, options, args|
|
|
@@ -167,6 +169,8 @@ class App
|
|
|
167
169
|
c.flag([:timeout], default_value: 30, type: Integer)
|
|
168
170
|
c.desc 'Shall SSL be used?'
|
|
169
171
|
c.switch([:ssl], default_value: true)
|
|
172
|
+
c.desc 'A unique name to use for a lock/unlock'
|
|
173
|
+
c.flag([:owner], default_value: 'default', type: String)
|
|
170
174
|
c.action do |global, options, args|
|
|
171
175
|
require_relative '../lib/judges/commands/push'
|
|
172
176
|
Judges::Push.new(loog).run(options, args)
|
|
@@ -187,6 +191,8 @@ class App
|
|
|
187
191
|
c.flag([:timeout], default_value: 30, type: Integer)
|
|
188
192
|
c.desc 'Shall SSL be used?'
|
|
189
193
|
c.switch([:ssl], default_value: true)
|
|
194
|
+
c.desc 'A unique name to use for a lock/unlock'
|
|
195
|
+
c.flag([:owner], default_value: 'default', type: String)
|
|
190
196
|
c.action do |global, options, args|
|
|
191
197
|
require_relative '../lib/judges/commands/pull'
|
|
192
198
|
Judges::Pull.new(loog).run(options, args)
|
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.
|
|
29
|
+
s.version = '0.13.0'
|
|
30
30
|
s.license = 'MIT'
|
|
31
31
|
s.summary = 'Command-Line Tool for a Factbase'
|
|
32
32
|
s.description =
|
|
@@ -43,7 +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_runtime_dependency 'backtrace', '~>0.3'
|
|
46
|
-
s.add_runtime_dependency 'concurrent-ruby', '1.2
|
|
46
|
+
s.add_runtime_dependency 'concurrent-ruby', '~>1.2'
|
|
47
47
|
s.add_runtime_dependency 'factbase', '~>0.0'
|
|
48
48
|
s.add_runtime_dependency 'gli', '~>2.21'
|
|
49
49
|
s.add_runtime_dependency 'iri', '~>0.8'
|
data/lib/judges/baza.rb
CHANGED
|
@@ -110,6 +110,36 @@ class Judges::Baza
|
|
|
110
110
|
finished
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
+
# Lock the name.
|
|
114
|
+
def lock(name, owner)
|
|
115
|
+
elapsed(@loog) do
|
|
116
|
+
with_retries do
|
|
117
|
+
checked(
|
|
118
|
+
Typhoeus::Request.get(
|
|
119
|
+
home.append('lock').append(name).add(owner:).to_s,
|
|
120
|
+
headers:
|
|
121
|
+
),
|
|
122
|
+
302
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Unlock the name.
|
|
129
|
+
def unlock(name, owner)
|
|
130
|
+
elapsed(@loog) do
|
|
131
|
+
with_retries do
|
|
132
|
+
checked(
|
|
133
|
+
Typhoeus::Request.get(
|
|
134
|
+
home.append('unlock').append(name).add(owner:).to_s,
|
|
135
|
+
headers:
|
|
136
|
+
),
|
|
137
|
+
302
|
|
138
|
+
)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
113
143
|
def recent(name)
|
|
114
144
|
job = 0
|
|
115
145
|
elapsed(@loog) do
|
data/lib/judges/churn.rb
CHANGED
|
@@ -27,34 +27,40 @@ require_relative '../judges'
|
|
|
27
27
|
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
|
28
28
|
# License:: MIT
|
|
29
29
|
class Judges::Churn
|
|
30
|
-
attr_reader :added, :removed
|
|
30
|
+
attr_reader :added, :removed, :errors
|
|
31
31
|
|
|
32
|
-
def initialize(added, removed)
|
|
32
|
+
def initialize(added, removed, errors = [])
|
|
33
33
|
@added = added
|
|
34
34
|
@removed = removed
|
|
35
|
+
@errors = errors
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def to_s
|
|
38
|
-
"#{@added}/#{@removed}"
|
|
39
|
+
"#{@added}/#{@removed}#{@errors.empty? ? '' : "/#{@errors.size}"}"
|
|
39
40
|
end
|
|
40
41
|
|
|
41
42
|
def zero?
|
|
42
|
-
@added.zero? && @removed.zero?
|
|
43
|
+
@added.zero? && @removed.zero? && @errors.empty?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def <<(error)
|
|
47
|
+
@errors << error
|
|
48
|
+
nil
|
|
43
49
|
end
|
|
44
50
|
|
|
45
51
|
def +(other)
|
|
46
52
|
if other.is_a?(Judges::Churn)
|
|
47
|
-
Judges::Churn.new(@added + other.added, @removed + other.removed)
|
|
53
|
+
Judges::Churn.new(@added + other.added, @removed + other.removed, @errors + other.errors)
|
|
48
54
|
else
|
|
49
|
-
Judges::Churn.new(@added + other, @removed)
|
|
55
|
+
Judges::Churn.new(@added + other, @removed, @errors)
|
|
50
56
|
end
|
|
51
57
|
end
|
|
52
58
|
|
|
53
59
|
def -(other)
|
|
54
60
|
if other.is_a?(Judges::Churn)
|
|
55
|
-
Judges::Churn.new(@added - other.added, @removed - other.removed)
|
|
61
|
+
Judges::Churn.new(@added - other.added, @removed - other.removed, @errors + other.errors)
|
|
56
62
|
else
|
|
57
|
-
Judges::Churn.new(@added, @removed + other)
|
|
63
|
+
Judges::Churn.new(@added, @removed + other, @errors)
|
|
58
64
|
end
|
|
59
65
|
end
|
|
60
66
|
end
|
data/lib/judges/commands/pull.rb
CHANGED
|
@@ -47,6 +47,7 @@ class Judges::Pull
|
|
|
47
47
|
name = args[0]
|
|
48
48
|
elapsed(@loog) do
|
|
49
49
|
if baza.name_exists?(name)
|
|
50
|
+
baza.lock(name, opts['owner'])
|
|
50
51
|
fb.import(baza.pull(wait(baza, baza.recent(name), opts['wait'])))
|
|
51
52
|
Judges::Impex.new(@loog, args[1]).export(fb)
|
|
52
53
|
throw :"Pulled #{fb.size} facts by the name '#{name}'"
|
data/lib/judges/commands/push.rb
CHANGED
|
@@ -72,6 +72,17 @@ class Judges::Update
|
|
|
72
72
|
end
|
|
73
73
|
throw :"Update finished in #{c} cycle(s), modified #{churn} fact(s)"
|
|
74
74
|
end
|
|
75
|
+
return if churn.zero? || !opts['summary']
|
|
76
|
+
fb.query('(eq what "judges-summary")').delete!
|
|
77
|
+
f = fb.insert
|
|
78
|
+
f.what = 'judges-summary'
|
|
79
|
+
f.when = Time.now
|
|
80
|
+
f.version = Judges::VERSION
|
|
81
|
+
f.cycles = c
|
|
82
|
+
f.added = churn.added.size
|
|
83
|
+
f.removed = churn.removed.size
|
|
84
|
+
churn.errors.each { |e| f.error = e }
|
|
85
|
+
impex.export(fb)
|
|
75
86
|
end
|
|
76
87
|
|
|
77
88
|
private
|
|
@@ -79,12 +90,11 @@ class Judges::Update
|
|
|
79
90
|
# Run all judges in a full cycle, one by one.
|
|
80
91
|
# @return [Churn] How many modifications have been made
|
|
81
92
|
def cycle(opts, judges, fb, options)
|
|
82
|
-
errors = []
|
|
83
93
|
churn = Judges::Churn.new(0, 0)
|
|
84
94
|
global = {}
|
|
85
95
|
elapsed(@loog) do
|
|
86
96
|
done = judges.each_with_index do |p, i|
|
|
87
|
-
@loog.info("\n
|
|
97
|
+
@loog.info("\n👉 Running #{p.name} (##{i}) at #{p.dir.to_rel}...")
|
|
88
98
|
elapsed(@loog) do
|
|
89
99
|
c = one_judge(fb, p, global, options)
|
|
90
100
|
churn += c
|
|
@@ -92,13 +102,13 @@ class Judges::Update
|
|
|
92
102
|
end
|
|
93
103
|
rescue StandardError, SyntaxError => e
|
|
94
104
|
@loog.warn(Backtrace.new(e))
|
|
95
|
-
|
|
105
|
+
churn << e.message
|
|
96
106
|
end
|
|
97
|
-
throw :"👍 #{done} judge(s) processed" if errors.empty?
|
|
98
|
-
throw :"❌ #{done} judge(s) processed with #{errors.size} errors"
|
|
107
|
+
throw :"👍 #{done} judge(s) processed" if churn.errors.empty?
|
|
108
|
+
throw :"❌ #{done} judge(s) processed with #{churn.errors.size} errors"
|
|
99
109
|
end
|
|
100
|
-
unless errors.empty?
|
|
101
|
-
raise "Failed to update correctly (#{errors.size} errors)" unless opts['quiet']
|
|
110
|
+
unless churn.errors.empty?
|
|
111
|
+
raise "Failed to update correctly (#{churn.errors.size} errors)" unless opts['quiet']
|
|
102
112
|
@loog.info('Not failing because of the --quiet flag provided')
|
|
103
113
|
end
|
|
104
114
|
churn
|
data/lib/judges.rb
CHANGED
data/test/commands/test_pull.rb
CHANGED
|
@@ -34,6 +34,7 @@ require_relative '../../lib/judges/commands/pull'
|
|
|
34
34
|
class TestPull < Minitest::Test
|
|
35
35
|
def test_pull_simple_factbase
|
|
36
36
|
WebMock.disable_net_connect!
|
|
37
|
+
stub_request(:get, 'http://example.org/lock/foo?owner=none').to_return(status: 302)
|
|
37
38
|
stub_request(:get, 'http://example.org/exists/foo').to_return(body: 'yes')
|
|
38
39
|
stub_request(:get, 'http://example.org/recent/foo.txt').to_return(body: '42')
|
|
39
40
|
stub_request(:get, 'http://example.org/finished/42').to_return(body: 'yes')
|
|
@@ -48,7 +49,8 @@ class TestPull < Minitest::Test
|
|
|
48
49
|
'host' => 'example.org',
|
|
49
50
|
'port' => 80,
|
|
50
51
|
'ssl' => false,
|
|
51
|
-
'wait' => 10
|
|
52
|
+
'wait' => 10,
|
|
53
|
+
'owner' => 'none'
|
|
52
54
|
},
|
|
53
55
|
['foo', file]
|
|
54
56
|
)
|
data/test/commands/test_push.rb
CHANGED
|
@@ -33,6 +33,8 @@ require_relative '../../lib/judges/commands/push'
|
|
|
33
33
|
class TestPush < Minitest::Test
|
|
34
34
|
def test_push_simple_factbase
|
|
35
35
|
WebMock.disable_net_connect!
|
|
36
|
+
stub_request(:get, 'https://example.org/lock/foo?owner=none').to_return(status: 302)
|
|
37
|
+
stub_request(:get, 'https://example.org/unlock/foo?owner=none').to_return(status: 302)
|
|
36
38
|
stub_request(:put, 'https://example.org/push/foo').to_return(
|
|
37
39
|
status: 200, body: '42'
|
|
38
40
|
)
|
|
@@ -46,7 +48,8 @@ class TestPush < Minitest::Test
|
|
|
46
48
|
'token' => '000',
|
|
47
49
|
'host' => 'example.org',
|
|
48
50
|
'port' => 443,
|
|
49
|
-
'ssl' => true
|
|
51
|
+
'ssl' => true,
|
|
52
|
+
'owner' => 'none'
|
|
50
53
|
},
|
|
51
54
|
['foo', file]
|
|
52
55
|
)
|
|
@@ -55,6 +58,7 @@ class TestPush < Minitest::Test
|
|
|
55
58
|
|
|
56
59
|
def test_fails_on_http_error
|
|
57
60
|
WebMock.disable_net_connect!
|
|
61
|
+
stub_request(:get, 'http://example.org/lock/foo?owner=none').to_return(status: 302)
|
|
58
62
|
stub_request(:put, 'http://example.org/push/foo').to_return(status: 500)
|
|
59
63
|
Dir.mktmpdir do |d|
|
|
60
64
|
file = File.join(d, 'base.fb')
|
|
@@ -67,7 +71,8 @@ class TestPush < Minitest::Test
|
|
|
67
71
|
'token' => '000',
|
|
68
72
|
'host' => 'example.org',
|
|
69
73
|
'port' => 80,
|
|
70
|
-
'ssl' => false
|
|
74
|
+
'ssl' => false,
|
|
75
|
+
'owner' => 'none'
|
|
71
76
|
},
|
|
72
77
|
['foo', file]
|
|
73
78
|
)
|
|
@@ -64,7 +64,7 @@ class TestUpdate < Minitest::Test
|
|
|
64
64
|
Dir.mktmpdir do |d|
|
|
65
65
|
File.write(File.join(d, 'foo.rb'), 'this$is$a$broken$Ruby$script')
|
|
66
66
|
file = File.join(d, 'base.fb')
|
|
67
|
-
Judges::Update.new(Loog::NULL).run({ 'quiet' => true }, [d, file])
|
|
67
|
+
Judges::Update.new(Loog::NULL).run({ 'quiet' => true, 'max-cycles' => 2 }, [d, file])
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
@@ -77,4 +77,23 @@ class TestUpdate < Minitest::Test
|
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
|
+
|
|
81
|
+
def test_update_with_error_and_summary
|
|
82
|
+
Dir.mktmpdir do |d|
|
|
83
|
+
File.write(File.join(d, 'foo.rb'), 'this$is$a$broken$Ruby$script')
|
|
84
|
+
file = File.join(d, 'base.fb')
|
|
85
|
+
2.times do
|
|
86
|
+
Judges::Update.new(Loog::NULL).run(
|
|
87
|
+
{ 'quiet' => true, 'summary' => true, 'max-cycles' => 2 },
|
|
88
|
+
[d, file]
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
fb = Factbase.new
|
|
92
|
+
fb.import(File.binread(file))
|
|
93
|
+
sums = fb.query('(eq what "judges-summary")').each.to_a
|
|
94
|
+
assert_equal(1, sums.size)
|
|
95
|
+
f = sums.first
|
|
96
|
+
assert(f.error.include?('unexpected global variable'), f.error)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
80
99
|
end
|
data/test/test_churn.rb
CHANGED
|
@@ -35,4 +35,12 @@ class TestChurn < Minitest::Test
|
|
|
35
35
|
assert_equal('42/0', (churn + 42).to_s)
|
|
36
36
|
assert_equal('0/17', (churn - 17).to_s)
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
def test_with_errors
|
|
40
|
+
churn = Judges::Churn.new(0, 0)
|
|
41
|
+
churn << 'oops'
|
|
42
|
+
assert_equal('0/0/1', churn.to_s)
|
|
43
|
+
assert_equal('42/0/1', (churn + 42).to_s)
|
|
44
|
+
assert_equal('0/0/1', (Judges::Churn.new(0, 0) + churn).to_s)
|
|
45
|
+
end
|
|
38
46
|
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.
|
|
4
|
+
version: 0.13.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-06-
|
|
11
|
+
date: 2024-06-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: backtrace
|
|
@@ -28,16 +28,16 @@ dependencies:
|
|
|
28
28
|
name: concurrent-ruby
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- -
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 1.2
|
|
33
|
+
version: '1.2'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- -
|
|
38
|
+
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 1.2
|
|
40
|
+
version: '1.2'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: factbase
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|