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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbc6115f9c7818a9c171c7c8928321bdd7c5fd737ce7f1cbed4024c56dfd2d91
4
- data.tar.gz: 148536d6a0e91a93994f12cb4672b8cdafe1e77e476b89532455bbcf47f3aaa4
3
+ metadata.gz: 4bc4e09cca35420bedfbe0e86cef17ed348f490f525913ad57171fc4651bb666
4
+ data.tar.gz: 27fb3f53e3c5323fa993ccf0c6b6d7eb432d088b2a47474197be35adaa07fc66
5
5
  SHA512:
6
- metadata.gz: 89b3a2e35810e21a94a096debaa2d709806702340ef23a0fcbe55cc73656cf263f8bef4ddbc4fbacf47c62516821dc94d11ad23948bdb0911bfcb49cb0271527
7
- data.tar.gz: 7b67f83e432c5da9d028fbd417c2f08b6c4007dc0bdb31e836c4ad4aa691c98f3c64d02e54b0c9c8f2141d40f64332d97e71b6f3f5ea8559442a1b796b57828b
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in yuuki.gemspec
6
6
  gemspec
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "yuuki"
3
+ require 'bundler/setup'
4
+ require 'yuuki'
5
5
 
6
- require "pry"
6
+ require 'pry'
7
7
  Pry.start
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
- raise Yuuki::Error, 'Runner instance must be extend Yuuki::Runner' unless klass.singleton_class.include?(Yuuki::Runner)
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
- raise Yuuki::Error, 'Runner instance must be extend Yuuki::Runner' unless instance.class.singleton_class.include?(Yuuki::Runner)
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
- run_select(proc{|_method, meta| meta[:tags]&.intersect?(tags)}, **args, &block)
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
- raise Yuuki::Error, "A required argument '#{name}' was not found on running #{method.owner}::#{method.name}" unless args.key?(name)
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
- raise Yuuki::Error, "A required key argument '#{name}' was not found on running #{method.owner}::#{method.name}" unless args.key?(name)
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, &params_block] : method[*params_array, **params_hash, &params_block]
179
214
  end
215
+ ensure
216
+ yoshinon&.unlock if @use_yoshinon
180
217
  end
181
218
  end
@@ -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
- next true if (l.div(meta[:periodic]) + 1) * meta[:periodic] <= c
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Yuuki
4
- VERSION = '0.1.4'
4
+ VERSION = '0.1.8'
5
5
  end
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
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-05-01 00:00:00.000000000 Z
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