okuribito 0.2.3 → 0.3.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/.rubocop.yml +4 -0
- data/README.md +14 -9
- data/lib/okuribito.rb +2 -106
- data/lib/okuribito/okuribito_patch.rb +8 -0
- data/lib/okuribito/patch_module.rb +29 -0
- data/lib/okuribito/patcher.rb +79 -0
- data/lib/okuribito/request.rb +23 -0
- data/lib/okuribito/version.rb +2 -1
- metadata +22 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88bb0983550c0142944b2032b5a2b3163326fbe4
|
4
|
+
data.tar.gz: fb8d80772642747ddd4c4346c67de6911f951f6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96e688e28032eb99c33f486c0647c2111704ba849b0de4160ff5617ed2275ba352d9b66bdc3000bd7d4df5257e2b23764109a20ecf2f59e25b83136b48c5542c
|
7
|
+
data.tar.gz: 8e83adc2fb3c9b1e63206d2cdaf88ae625cbaa98fbcdf228daff76da9c51179c71a59b94f2fae43440428e273d22ef2b42a04f991e4c5ec5b205adfce045c982
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -48,7 +48,7 @@ Admin::Manage:
|
|
48
48
|
By writing the following code to start the monitoring of the method.
|
49
49
|
|
50
50
|
```ruby
|
51
|
-
okuribito = Okuribito::
|
51
|
+
okuribito = Okuribito::Request.new do |method_name, obj_name, caller_info|
|
52
52
|
# do something as you like!
|
53
53
|
end
|
54
54
|
okuribito.apply("config/okuribito.yml")
|
@@ -59,7 +59,7 @@ You can also give the option.
|
|
59
59
|
`once_detect`: When it detects a method call, and run only once the code that has been set.
|
60
60
|
|
61
61
|
```ruby
|
62
|
-
okuribito = Okuribito::
|
62
|
+
okuribito = Okuribito::Request.new(once_detect: true) do |method_name, obj_name, caller_info|
|
63
63
|
# do something as you like!
|
64
64
|
end
|
65
65
|
okuribito.apply("config/okuribito.yml")
|
@@ -68,10 +68,10 @@ okuribito.apply("config/okuribito.yml")
|
|
68
68
|
You can also monitor a single method with a string specification.
|
69
69
|
|
70
70
|
```ruby
|
71
|
-
okuribito = Okuribito::
|
71
|
+
okuribito = Okuribito::Request.new do |method_name, obj_name, caller_info|
|
72
72
|
# do something as you like!
|
73
73
|
end
|
74
|
-
okuribito.
|
74
|
+
okuribito.apply_one("TestTarget#deprecated_method")
|
75
75
|
```
|
76
76
|
|
77
77
|
You can use the following parameters when executing arbitrary code.
|
@@ -84,10 +84,10 @@ You can use the following parameters when executing arbitrary code.
|
|
84
84
|
* args
|
85
85
|
|
86
86
|
```ruby
|
87
|
-
okuribito = Okuribito::
|
87
|
+
okuribito = Okuribito::Request.new do |method_name, obj_name, caller_info, class_name, symbol, args|
|
88
88
|
# do something as you like!
|
89
89
|
end
|
90
|
-
okuribito.
|
90
|
+
okuribito.apply_one("TestTarget#deprecated_method_with_args")
|
91
91
|
```
|
92
92
|
|
93
93
|
### ex: Ruby On Rails
|
@@ -97,7 +97,7 @@ Edit `application.rb`
|
|
97
97
|
```ruby
|
98
98
|
class OkuribitoSetting < Rails::Railtie
|
99
99
|
config.after_initialize do
|
100
|
-
okuribito = Okuribito::
|
100
|
+
okuribito = Okuribito::Request.new do |method_name, obj_name, caller_info|
|
101
101
|
# do something as you like!
|
102
102
|
end
|
103
103
|
okuribito.apply("config/okuribito.yml")
|
@@ -119,7 +119,7 @@ class TestTarget
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
okuribito = Okuribito::
|
122
|
+
okuribito = Okuribito::Request.new do |method_name, obj_name, caller_info|
|
123
123
|
puts "#{obj_name} #{method_name} #{caller_info[0]}"
|
124
124
|
end
|
125
125
|
okuribito.apply("config/okuribito.yml")
|
@@ -149,7 +149,7 @@ TestTarget deprecated_self_method example.rb:17:in `<main>'
|
|
149
149
|
### Full stacktrace
|
150
150
|
|
151
151
|
```ruby
|
152
|
-
okuribito = Okuribito::
|
152
|
+
okuribito = Okuribito::Request.new do |method_name, obj_name, caller_info|
|
153
153
|
puts "#############################################################"
|
154
154
|
puts "#{obj_name} #{method_name} #{caller_info[0]}"
|
155
155
|
puts "#############################################################"
|
@@ -161,6 +161,11 @@ okuribito.apply("config/okuribito.yml")
|
|
161
161
|
### Other ideas
|
162
162
|
- Send to Fluentd, TreasureData, Slack...
|
163
163
|
|
164
|
+
## Compatibility
|
165
|
+
- `Okuribito::OkuribitoPatch` has backward compatibility, but it is old class!
|
166
|
+
- Later version 0.3.0, you should use `Okuribito::Request`
|
167
|
+
|
168
|
+
|
164
169
|
## License
|
165
170
|
|
166
171
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/okuribito.rb
CHANGED
@@ -1,110 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "okuribito/version"
|
2
|
-
require "
|
3
|
-
require "active_support"
|
4
|
-
require "active_support/core_ext"
|
3
|
+
require "okuribito/okuribito_patch"
|
5
4
|
|
6
5
|
module Okuribito
|
7
|
-
class OkuribitoPatch
|
8
|
-
CLASS_METHOD_SYMBOL = ".".freeze
|
9
|
-
INSTANCE_METHOD_SYMBOL = "#".freeze
|
10
|
-
PATTERN = /\A(?<symbol>[#{CLASS_METHOD_SYMBOL}#{INSTANCE_METHOD_SYMBOL}])(?<method_name>.+)\z/
|
11
|
-
|
12
|
-
module SimplePatchModule
|
13
|
-
private
|
14
|
-
|
15
|
-
def define_patch(method_name, _patch, _id, _opt = {})
|
16
|
-
define_method(method_name) do |*args|
|
17
|
-
yield(to_s, caller) if block_given?
|
18
|
-
super(*args)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
module FunctionalPatchModule
|
24
|
-
private
|
25
|
-
|
26
|
-
def define_patch(method_name, patch, id, opt = {})
|
27
|
-
sn = method_name.to_s.gsub(/\?/, "__q").gsub(/!/, "__e").gsub(/=/, "__eq")
|
28
|
-
patch.instance_variable_set("@#{sn}_#{id}_called", false)
|
29
|
-
define_method(method_name) do |*args|
|
30
|
-
if block_given? && !patch.instance_variable_get("@#{sn}_#{id}_called")
|
31
|
-
yield(to_s, caller)
|
32
|
-
patch.instance_variable_set("@#{sn}_#{id}_called", true) if opt[:once_detect]
|
33
|
-
end
|
34
|
-
super(*args)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def initialize(opt = {}, &callback)
|
40
|
-
@callback = callback
|
41
|
-
@opt ||= opt
|
42
|
-
end
|
43
|
-
|
44
|
-
def apply(yaml_path)
|
45
|
-
yaml = YAML.load_file(yaml_path)
|
46
|
-
yaml.each do |class_name, observe_methods|
|
47
|
-
patch_okuribito(class_name, observe_methods)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def apply_one(full_method_name)
|
52
|
-
class_name, symbol, method_name = full_method_name.split(/(\.|#)/)
|
53
|
-
patch_okuribito(class_name, [symbol + method_name])
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def patch_okuribito(full_class_name, observe_methods)
|
59
|
-
callback = @callback
|
60
|
-
opt ||= @opt
|
61
|
-
klass = full_class_name.constantize
|
62
|
-
uniq_constant = full_class_name.gsub(/::/, "Sp")
|
63
|
-
i_method_patch = patch_module(opt, "#{uniq_constant}InstancePatch")
|
64
|
-
c_method_patch = patch_module(opt, "#{uniq_constant}ClassPatch")
|
65
|
-
i_method_patched = 0
|
66
|
-
c_method_patched = 0
|
67
|
-
|
68
|
-
klass.class_eval do
|
69
|
-
observe_methods.each do |observe_method|
|
70
|
-
next unless (md = PATTERN.match(observe_method))
|
71
|
-
symbol = md[:symbol]
|
72
|
-
method_name = md[:method_name].to_sym
|
73
|
-
|
74
|
-
case symbol
|
75
|
-
when INSTANCE_METHOD_SYMBOL
|
76
|
-
next unless klass.instance_methods.include?(method_name)
|
77
|
-
i_method_patch.module_eval do
|
78
|
-
define_patch(method_name, i_method_patch, "i", opt) do |obj_name, caller_info|
|
79
|
-
callback.call(method_name, obj_name, caller_info, full_class_name, symbol)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
i_method_patched += 1
|
83
|
-
when CLASS_METHOD_SYMBOL
|
84
|
-
next unless klass.respond_to?(method_name)
|
85
|
-
c_method_patch.module_eval do
|
86
|
-
define_patch(method_name, c_method_patch, "c", opt) do |obj_name, caller_info|
|
87
|
-
callback.call(method_name, obj_name, caller_info, full_class_name, symbol)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
c_method_patched += 1
|
91
|
-
end
|
92
|
-
end
|
93
|
-
prepend i_method_patch if i_method_patched > 0
|
94
|
-
singleton_class.send(:prepend, c_method_patch) if c_method_patched > 0
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def patch_module(opt, patch_name)
|
99
|
-
if opt.present?
|
100
|
-
if FunctionalPatchModule.const_defined?(patch_name)
|
101
|
-
Module.new.extend(FunctionalPatchModule)
|
102
|
-
else
|
103
|
-
FunctionalPatchModule.const_set(patch_name, Module.new.extend(FunctionalPatchModule))
|
104
|
-
end
|
105
|
-
else
|
106
|
-
Module.new.extend(SimplePatchModule)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
6
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Okuribito
|
3
|
+
module SimplePatchModule
|
4
|
+
private
|
5
|
+
|
6
|
+
def define_patch(method_name, _patch, _id, _opt = {})
|
7
|
+
define_method(method_name) do |*args|
|
8
|
+
yield(to_s, caller) if block_given?
|
9
|
+
super(*args)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module FunctionalPatchModule
|
15
|
+
private
|
16
|
+
|
17
|
+
def define_patch(method_name, patch, id, opt = {})
|
18
|
+
sn = method_name.to_s.gsub(/\?/, "__q").gsub(/!/, "__e").gsub(/=/, "__eq")
|
19
|
+
patch.instance_variable_set("@#{sn}_#{id}_called", false)
|
20
|
+
define_method(method_name) do |*args|
|
21
|
+
if block_given? && !patch.instance_variable_get("@#{sn}_#{id}_called")
|
22
|
+
yield(to_s, caller)
|
23
|
+
patch.instance_variable_set("@#{sn}_#{id}_called", true) if opt[:once_detect]
|
24
|
+
end
|
25
|
+
super(*args)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "okuribito/patch_module"
|
3
|
+
require "active_support"
|
4
|
+
require "active_support/core_ext"
|
5
|
+
|
6
|
+
module Okuribito
|
7
|
+
class Patcher
|
8
|
+
CLASS_METHOD_SYMBOL = ".".freeze
|
9
|
+
INSTANCE_METHOD_SYMBOL = "#".freeze
|
10
|
+
PATTERN = /\A(?<symbol>[#{CLASS_METHOD_SYMBOL}#{INSTANCE_METHOD_SYMBOL}])(?<method_name>.+)\z/
|
11
|
+
|
12
|
+
def initialize(opt, callback)
|
13
|
+
@opt = opt
|
14
|
+
@callback = callback
|
15
|
+
end
|
16
|
+
|
17
|
+
def patch_okuribito(full_class_name, observe_methods)
|
18
|
+
opt = @opt
|
19
|
+
callback = @callback
|
20
|
+
klass = full_class_name.safe_constantize
|
21
|
+
unless klass
|
22
|
+
process_undefined_class(full_class_name)
|
23
|
+
return
|
24
|
+
end
|
25
|
+
uniq_constant = full_class_name.gsub(/::/, "Sp")
|
26
|
+
i_method_patch = patch_module("#{uniq_constant}InstancePatch", opt)
|
27
|
+
c_method_patch = patch_module("#{uniq_constant}ClassPatch", opt)
|
28
|
+
i_method_patched = 0
|
29
|
+
c_method_patched = 0
|
30
|
+
|
31
|
+
klass.class_eval do
|
32
|
+
observe_methods.each do |observe_method|
|
33
|
+
next unless (md = PATTERN.match(observe_method))
|
34
|
+
symbol = md[:symbol]
|
35
|
+
method_name = md[:method_name].to_sym
|
36
|
+
|
37
|
+
case symbol
|
38
|
+
when INSTANCE_METHOD_SYMBOL
|
39
|
+
next unless klass.instance_methods.include?(method_name)
|
40
|
+
i_method_patch.module_eval do
|
41
|
+
define_patch(method_name, i_method_patch, "i", opt) do |obj_name, caller_info|
|
42
|
+
callback.call(method_name, obj_name, caller_info, full_class_name, symbol)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
i_method_patched += 1
|
46
|
+
when CLASS_METHOD_SYMBOL
|
47
|
+
next unless klass.respond_to?(method_name)
|
48
|
+
c_method_patch.module_eval do
|
49
|
+
define_patch(method_name, c_method_patch, "c", opt) do |obj_name, caller_info|
|
50
|
+
callback.call(method_name, obj_name, caller_info, full_class_name, symbol)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
c_method_patched += 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
prepend i_method_patch if i_method_patched > 0
|
57
|
+
singleton_class.send(:prepend, c_method_patch) if c_method_patched > 0
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def patch_module(patch_name, opt)
|
64
|
+
if opt.present?
|
65
|
+
if FunctionalPatchModule.const_defined?(patch_name)
|
66
|
+
Module.new.extend(FunctionalPatchModule)
|
67
|
+
else
|
68
|
+
FunctionalPatchModule.const_set(patch_name, Module.new.extend(FunctionalPatchModule))
|
69
|
+
end
|
70
|
+
else
|
71
|
+
Module.new.extend(SimplePatchModule)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def process_undefined_class(_full_class_name)
|
76
|
+
# do nothing....
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "okuribito/patcher"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module Okuribito
|
6
|
+
class Request
|
7
|
+
def initialize(opt = {}, &callback)
|
8
|
+
@patcher = Patcher.new(opt, callback)
|
9
|
+
end
|
10
|
+
|
11
|
+
def apply(yaml_path)
|
12
|
+
yaml = YAML.load_file(yaml_path)
|
13
|
+
yaml.each do |class_name, observe_methods|
|
14
|
+
@patcher.patch_okuribito(class_name, observe_methods)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def apply_one(full_method_name)
|
19
|
+
class_name, symbol, method_name = full_method_name.split(/(\.|#)/)
|
20
|
+
@patcher.patch_okuribito(class_name, [symbol + method_name])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/okuribito/version.rb
CHANGED
metadata
CHANGED
@@ -1,83 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: okuribito
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- muramurasan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '3.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rubocop
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: simplecov
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: codeclimate-test-reporter
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 1.0.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 1.0.0
|
83
83
|
description: Okuribito monitors the method call, and exec specified code.
|
@@ -87,9 +87,9 @@ executables: []
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
-
- .gitignore
|
91
|
-
- .rspec
|
92
|
-
- .rubocop.yml
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".rubocop.yml"
|
93
93
|
- CHANGELOG.md
|
94
94
|
- Gemfile
|
95
95
|
- LICENSE.txt
|
@@ -97,6 +97,10 @@ files:
|
|
97
97
|
- Rakefile
|
98
98
|
- circle.yml
|
99
99
|
- lib/okuribito.rb
|
100
|
+
- lib/okuribito/okuribito_patch.rb
|
101
|
+
- lib/okuribito/patch_module.rb
|
102
|
+
- lib/okuribito/patcher.rb
|
103
|
+
- lib/okuribito/request.rb
|
100
104
|
- lib/okuribito/version.rb
|
101
105
|
- okuribito.gemspec
|
102
106
|
- okuribito_logo.png
|
@@ -110,17 +114,17 @@ require_paths:
|
|
110
114
|
- lib
|
111
115
|
required_ruby_version: !ruby/object:Gem::Requirement
|
112
116
|
requirements:
|
113
|
-
- -
|
117
|
+
- - ">="
|
114
118
|
- !ruby/object:Gem::Version
|
115
119
|
version: 2.0.0
|
116
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
121
|
requirements:
|
118
|
-
- -
|
122
|
+
- - ">="
|
119
123
|
- !ruby/object:Gem::Version
|
120
124
|
version: '0'
|
121
125
|
requirements: []
|
122
126
|
rubyforge_project:
|
123
|
-
rubygems_version: 2.
|
127
|
+
rubygems_version: 2.5.1
|
124
128
|
signing_key:
|
125
129
|
specification_version: 4
|
126
130
|
summary: Okuribito monitors the method call, and exec specified code.
|