judges 0.0.30 → 0.0.32
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/.github/workflows/license.yml +57 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +8 -8
- data/bin/judges +1 -1
- data/features/import.feature +1 -1
- data/features/step_definitions/steps.rb +1 -1
- data/features/test.feature +1 -1
- data/features/update.feature +20 -0
- data/fixtures/guess/guess.rb +28 -0
- data/fixtures/{reward_for_good_bug/simple-reward.yml → guess/guess_made.yml} +4 -13
- data/fixtures/guess/skipped.yml +24 -0
- data/fixtures/{reward_for_good_bug/no-reward.yml → try/tried.yml} +3 -7
- data/fixtures/{reward_for_good_bug/reward_it.rb → try/try.rb} +2 -8
- data/judges.gemspec +2 -2
- data/lib/judges/commands/eval.rb +11 -11
- data/lib/judges/commands/import.rb +14 -12
- data/lib/judges/commands/join.rb +7 -4
- data/lib/judges/commands/print.rb +17 -15
- data/lib/judges/commands/test.rb +26 -27
- data/lib/judges/commands/trim.rb +5 -7
- data/lib/judges/commands/update.rb +38 -31
- data/lib/judges/elapsed.rb +32 -0
- data/lib/judges/pack.rb +3 -1
- data/test/commands/test_update.rb +11 -1
- data/test/test_pack.rb +24 -0
- metadata +11 -8
- data/fixtures/reward_for_good_bug/README.md +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cf26642d3989b5d0097e54b224bd8c8b431f5e488f04a6c6cc778f9a914e0ad6
|
|
4
|
+
data.tar.gz: 79974f0a047a19f499e8b9b69566ded6b9b78d3bf6f470bfc67e9aead9988dc9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7af589ce71752db5991f3838ea4e6b0e13969f3caab954f21d991d692d75b592c5f3bbe5d42e26cdc9a5d2c68a8ed3fcbe87401c34b1d6daa92c380f6fc7688
|
|
7
|
+
data.tar.gz: 25a4cc8aa470fb2f457c9f00b1581d5e4c05ab07d8580da124fd59d92c768796b4548948cb03abfc88256936b3ad8a2ae2fa4dd0edd66a7f1ae69a8530176fcf
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Copyright (c) 2024 Yegor Bugayenko
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
# furnished to do so, subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
# copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
# SOFTWARE.
|
|
20
|
+
---
|
|
21
|
+
name: license
|
|
22
|
+
'on':
|
|
23
|
+
push:
|
|
24
|
+
branches:
|
|
25
|
+
- master
|
|
26
|
+
pull_request:
|
|
27
|
+
branches:
|
|
28
|
+
- master
|
|
29
|
+
jobs:
|
|
30
|
+
license:
|
|
31
|
+
runs-on: ubuntu-22.04
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- shell: bash
|
|
35
|
+
run: |
|
|
36
|
+
header="Copyright (c) $(date +%Y) Yegor Bugayenko"
|
|
37
|
+
failed="false"
|
|
38
|
+
while IFS= read -r file; do
|
|
39
|
+
if ! grep -q "${header}" "${file}"; then
|
|
40
|
+
failed="true"
|
|
41
|
+
echo "⚠️ Copyright header is not found in: ${file}"
|
|
42
|
+
else
|
|
43
|
+
echo "File looks good: ${file}"
|
|
44
|
+
fi
|
|
45
|
+
done < <(find . -type f \( \
|
|
46
|
+
-name "Dockerfile" -o \
|
|
47
|
+
-name "LICENSE.txt" -o \
|
|
48
|
+
-name "Makefile" -o \
|
|
49
|
+
-name "Rakefile" -o \
|
|
50
|
+
-name "*.sh" -o \
|
|
51
|
+
-name "*.rb" -o \
|
|
52
|
+
-name "*.fe" -o \
|
|
53
|
+
-name "*.yml" \
|
|
54
|
+
\) -print)
|
|
55
|
+
if [ "${failed}" = "true" ]; then
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
data/Gemfile
CHANGED
|
@@ -24,10 +24,10 @@ source 'https://rubygems.org'
|
|
|
24
24
|
gemspec
|
|
25
25
|
|
|
26
26
|
gem 'cucumber', '9.2.0', require: false
|
|
27
|
-
gem 'minitest', '5.23.
|
|
27
|
+
gem 'minitest', '5.23.1', require: false
|
|
28
28
|
gem 'rake', '13.2.1', require: false
|
|
29
29
|
gem 'rspec-rails', '6.1.2', require: false
|
|
30
|
-
gem 'rubocop', '1.
|
|
30
|
+
gem 'rubocop', '1.64.0', require: false
|
|
31
31
|
gem 'rubocop-performance', '1.21.0', require: false
|
|
32
32
|
gem 'rubocop-rspec', '2.29.2', require: false
|
|
33
33
|
gem 'simplecov', '0.22.0', require: false
|
data/Gemfile.lock
CHANGED
|
@@ -3,7 +3,7 @@ PATH
|
|
|
3
3
|
specs:
|
|
4
4
|
judges (0.0.0)
|
|
5
5
|
backtrace (~> 0.3)
|
|
6
|
-
factbase (~> 0.0.
|
|
6
|
+
factbase (~> 0.0.30)
|
|
7
7
|
gli (~> 2.21)
|
|
8
8
|
loog (~> 0.2)
|
|
9
9
|
nokogiri (~> 1.10)
|
|
@@ -74,7 +74,7 @@ GEM
|
|
|
74
74
|
docile (1.4.0)
|
|
75
75
|
drb (2.2.1)
|
|
76
76
|
erubi (1.12.0)
|
|
77
|
-
factbase (0.0.
|
|
77
|
+
factbase (0.0.30)
|
|
78
78
|
json (~> 2.7)
|
|
79
79
|
loog (~> 0.2)
|
|
80
80
|
nokogiri (~> 1.10)
|
|
@@ -95,7 +95,7 @@ GEM
|
|
|
95
95
|
nokogiri (>= 1.12.0)
|
|
96
96
|
loog (0.5.1)
|
|
97
97
|
mini_mime (1.1.5)
|
|
98
|
-
minitest (5.23.
|
|
98
|
+
minitest (5.23.1)
|
|
99
99
|
multi_test (1.1.0)
|
|
100
100
|
mutex_m (0.2.0)
|
|
101
101
|
nokogiri (1.16.5-arm64-darwin)
|
|
@@ -112,7 +112,7 @@ GEM
|
|
|
112
112
|
racc
|
|
113
113
|
psych (5.1.2)
|
|
114
114
|
stringio
|
|
115
|
-
racc (1.
|
|
115
|
+
racc (1.8.0)
|
|
116
116
|
rack (3.0.11)
|
|
117
117
|
rack-session (2.0.0)
|
|
118
118
|
rack (>= 3.0.0)
|
|
@@ -138,7 +138,7 @@ GEM
|
|
|
138
138
|
zeitwerk (~> 2.6)
|
|
139
139
|
rainbow (3.1.1)
|
|
140
140
|
rake (13.2.1)
|
|
141
|
-
rdoc (6.
|
|
141
|
+
rdoc (6.7.0)
|
|
142
142
|
psych (>= 4.0.0)
|
|
143
143
|
regexp_parser (2.9.2)
|
|
144
144
|
reline (0.5.7)
|
|
@@ -162,7 +162,7 @@ GEM
|
|
|
162
162
|
rspec-mocks (~> 3.13)
|
|
163
163
|
rspec-support (~> 3.13)
|
|
164
164
|
rspec-support (3.13.1)
|
|
165
|
-
rubocop (1.
|
|
165
|
+
rubocop (1.64.0)
|
|
166
166
|
json (~> 2.3)
|
|
167
167
|
language_server-protocol (>= 3.17.0)
|
|
168
168
|
parallel (~> 1.10)
|
|
@@ -221,10 +221,10 @@ PLATFORMS
|
|
|
221
221
|
DEPENDENCIES
|
|
222
222
|
cucumber (= 9.2.0)
|
|
223
223
|
judges!
|
|
224
|
-
minitest (= 5.23.
|
|
224
|
+
minitest (= 5.23.1)
|
|
225
225
|
rake (= 13.2.1)
|
|
226
226
|
rspec-rails (= 6.1.2)
|
|
227
|
-
rubocop (= 1.
|
|
227
|
+
rubocop (= 1.64.0)
|
|
228
228
|
rubocop-performance (= 1.21.0)
|
|
229
229
|
rubocop-rspec (= 2.29.2)
|
|
230
230
|
simplecov (= 0.22.0)
|
data/bin/judges
CHANGED
data/features/import.feature
CHANGED
|
@@ -49,7 +49,7 @@ When(%r{^I run bin/judges with "([^"]*)"$}) do |arg|
|
|
|
49
49
|
home = File.join(File.dirname(__FILE__), '../..')
|
|
50
50
|
cmd = "ruby -I#{home}/lib #{home}/bin/judges #{arg}"
|
|
51
51
|
cmd = "GLI_DEBUG=true #{cmd}" unless Gem.win_platform?
|
|
52
|
-
@stdout = `#{cmd}`
|
|
52
|
+
@stdout = `#{cmd} 2>&1`
|
|
53
53
|
@exitstatus = $CHILD_STATUS.exitstatus
|
|
54
54
|
end
|
|
55
55
|
|
data/features/test.feature
CHANGED
|
@@ -8,7 +8,7 @@ Feature: Test
|
|
|
8
8
|
And Exit code is zero
|
|
9
9
|
|
|
10
10
|
Scenario: Simple test of just one pack
|
|
11
|
-
Given I run bin/judges with "test --pack
|
|
11
|
+
Given I run bin/judges with "test --pack guess ./fixtures"
|
|
12
12
|
Then Stdout contains "judge(s) tested successfully"
|
|
13
13
|
And Exit code is zero
|
|
14
14
|
|
data/features/update.feature
CHANGED
|
@@ -30,3 +30,23 @@ Feature: Update
|
|
|
30
30
|
Then Stdout contains "1 judge(s) processed"
|
|
31
31
|
Then Stdout contains "Update finished: 1 cycles"
|
|
32
32
|
And Exit code is zero
|
|
33
|
+
|
|
34
|
+
Scenario: The update fails when a bug in a judge
|
|
35
|
+
Given I make a temp directory
|
|
36
|
+
Then I have a "mypacks/mypack/broken.rb" file with content:
|
|
37
|
+
"""
|
|
38
|
+
a < 1
|
|
39
|
+
"""
|
|
40
|
+
Then I run bin/judges with "update mypacks simple.fb"
|
|
41
|
+
Then Stdout contains "Failed to update correctly"
|
|
42
|
+
And Exit code is not zero
|
|
43
|
+
|
|
44
|
+
Scenario: The update fails when a broken Ruby syntax in a judge
|
|
45
|
+
Given I make a temp directory
|
|
46
|
+
Then I have a "mypacks/mypack/broken.rb" file with content:
|
|
47
|
+
"""
|
|
48
|
+
invalid$ruby$syntax$here
|
|
49
|
+
"""
|
|
50
|
+
Then I run bin/judges with "update mypacks simple.fb"
|
|
51
|
+
Then Stdout contains "Failed to update correctly"
|
|
52
|
+
And Exit code is not zero
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
$loog.info("Trying to guess a number (judge=#{$judge})...")
|
|
24
|
+
$fb.txn do |fbt|
|
|
25
|
+
n = fbt.insert
|
|
26
|
+
n.number = Random.rand(100)
|
|
27
|
+
n.time = Time.now
|
|
28
|
+
end
|
|
@@ -18,17 +18,8 @@
|
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
19
|
# SOFTWARE.
|
|
20
20
|
---
|
|
21
|
-
input:
|
|
22
|
-
-
|
|
23
|
-
kind: bug was accepted
|
|
24
|
-
reporter: yegor256
|
|
25
|
-
time: 2024-01-01T03:15:45
|
|
26
|
-
seen:
|
|
27
|
-
- one
|
|
28
|
-
- two
|
|
29
|
-
- three
|
|
21
|
+
input: []
|
|
30
22
|
expected:
|
|
31
|
-
- /fb[count(f)=
|
|
32
|
-
- /fb/f
|
|
33
|
-
- /fb/f
|
|
34
|
-
- /fb/f[amount='15']
|
|
23
|
+
- /fb[count(f)=1]
|
|
24
|
+
- /fb/f/number
|
|
25
|
+
- /fb/f/time
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Copyright (c) 2024 Yegor Bugayenko
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
# furnished to do so, subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
# copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
# SOFTWARE.
|
|
20
|
+
---
|
|
21
|
+
skip: true
|
|
22
|
+
input: []
|
|
23
|
+
expected:
|
|
24
|
+
- /should-never-reach-this-point
|
|
@@ -20,13 +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
|
-
$
|
|
24
|
-
|
|
25
|
-
once($fb).query("(eq kind 'bug was accepted')").each do |f|
|
|
26
|
-
$loog.info('Good candidate found!')
|
|
23
|
+
once($fb).query("(and (exists number) (lt time #{Time.now.utc.iso8601}))").each do |f|
|
|
27
24
|
n = $fb.insert
|
|
28
|
-
n.
|
|
29
|
-
n.payee = f.reporter
|
|
30
|
-
n.amount = 15
|
|
31
|
-
n.message = 'thanks for reporting a bug; you get +15 points for this'
|
|
25
|
+
n.guess = f.number
|
|
32
26
|
end
|
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.0.
|
|
29
|
+
s.version = '0.0.32'
|
|
30
30
|
s.license = 'MIT'
|
|
31
31
|
s.summary = 'Command-Line Tool for a Factbase'
|
|
32
32
|
s.description = '
|
|
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
|
|
|
42
42
|
s.rdoc_options = ['--charset=UTF-8']
|
|
43
43
|
s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
|
|
44
44
|
s.add_runtime_dependency 'backtrace', '~> 0.3'
|
|
45
|
-
s.add_runtime_dependency 'factbase', '~>0.0.
|
|
45
|
+
s.add_runtime_dependency 'factbase', '~>0.0.30'
|
|
46
46
|
s.add_runtime_dependency 'gli', '~>2.21'
|
|
47
47
|
s.add_runtime_dependency 'loog', '~>0.2'
|
|
48
48
|
s.add_runtime_dependency 'nokogiri', '~> 1.10'
|
data/lib/judges/commands/eval.rb
CHANGED
|
@@ -20,13 +20,10 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
-
require 'backtrace'
|
|
24
23
|
require 'factbase/looged'
|
|
25
24
|
require_relative '../../judges'
|
|
26
|
-
require_relative '../../judges/to_rel'
|
|
27
|
-
require_relative '../../judges/packs'
|
|
28
|
-
require_relative '../../judges/options'
|
|
29
25
|
require_relative '../../judges/impex'
|
|
26
|
+
require_relative '../../judges/elapsed'
|
|
30
27
|
|
|
31
28
|
# Eval.
|
|
32
29
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
@@ -40,12 +37,15 @@ class Judges::Eval
|
|
|
40
37
|
def run(_opts, args)
|
|
41
38
|
raise 'Exactly two arguments required' unless args.size == 2
|
|
42
39
|
impex = Judges::Impex.new(@loog, args[0])
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
elapsed(@loog) do
|
|
41
|
+
$fb = impex.import(strict: false)
|
|
42
|
+
$fb = Factbase::Looged.new($fb, @loog)
|
|
43
|
+
expr = args[1]
|
|
44
|
+
# rubocop:disable Security/Eval
|
|
45
|
+
eval(expr)
|
|
46
|
+
# rubocop:enable Security/Eval
|
|
47
|
+
impex.export($fb)
|
|
48
|
+
throw :'Evaluated successfully'
|
|
49
|
+
end
|
|
50
50
|
end
|
|
51
51
|
end
|
|
@@ -25,6 +25,7 @@ require 'factbase/looged'
|
|
|
25
25
|
require_relative '../../judges'
|
|
26
26
|
require_relative '../../judges/impex'
|
|
27
27
|
require_relative '../../judges/to_rel'
|
|
28
|
+
require_relative '../../judges/elapsed'
|
|
28
29
|
|
|
29
30
|
# Import.
|
|
30
31
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
@@ -38,19 +39,20 @@ class Judges::Import
|
|
|
38
39
|
def run(_opts, args)
|
|
39
40
|
raise 'Exactly two arguments required' unless args.size == 2
|
|
40
41
|
raise "File not found #{args[0].to_rel}" unless File.exist?(args[0])
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
elapsed(@loog) do
|
|
43
|
+
yaml = YAML.load_file(args[0], permitted_classes: [Time])
|
|
44
|
+
@loog.info("YAML loaded from #{args[0].to_rel} (#{yaml.size} facts)")
|
|
45
|
+
impex = Judges::Impex.new(@loog, args[1])
|
|
46
|
+
fb = impex.import(strict: false)
|
|
47
|
+
fb = Factbase::Looged.new(fb, @loog)
|
|
48
|
+
yaml.each do |i|
|
|
49
|
+
f = fb.insert
|
|
50
|
+
i.each do |p, v|
|
|
51
|
+
f.send("#{p}=", v)
|
|
52
|
+
end
|
|
51
53
|
end
|
|
54
|
+
impex.export(fb)
|
|
55
|
+
throw :"Import of #{yaml.size} facts finished"
|
|
52
56
|
end
|
|
53
|
-
impex.export(fb)
|
|
54
|
-
@loog.info("Import finished in #{format('%.02f', Time.now - start)}s")
|
|
55
57
|
end
|
|
56
58
|
end
|
data/lib/judges/commands/join.rb
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
require_relative '../../judges'
|
|
24
24
|
require_relative '../../judges/impex'
|
|
25
|
+
require_relative '../../judges/elapsed'
|
|
25
26
|
|
|
26
27
|
# Join.
|
|
27
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
@@ -36,9 +37,11 @@ class Judges::Join
|
|
|
36
37
|
raise 'Exactly two arguments required' unless args.size == 2
|
|
37
38
|
master = Judges::Impex.new(@loog, args[0])
|
|
38
39
|
slave = Judges::Impex.new(@loog, args[1])
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
elapsed(@loog) do
|
|
41
|
+
fb = master.import
|
|
42
|
+
slave.import_to(fb)
|
|
43
|
+
master.export(fb)
|
|
44
|
+
throw :'Two factbases joined'
|
|
45
|
+
end
|
|
43
46
|
end
|
|
44
47
|
end
|
|
@@ -24,6 +24,7 @@ require 'fileutils'
|
|
|
24
24
|
require 'factbase'
|
|
25
25
|
require_relative '../../judges'
|
|
26
26
|
require_relative '../../judges/impex'
|
|
27
|
+
require_relative '../../judges/elapsed'
|
|
27
28
|
|
|
28
29
|
# Update.
|
|
29
30
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
@@ -53,20 +54,21 @@ class Judges::Print
|
|
|
53
54
|
end
|
|
54
55
|
@loog.debug("The factbase #{f.to_rel} is younger than the target #{o.to_rel}, need to print")
|
|
55
56
|
end
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
57
|
+
elapsed(@loog) do
|
|
58
|
+
output =
|
|
59
|
+
case opts[:format].downcase
|
|
60
|
+
when 'yaml'
|
|
61
|
+
require 'factbase/to_yaml'
|
|
62
|
+
Factbase::ToYAML.new(fb).yaml
|
|
63
|
+
when 'json'
|
|
64
|
+
require 'factbase/to_json'
|
|
65
|
+
Factbase::ToJSON.new(fb).json
|
|
66
|
+
when 'xml'
|
|
67
|
+
require 'factbase/to_xml'
|
|
68
|
+
Factbase::ToXML.new(fb).xml
|
|
69
|
+
end
|
|
70
|
+
File.binwrite(o, output)
|
|
71
|
+
throw :"Factbase printed to #{o.to_rel} (#{File.size(o)} bytes)"
|
|
72
|
+
end
|
|
71
73
|
end
|
|
72
74
|
end
|
data/lib/judges/commands/test.rb
CHANGED
|
@@ -29,6 +29,7 @@ require_relative '../../judges'
|
|
|
29
29
|
require_relative '../../judges/to_rel'
|
|
30
30
|
require_relative '../../judges/packs'
|
|
31
31
|
require_relative '../../judges/options'
|
|
32
|
+
require_relative '../../judges/elapsed'
|
|
32
33
|
|
|
33
34
|
# Test.
|
|
34
35
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
@@ -45,34 +46,32 @@ class Judges::Test
|
|
|
45
46
|
@loog.info("Testing judges in #{dir.to_rel}...")
|
|
46
47
|
errors = []
|
|
47
48
|
done = 0
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
elapsed(@loog) do
|
|
50
|
+
Judges::Packs.new(dir, opts['lib'], @loog).each_with_index do |p, i|
|
|
51
|
+
next unless include?(opts, p.name)
|
|
52
|
+
@loog.info("\n👉 Testing #{p.script} (##{i}) in #{p.dir.to_rel}...")
|
|
53
|
+
p.tests.each do |f|
|
|
54
|
+
yaml = YAML.load_file(f, permitted_classes: [Time])
|
|
55
|
+
if yaml['skip']
|
|
56
|
+
@loog.info("Skippped #{f.to_rel}")
|
|
57
|
+
next
|
|
58
|
+
end
|
|
59
|
+
@loog.info("Testing #{f.to_rel}:")
|
|
60
|
+
begin
|
|
61
|
+
test_one(p, yaml)
|
|
62
|
+
rescue StandardError => e
|
|
63
|
+
@loog.warn(Backtrace.new(e))
|
|
64
|
+
errors << f
|
|
65
|
+
end
|
|
62
66
|
end
|
|
67
|
+
done += 1
|
|
63
68
|
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if done.zero?
|
|
68
|
-
raise 'No judges tested :(' unless opts['quiet']
|
|
69
|
-
@loog.warn("\n👍 No judges tested #{lapse}")
|
|
70
|
-
elsif errors.empty?
|
|
71
|
-
@loog.info("\n👍 All #{done} judge(s) tested successfully #{lapse}")
|
|
72
|
-
else
|
|
73
|
-
@loog.info("\n❌ #{done} judge(s) tested, #{errors.size} of them failed #{lapse}")
|
|
74
|
-
raise "#{errors.size} tests failed" unless opts['quiet']
|
|
69
|
+
throw :'👍 No judges tested' if done.zero?
|
|
70
|
+
throw :"👍 All #{done} judge(s) tested successfully" if errors.empty?
|
|
71
|
+
throw :"❌ #{done} judge(s) tested, #{errors.size} of them failed"
|
|
75
72
|
end
|
|
73
|
+
raise "#{errors.size} tests failed" unless opts['quiet'] || errors.empty?
|
|
74
|
+
raise 'No judges tested :(' unless opts['quiet'] || !done.zero?
|
|
76
75
|
end
|
|
77
76
|
|
|
78
77
|
private
|
|
@@ -83,7 +82,7 @@ class Judges::Test
|
|
|
83
82
|
packs.include?(name)
|
|
84
83
|
end
|
|
85
84
|
|
|
86
|
-
def test_one(pack,
|
|
85
|
+
def test_one(pack, yaml)
|
|
87
86
|
fb = Factbase.new
|
|
88
87
|
yaml['input'].each do |i|
|
|
89
88
|
f = fb.insert
|
|
@@ -97,7 +96,7 @@ class Judges::Test
|
|
|
97
96
|
end
|
|
98
97
|
end
|
|
99
98
|
end
|
|
100
|
-
pack.run(Factbase::Looged.new(fb, @loog),
|
|
99
|
+
pack.run(Factbase::Looged.new(fb, @loog), {}, {}, Judges::Options.new(yaml['options']))
|
|
101
100
|
xml = Nokogiri::XML.parse(Factbase::ToXML.new(fb).xml)
|
|
102
101
|
yaml['expected'].each do |xp|
|
|
103
102
|
raise "#{pack.script} doesn't match '#{xp}':\n#{xml}" if xml.xpath(xp).empty?
|
data/lib/judges/commands/trim.rb
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
require 'time'
|
|
24
24
|
require_relative '../../judges'
|
|
25
25
|
require_relative '../../judges/impex'
|
|
26
|
+
require_relative '../../judges/elapsed'
|
|
26
27
|
|
|
27
28
|
# Trim.
|
|
28
29
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
@@ -46,14 +47,11 @@ class Judges::Trim
|
|
|
46
47
|
else
|
|
47
48
|
raise 'Specify either --days or --query' unless opts['days'].nil?
|
|
48
49
|
end
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if deleted.zero?
|
|
53
|
-
@loog.info("No facts deleted #{lapse}")
|
|
54
|
-
else
|
|
55
|
-
@loog.info("🗑 #{deleted} fact(s) deleted #{lapse}")
|
|
50
|
+
elapsed(@loog) do
|
|
51
|
+
deleted = fb.query(query).delete!
|
|
52
|
+
throw :'No facts deleted' if deleted.zero?
|
|
56
53
|
impex.export(fb)
|
|
54
|
+
throw :"🗑 #{deleted} fact(s) deleted"
|
|
57
55
|
end
|
|
58
56
|
end
|
|
59
57
|
end
|
|
@@ -27,6 +27,7 @@ require_relative '../../judges/to_rel'
|
|
|
27
27
|
require_relative '../../judges/packs'
|
|
28
28
|
require_relative '../../judges/options'
|
|
29
29
|
require_relative '../../judges/impex'
|
|
30
|
+
require_relative '../../judges/elapsed'
|
|
30
31
|
|
|
31
32
|
# Update.
|
|
32
33
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
@@ -48,23 +49,27 @@ class Judges::Update
|
|
|
48
49
|
@loog.debug("The following options provided:\n\t#{options.to_s.gsub("\n", "\n\t")}")
|
|
49
50
|
packs = Judges::Packs.new(dir, opts['lib'], @loog)
|
|
50
51
|
c = 0
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
break
|
|
52
|
+
elapsed(@loog) do
|
|
53
|
+
loop do
|
|
54
|
+
c += 1
|
|
55
|
+
if c > 1
|
|
56
|
+
@loog.info("\n\nStarting cycle ##{c}#{opts['max-cycles'] ? " (out of #{opts['max-cycles']})" : ''}...")
|
|
57
|
+
end
|
|
58
|
+
diff = cycle(opts, packs, fb, options)
|
|
59
|
+
impex.export(fb)
|
|
60
|
+
break if diff.zero?
|
|
61
|
+
if !opts['max-cycles'].nil? && c >= opts['max-cycles']
|
|
62
|
+
@loog.info('Too many cycles already, as set by --max-cycles, breaking')
|
|
63
|
+
break
|
|
64
|
+
end
|
|
65
|
+
@loog.info(
|
|
66
|
+
"By #{diff} facts the factbase " \
|
|
67
|
+
"#{diff.positive? ? 'increased' : 'decreased'} " \
|
|
68
|
+
"its size at the cycle ##{c}"
|
|
69
|
+
)
|
|
60
70
|
end
|
|
61
|
-
|
|
62
|
-
"By #{diff} facts the factbase " \
|
|
63
|
-
"#{diff.positive? ? 'increased' : 'decreased'} " \
|
|
64
|
-
"its size at the cycle ##{c}"
|
|
65
|
-
)
|
|
71
|
+
throw :"Update finished: #{c} cycles"
|
|
66
72
|
end
|
|
67
|
-
@loog.info("Update finished: #{c} cycles in #{format('%.02f', Time.now - start)}s")
|
|
68
73
|
end
|
|
69
74
|
|
|
70
75
|
private
|
|
@@ -73,25 +78,27 @@ class Judges::Update
|
|
|
73
78
|
errors = []
|
|
74
79
|
diff = 0
|
|
75
80
|
global = {}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
elapsed(@loog) do
|
|
82
|
+
done = packs.each_with_index do |p, i|
|
|
83
|
+
local = {}
|
|
84
|
+
@loog.info("👉 Running #{p.name} (##{i}) at #{p.dir.to_rel}...")
|
|
85
|
+
before = fb.size
|
|
86
|
+
begin
|
|
87
|
+
p.run(fb, global, local, options)
|
|
88
|
+
rescue StandardError, SyntaxError => e
|
|
89
|
+
@loog.warn(Backtrace.new(e))
|
|
90
|
+
errors << p.script
|
|
91
|
+
end
|
|
92
|
+
after = fb.size
|
|
93
|
+
@loog.info("👍 The judge #{p.dir.to_rel} added #{after - before} facts") if after > before
|
|
94
|
+
diff += after - before
|
|
85
95
|
end
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
diff += after - before
|
|
96
|
+
throw :"👍 #{done} judge(s) processed" if errors.empty?
|
|
97
|
+
throw :"❌ #{done} judge(s) processed with #{errors.size} errors"
|
|
89
98
|
end
|
|
90
|
-
|
|
91
|
-
@loog.info("👍 #{done} judge(s) processed")
|
|
92
|
-
else
|
|
93
|
-
@loog.info("❌ #{done} judge(s) processed with #{errors.size} errors")
|
|
99
|
+
unless errors.empty?
|
|
94
100
|
raise "Failed to update correctly (#{errors.size} errors)" unless opts['quiet']
|
|
101
|
+
@loog.info('Not failing because of the --quiet flag provided')
|
|
95
102
|
end
|
|
96
103
|
diff
|
|
97
104
|
end
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
def elapsed(loog)
|
|
24
|
+
start = Time.now
|
|
25
|
+
begin
|
|
26
|
+
yield
|
|
27
|
+
rescue UncaughtThrowError => e
|
|
28
|
+
tag = e.tag
|
|
29
|
+
throw e unless tag.is_a?(Symbol)
|
|
30
|
+
loog.info("#{tag} in #{format('%.02f', Time.now - start)}s")
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/judges/pack.rb
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
require_relative '../judges'
|
|
24
24
|
require_relative '../judges/to_rel'
|
|
25
|
+
require_relative '../judges/elapsed'
|
|
25
26
|
require_relative '../judges/fb/once'
|
|
26
27
|
require_relative '../judges/fb/if_absent'
|
|
27
28
|
|
|
@@ -55,8 +56,9 @@ class Judges::Pack
|
|
|
55
56
|
end
|
|
56
57
|
s = File.join(@dir, script)
|
|
57
58
|
raise "Can't load '#{s}'" unless File.exist?(s)
|
|
58
|
-
|
|
59
|
+
elapsed(@loog) do
|
|
59
60
|
load(s, true)
|
|
61
|
+
throw :"#{name} finished"
|
|
60
62
|
ensure
|
|
61
63
|
$fb = $judge = $options = $loog = nil
|
|
62
64
|
end
|
|
@@ -62,9 +62,19 @@ class TestUpdate < Minitest::Test
|
|
|
62
62
|
|
|
63
63
|
def test_update_with_error
|
|
64
64
|
Dir.mktmpdir do |d|
|
|
65
|
-
File.write(File.join(d, 'foo.rb'), 'this
|
|
65
|
+
File.write(File.join(d, 'foo.rb'), 'this$is$a$broken$Ruby$script')
|
|
66
66
|
file = File.join(d, 'base.fb')
|
|
67
67
|
Judges::Update.new(Loog::NULL).run({ 'quiet' => true }, [d, file])
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
|
+
|
|
71
|
+
def test_update_with_error_no_quiet
|
|
72
|
+
assert_raises do
|
|
73
|
+
Dir.mktmpdir do |d|
|
|
74
|
+
File.write(File.join(d, 'foo.rb'), 'a < 1')
|
|
75
|
+
file = File.join(d, 'base.fb')
|
|
76
|
+
Judges::Update.new(Loog::NULL).run({ 'quiet' => false }, [d, file])
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
70
80
|
end
|
data/test/test_pack.rb
CHANGED
|
@@ -107,4 +107,28 @@ class TestPack < Minitest::Test
|
|
|
107
107
|
assert_equal(42, fb.query('()').each.to_a.first.bar)
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
|
+
|
|
111
|
+
def test_with_broken_ruby_syntax
|
|
112
|
+
assert_raises do
|
|
113
|
+
Dir.mktmpdir do |d|
|
|
114
|
+
dir = File.join(d, 'packs')
|
|
115
|
+
FileUtils.mkdir_p(dir)
|
|
116
|
+
File.write(File.join(dir, 'x.rb'), 'this$is$broken$syntax')
|
|
117
|
+
pack = Judges::Pack.new(dir, lib, Loog::NULL)
|
|
118
|
+
pack.run(Factbase.new, {}, {}, {})
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def test_with_runtime_ruby_error
|
|
124
|
+
assert_raises do
|
|
125
|
+
Dir.mktmpdir do |d|
|
|
126
|
+
dir = File.join(d, 'packs')
|
|
127
|
+
FileUtils.mkdir_p(dir)
|
|
128
|
+
File.write(File.join(dir, 'x.rb'), 'a < 1')
|
|
129
|
+
pack = Judges::Pack.new(dir, lib, Loog::NULL)
|
|
130
|
+
pack.run(Factbase.new, {}, {}, {})
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
110
134
|
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.0.
|
|
4
|
+
version: 0.0.32
|
|
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-05-
|
|
11
|
+
date: 2024-05-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: backtrace
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.0.
|
|
33
|
+
version: 0.0.30
|
|
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: 0.0.
|
|
40
|
+
version: 0.0.30
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: gli
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -96,6 +96,7 @@ files:
|
|
|
96
96
|
- ".gitattributes"
|
|
97
97
|
- ".github/workflows/actionlint.yml"
|
|
98
98
|
- ".github/workflows/codecov.yml"
|
|
99
|
+
- ".github/workflows/license.yml"
|
|
99
100
|
- ".github/workflows/markdown-lint.yml"
|
|
100
101
|
- ".github/workflows/pdd.yml"
|
|
101
102
|
- ".github/workflows/rake.yml"
|
|
@@ -123,10 +124,11 @@ files:
|
|
|
123
124
|
- features/test.feature
|
|
124
125
|
- features/trim.feature
|
|
125
126
|
- features/update.feature
|
|
126
|
-
- fixtures/
|
|
127
|
-
- fixtures/
|
|
128
|
-
- fixtures/
|
|
129
|
-
- fixtures/
|
|
127
|
+
- fixtures/guess/guess.rb
|
|
128
|
+
- fixtures/guess/guess_made.yml
|
|
129
|
+
- fixtures/guess/skipped.yml
|
|
130
|
+
- fixtures/try/tried.yml
|
|
131
|
+
- fixtures/try/try.rb
|
|
130
132
|
- judges.gemspec
|
|
131
133
|
- lib/judges.rb
|
|
132
134
|
- lib/judges/commands/eval.rb
|
|
@@ -137,6 +139,7 @@ files:
|
|
|
137
139
|
- lib/judges/commands/test.rb
|
|
138
140
|
- lib/judges/commands/trim.rb
|
|
139
141
|
- lib/judges/commands/update.rb
|
|
142
|
+
- lib/judges/elapsed.rb
|
|
140
143
|
- lib/judges/fb/if_absent.rb
|
|
141
144
|
- lib/judges/fb/once.rb
|
|
142
145
|
- lib/judges/impex.rb
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
# Why bugs reports are rewarded?
|
|
2
|
-
|
|
3
|
-
Every bug reported and accepted deserves a reward, which
|
|
4
|
-
are given to the reporter of the bug. A bug is considered as
|
|
5
|
-
"accepted" only if it has the `bug`, `enhancement`, or `question` label
|
|
6
|
-
attached to it. Such a reward encourages programmers to report
|
|
7
|
-
more bugs, thus revealing problems that will be fixed before they
|
|
8
|
-
are shipped to a customer.
|