yuuki 0.1.4 → 0.1.8
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/.rubocop.yml +42 -0
- data/Gemfile +1 -1
- data/bin/console +3 -3
- data/lib/yuuki/caller.rb +50 -13
- data/lib/yuuki/periodic.rb +6 -4
- data/lib/yuuki/version.rb +1 -1
- data/yuuki.gemspec +3 -2
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4bc4e09cca35420bedfbe0e86cef17ed348f490f525913ad57171fc4651bb666
|
|
4
|
+
data.tar.gz: 27fb3f53e3c5323fa993ccf0c6b6d7eb432d088b2a47474197be35adaa07fc66
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 264c26d8223f5dc39b0e646202980a307815fdc70e248179726bcbfa734f386c0d84eb83dee067b084c5deb78ccc342e63c5b30f4c9b924be0b00a63b3ee2a47
|
|
7
|
+
data.tar.gz: ac176b3a17eaea160b2ffa0a1ca8aa499ae0d1e87bf759c889c991bdc5a991adf5a13250558cbc57f09b8ca31ae6b04c10d24be86a95e5e3f5102e28cdbe8e69
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 2.6
|
|
3
|
+
|
|
4
|
+
Metrics/AbcSize:
|
|
5
|
+
Max: 170
|
|
6
|
+
|
|
7
|
+
Metrics/BlockLength:
|
|
8
|
+
Max: 250
|
|
9
|
+
|
|
10
|
+
Metrics/ClassLength:
|
|
11
|
+
Max: 1000
|
|
12
|
+
|
|
13
|
+
Metrics/CyclomaticComplexity:
|
|
14
|
+
Max: 70
|
|
15
|
+
|
|
16
|
+
Metrics/MethodLength:
|
|
17
|
+
Max: 100
|
|
18
|
+
|
|
19
|
+
Metrics/ModuleLength:
|
|
20
|
+
Max: 1000
|
|
21
|
+
|
|
22
|
+
Metrics/ParameterLists:
|
|
23
|
+
Max: 50
|
|
24
|
+
|
|
25
|
+
Metrics/PerceivedComplexity:
|
|
26
|
+
Max: 80
|
|
27
|
+
|
|
28
|
+
Layout/SpaceInsideBlockBraces:
|
|
29
|
+
EnforcedStyle: no_space
|
|
30
|
+
SpaceBeforeBlockParameters: false
|
|
31
|
+
|
|
32
|
+
Style/Documentation:
|
|
33
|
+
Enabled: false
|
|
34
|
+
|
|
35
|
+
Style/NumericPredicate:
|
|
36
|
+
EnforcedStyle: comparison
|
|
37
|
+
|
|
38
|
+
Style/MultilineBlockChain:
|
|
39
|
+
Enabled: false
|
|
40
|
+
|
|
41
|
+
Style/SpecialGlobalVars:
|
|
42
|
+
EnforcedStyle: use_perl_names
|
data/Gemfile
CHANGED
data/bin/console
CHANGED
data/lib/yuuki/caller.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'set'
|
|
4
4
|
require 'yuuki/runner'
|
|
5
|
+
require 'yoshinon'
|
|
5
6
|
|
|
6
7
|
module Yuuki
|
|
7
8
|
class Caller
|
|
@@ -9,14 +10,15 @@ module Yuuki
|
|
|
9
10
|
# @param [String] require_dir directory
|
|
10
11
|
# @param [Boolean] recursive
|
|
11
12
|
def self.require_dir(require_dir, recursive: false)
|
|
12
|
-
Dir.glob(recursive ? "#{require_dir}/**/*.rb" : "#{require_dir}/*.rb"){|file| require file}
|
|
13
|
+
Dir.glob(recursive ? "#{require_dir}/**/*.rb" : "#{require_dir}/*.rb").sort.each {|file| require file}
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
# @param [Object] instances
|
|
16
|
-
def initialize(*instances)
|
|
17
|
+
def initialize(*instances, use_yoshinon: true)
|
|
17
18
|
@instances = Set.new
|
|
18
19
|
@threads = []
|
|
19
20
|
add(*instances)
|
|
21
|
+
@use_yoshinon = use_yoshinon
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
# adds instances to yuuki
|
|
@@ -27,13 +29,19 @@ module Yuuki
|
|
|
27
29
|
if instance.is_a?(Class)
|
|
28
30
|
klass = instance
|
|
29
31
|
# check the klass is extended
|
|
30
|
-
|
|
32
|
+
unless klass.singleton_class.include?(Yuuki::Runner)
|
|
33
|
+
raise Yuuki::Error, 'Runner instance must be extend Yuuki::Runner'
|
|
34
|
+
end
|
|
35
|
+
|
|
31
36
|
instance = instance.allocate
|
|
32
37
|
instance.instance_variable_set(:@yuuki, self)
|
|
33
38
|
instance.send(:initialize)
|
|
34
39
|
else
|
|
35
40
|
# check the klass is extended
|
|
36
|
-
|
|
41
|
+
unless instance.class.singleton_class.include?(Yuuki::Runner)
|
|
42
|
+
raise Yuuki::Error, 'Runner instance must be extend Yuuki::Runner'
|
|
43
|
+
end
|
|
44
|
+
|
|
37
45
|
# add @yuuki to the instance
|
|
38
46
|
instance.instance_variable_set(:@yuuki, self)
|
|
39
47
|
end
|
|
@@ -48,17 +56,20 @@ module Yuuki
|
|
|
48
56
|
def runners
|
|
49
57
|
list = @instances.flat_map do |instance|
|
|
50
58
|
methods = instance.class.instance_variable_get(:@yuuki_methods)
|
|
51
|
-
methods.select{|_sig, meta| meta[:enabled]}.map{|sig, meta| [instance.method(sig), meta]}
|
|
59
|
+
methods.select {|_sig, meta| meta[:enabled]}.map {|sig, meta| [instance.method(sig), meta]}
|
|
52
60
|
end
|
|
53
|
-
list.sort_by{|_method, meta| -(meta[:priority] || 0)}
|
|
61
|
+
list.sort_by {|_method, meta| -(meta[:priority] || 0)}
|
|
54
62
|
end
|
|
55
63
|
|
|
56
|
-
# returns all tags defined
|
|
64
|
+
# returns all tags defined as Set
|
|
57
65
|
def tags
|
|
58
|
-
@instances.flat_map do |instance|
|
|
66
|
+
tags = @instances.flat_map do |instance|
|
|
59
67
|
methods = instance.class.instance_variable_get(:@yuuki_methods)
|
|
60
|
-
methods.select{|_sig, meta| meta[:enabled]}.flat_map{|_sig, meta| meta[:tags]}
|
|
68
|
+
methods.select {|_sig, meta| meta[:enabled]}.flat_map {|_sig, meta| meta[:tags]}
|
|
61
69
|
end
|
|
70
|
+
ret = Set.new
|
|
71
|
+
tags.each {|e| ret += e if e}
|
|
72
|
+
ret
|
|
62
73
|
end
|
|
63
74
|
|
|
64
75
|
# runs all methods
|
|
@@ -74,11 +85,23 @@ module Yuuki
|
|
|
74
85
|
run_internal(runners.select(&proc_select), args, &block)
|
|
75
86
|
end
|
|
76
87
|
|
|
88
|
+
# set whether to ignore ``tag not associated'' error
|
|
89
|
+
def ignore_tag_error(enabled: true)
|
|
90
|
+
@ignore_tag_error = enabled
|
|
91
|
+
end
|
|
92
|
+
|
|
77
93
|
# runs all methods with the specified tags
|
|
78
94
|
# @param [Symbol] tags
|
|
79
95
|
# @param [Object] args arguments
|
|
80
96
|
def run_tag(*tags, **args, &block)
|
|
81
|
-
|
|
97
|
+
t = self.tags
|
|
98
|
+
tags.each do |e|
|
|
99
|
+
next if t.include?(e)
|
|
100
|
+
raise Yuuki::Error, "tag `#{e}` is not associated" unless @ignore_tag_error
|
|
101
|
+
|
|
102
|
+
warn "Yuuki Warning: tag `#{e}` is not associated"
|
|
103
|
+
end
|
|
104
|
+
run_select(proc {|_method, meta| meta[:tags]&.intersect?(tags)}, **args, &block)
|
|
82
105
|
end
|
|
83
106
|
|
|
84
107
|
# runs the specific method
|
|
@@ -128,6 +151,8 @@ module Yuuki
|
|
|
128
151
|
def run_method_internal(method, args, &block)
|
|
129
152
|
params = method.parameters
|
|
130
153
|
return method[] if params.empty?
|
|
154
|
+
|
|
155
|
+
yoshinon = Yoshinon.lock if @use_yoshinon
|
|
131
156
|
params_array = []
|
|
132
157
|
params_hash = {}
|
|
133
158
|
params_block = nil
|
|
@@ -135,11 +160,15 @@ module Yuuki
|
|
|
135
160
|
params.each do |type, name|
|
|
136
161
|
case type
|
|
137
162
|
when :req
|
|
138
|
-
|
|
163
|
+
unless args.key?(name)
|
|
164
|
+
raise Yuuki::Error, "A required argument '#{name}' was not found on running #{method.owner}::#{method.name}"
|
|
165
|
+
end
|
|
166
|
+
|
|
139
167
|
params_array << args[name]
|
|
140
168
|
when :opt
|
|
141
169
|
# if parameters do not contain the :opt argument, treat it as not specified
|
|
142
170
|
next nonspecified_last_opt = name unless args.key?(name)
|
|
171
|
+
|
|
143
172
|
if nonspecified_last_opt
|
|
144
173
|
# if there already exist non-specified :opt arguments, no more specified :opt argument is allowed
|
|
145
174
|
raise Yuuki::Error, "A required argument '#{nonspecified_last_opt}' was not found"\
|
|
@@ -148,6 +177,7 @@ module Yuuki
|
|
|
148
177
|
params_array << args[name]
|
|
149
178
|
when :rest
|
|
150
179
|
next unless args.key?(name)
|
|
180
|
+
|
|
151
181
|
if nonspecified_last_opt
|
|
152
182
|
# if there already exist non-specified :opt arguments, the :rest argument cannot be handled
|
|
153
183
|
raise Yuuki::Error, "A required argument '#{nonspecified_last_opt}' not found"\
|
|
@@ -159,12 +189,17 @@ module Yuuki
|
|
|
159
189
|
params_array << args[name]
|
|
160
190
|
end
|
|
161
191
|
when :keyreq
|
|
162
|
-
|
|
192
|
+
unless args.key?(name)
|
|
193
|
+
raise Yuuki::Error,
|
|
194
|
+
"A required key argument '#{name}' was not found on running #{method.owner}::#{method.name}"
|
|
195
|
+
end
|
|
196
|
+
|
|
163
197
|
params_hash[name] = args[name]
|
|
164
198
|
when :key
|
|
165
199
|
params_hash[name] = args[name] if args.key?(name)
|
|
166
200
|
when :keyrest
|
|
167
201
|
next unless args.key?(name)
|
|
202
|
+
|
|
168
203
|
if args[name].respond_to?(:to_hash)
|
|
169
204
|
params_hash.merge!(args[name])
|
|
170
205
|
else
|
|
@@ -174,8 +209,10 @@ module Yuuki
|
|
|
174
209
|
params_block = args[name]
|
|
175
210
|
end
|
|
176
211
|
end
|
|
177
|
-
params_block = block unless params.any?{|type, _| type == :block}
|
|
212
|
+
params_block = block unless params.any? {|type, _| type == :block}
|
|
178
213
|
params_hash.empty? ? method[*params_array, ¶ms_block] : method[*params_array, **params_hash, ¶ms_block]
|
|
179
214
|
end
|
|
215
|
+
ensure
|
|
216
|
+
yoshinon&.unlock if @use_yoshinon
|
|
180
217
|
end
|
|
181
218
|
end
|
data/lib/yuuki/periodic.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'yuuki/caller'
|
|
4
4
|
require 'yuuki/runner'
|
|
5
|
+
require 'yoshinon'
|
|
5
6
|
|
|
6
7
|
module Yuuki
|
|
7
8
|
module Runner
|
|
@@ -35,7 +36,7 @@ module Yuuki
|
|
|
35
36
|
class PeriodicCaller < Caller
|
|
36
37
|
attr_reader :first_run, :current_time
|
|
37
38
|
|
|
38
|
-
def initialize(*instances)
|
|
39
|
+
def initialize(*instances, use_yoshinon: true)
|
|
39
40
|
super
|
|
40
41
|
@first_run = true
|
|
41
42
|
end
|
|
@@ -59,18 +60,19 @@ module Yuuki
|
|
|
59
60
|
next true if @first_run && meta[:first_run]
|
|
60
61
|
next false unless meta[:periodic]
|
|
61
62
|
next false unless last_time
|
|
63
|
+
|
|
62
64
|
c = @current_time + gmtoff
|
|
63
65
|
l = last_time + gmtoff
|
|
64
|
-
|
|
66
|
+
(l.div(meta[:periodic]) + 1) * meta[:periodic] <= c
|
|
65
67
|
end
|
|
66
68
|
run_select(select_proc, **args, &block)
|
|
67
|
-
rescue
|
|
69
|
+
rescue StandardError
|
|
68
70
|
@on_error ? @on_error[$!] : raise
|
|
69
71
|
end
|
|
70
72
|
@first_run = false
|
|
71
73
|
|
|
72
74
|
last_time = @current_time
|
|
73
|
-
((@current_time + 1).floor - Time.now.to_f).tap{|e| sleep e if e > 0}
|
|
75
|
+
((@current_time + 1).floor - Time.now.to_f).tap {|e| sleep e if e > 0}
|
|
74
76
|
end
|
|
75
77
|
end
|
|
76
78
|
end
|
data/lib/yuuki/version.rb
CHANGED
data/yuuki.gemspec
CHANGED
|
@@ -18,12 +18,13 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
# Specify which files should be added to the gem when it is released.
|
|
19
19
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
20
20
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
21
|
-
`git ls-files -z`.split("\x0").reject{|f| f.match(%r{^(test|spec|features)/})}
|
|
21
|
+
`git ls-files -z`.split("\x0").reject {|f| f.match(%r{^(test|spec|features)/})}
|
|
22
22
|
end
|
|
23
23
|
spec.bindir = 'exe'
|
|
24
|
-
spec.executables = spec.files.grep(%r{^exe/}){|f| File.basename(f)}
|
|
24
|
+
spec.executables = spec.files.grep(%r{^exe/}) {|f| File.basename(f)}
|
|
25
25
|
spec.require_paths = ['lib']
|
|
26
26
|
|
|
27
|
+
spec.add_dependency 'yoshinon'
|
|
27
28
|
spec.add_development_dependency 'bundler'
|
|
28
29
|
spec.add_development_dependency 'pry'
|
|
29
30
|
spec.add_development_dependency 'rake'
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yuuki
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ishotihadus
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-06-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: yoshinon
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: bundler
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -61,6 +75,7 @@ extra_rdoc_files: []
|
|
|
61
75
|
files:
|
|
62
76
|
- ".DS_Store"
|
|
63
77
|
- ".gitignore"
|
|
78
|
+
- ".rubocop.yml"
|
|
64
79
|
- Gemfile
|
|
65
80
|
- LICENSE.txt
|
|
66
81
|
- README.md
|