appmap 0.34.0 → 0.35.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/.gitignore +1 -1
- data/.rbenv-gemsets +1 -0
- data/CHANGELOG.md +31 -0
- data/README.md +17 -2
- data/Rakefile +10 -3
- data/appmap.gemspec +5 -0
- data/ext/appmap/appmap.c +95 -0
- data/ext/appmap/extconf.rb +6 -0
- data/lib/appmap.rb +4 -1
- data/lib/appmap/class_map.rb +5 -6
- data/lib/appmap/config.rb +2 -2
- data/lib/appmap/cucumber.rb +19 -2
- data/lib/appmap/event.rb +28 -10
- data/lib/appmap/hook.rb +13 -20
- data/lib/appmap/hook/method.rb +59 -27
- data/lib/appmap/rails/request_handler.rb +88 -0
- data/lib/appmap/rails/sql_handler.rb +13 -10
- data/lib/appmap/railtie.rb +3 -5
- data/lib/appmap/rspec.rb +10 -0
- data/lib/appmap/trace.rb +9 -7
- data/lib/appmap/util.rb +18 -1
- data/lib/appmap/version.rb +1 -1
- data/spec/abstract_controller4_base_spec.rb +1 -1
- data/spec/abstract_controller_base_spec.rb +6 -0
- data/spec/fixtures/hook/instance_method.rb +4 -0
- data/spec/fixtures/hook/singleton_method.rb +21 -12
- data/spec/hook_spec.rb +85 -8
- metadata +50 -4
- data/lib/appmap/rails/action_handler.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 587d9e4e90152c5ab6b04d4fa6b95d3071419563d82f4ed3c609def87111757b
|
4
|
+
data.tar.gz: b1867167f44a1f244e165a628293415dd54bcaacb0b4471c5d30c26dce3bef64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23a6e927bda905ce13666aa514040415bbaf0b8f317ffac524b1f0f94de58de17c175e001c921825ac0cbe05287a3e137899e5a5f86609cdbd9ce4000b4cbe4f
|
7
|
+
data.tar.gz: dcd2ad0a96709cc28f383726c56e133a75ba81e3edbd6679913afc7c1ae4097c3767c79b07ebf5bc9357c40660be00d39205dcbf4c1316a7add323b613a2f1a3
|
data/.gitignore
CHANGED
data/.rbenv-gemsets
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
appmap-ruby
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
# v0.35.0
|
2
|
+
* Provide a custom display string for files and HTTP requests.
|
3
|
+
* Report `mime_type` on HTTP response.
|
4
|
+
|
5
|
+
# v0.34.6
|
6
|
+
* Only warn once about problems determining database version for an ActiveRecord
|
7
|
+
connection.
|
8
|
+
|
9
|
+
# v0.34.5
|
10
|
+
* Ensure that hooking a method doesn't change its arity.
|
11
|
+
|
12
|
+
# v0.34.4
|
13
|
+
* Make sure `AppMap:Rails::SQLExaminer::ActiveRecordExaminer.server_version` only calls
|
14
|
+
`ActiveRecord::Base.connection.database_version` if it's available.
|
15
|
+
* Fix `AppMap:Rails::SQLExaminer::ActiveRecordExaminer.database_type` returns `:postgres`
|
16
|
+
in all supported versions of Rails.
|
17
|
+
|
18
|
+
# v0.34.3
|
19
|
+
* Fix a crash in `singleton_method_owner_name` that occurred if `__attached__.class` returned
|
20
|
+
something other than a `Module` or a `Class`.
|
21
|
+
|
22
|
+
# v0.34.2
|
23
|
+
* Add an extension that gets the name of the owner of a singleton method without calling
|
24
|
+
any methods that may have been redefined (e.g. `#to_s` or `.name`).
|
25
|
+
|
26
|
+
# v0.34.1
|
27
|
+
* Ensure that capturing events doesn't change the behavior of a hooked method that uses
|
28
|
+
`Time.now`. For example, if a test expects that `Time.now` will be called a certain
|
29
|
+
number of times by a hooked method, that expectation will now be met.
|
30
|
+
* Make sure `appmap/cucumber` requires `appmap`.
|
31
|
+
|
1
32
|
# v0.34.0
|
2
33
|
|
3
34
|
* Records builtin security and I/O methods from `OpenSSL`, `Net`, and `IO`.
|
data/README.md
CHANGED
@@ -57,6 +57,15 @@ end
|
|
57
57
|
|
58
58
|
Then install with `bundle`.
|
59
59
|
|
60
|
+
**Railtie**
|
61
|
+
|
62
|
+
If you are using Ruby on Rails, require the railtie after Rails is loaded.
|
63
|
+
|
64
|
+
```
|
65
|
+
# application.rb is a good place to do this, along with all the other railties.
|
66
|
+
require 'appmap/railtie'
|
67
|
+
```
|
68
|
+
|
60
69
|
# Configuration
|
61
70
|
|
62
71
|
When you run your program, the `appmap` gem reads configuration settings from `appmap.yml`. Here's a sample configuration
|
@@ -267,7 +276,13 @@ $ bundle config local.appmap $(pwd)
|
|
267
276
|
Run the tests via `rake`:
|
268
277
|
```
|
269
278
|
$ bundle exec rake test
|
270
|
-
```
|
279
|
+
```
|
280
|
+
|
281
|
+
The `test` target will build the native extension first, then run the tests. If you need
|
282
|
+
to build the extension separately, run
|
283
|
+
```
|
284
|
+
$ bundle exec rake compile
|
285
|
+
```
|
271
286
|
|
272
287
|
## Using fixture apps
|
273
288
|
|
@@ -286,7 +301,7 @@ resources such as a PostgreSQL database.
|
|
286
301
|
To build the fixture container images, first run:
|
287
302
|
|
288
303
|
```sh-session
|
289
|
-
$ bundle exec rake fixtures:all
|
304
|
+
$ bundle exec rake build:fixtures:all
|
290
305
|
```
|
291
306
|
|
292
307
|
This will build the `appmap.gem`, along with a Docker image for each fixture app.
|
data/Rakefile
CHANGED
@@ -6,6 +6,13 @@ require 'rdoc/task'
|
|
6
6
|
|
7
7
|
require 'open3'
|
8
8
|
|
9
|
+
require "rake/extensiontask"
|
10
|
+
|
11
|
+
desc 'build the native extension'
|
12
|
+
Rake::ExtensionTask.new("appmap") do |ext|
|
13
|
+
ext.lib_dir = "lib/appmap"
|
14
|
+
end
|
15
|
+
|
9
16
|
namespace 'gem' do
|
10
17
|
require 'bundler/gem_tasks'
|
11
18
|
end
|
@@ -104,7 +111,7 @@ end
|
|
104
111
|
namespace :spec do
|
105
112
|
RUBY_VERSIONS.each do |ruby_version|
|
106
113
|
desc ruby_version
|
107
|
-
task ruby_version, [:specs] => ["build:fixtures:#{ruby_version}:all"] do |_, task_args|
|
114
|
+
task ruby_version, [:specs] => ["compile", "build:fixtures:#{ruby_version}:all"] do |_, task_args|
|
108
115
|
run_specs(ruby_version, task_args)
|
109
116
|
end.tap do|t|
|
110
117
|
desc "Run all specs"
|
@@ -119,13 +126,13 @@ Rake::RDocTask.new do |rd|
|
|
119
126
|
rd.title = 'AppMap'
|
120
127
|
end
|
121
128
|
|
122
|
-
Rake::TestTask.new(:
|
129
|
+
Rake::TestTask.new(minitest: 'compile') do |t|
|
123
130
|
t.libs << 'test'
|
124
131
|
t.libs << 'lib'
|
125
132
|
t.test_files = FileList['test/*_test.rb']
|
126
133
|
end
|
127
134
|
|
128
|
-
task spec:
|
135
|
+
task spec: %i[spec:all]
|
129
136
|
|
130
137
|
task test: %i[spec:all minitest]
|
131
138
|
|
data/appmap.gemspec
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
19
|
spec.files = `git ls-files --no-deleted`.split("
|
20
20
|
")
|
21
|
+
spec.extensions << "ext/appmap/extconf.rb"
|
22
|
+
|
21
23
|
spec.bindir = 'exe'
|
22
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
25
|
spec.require_paths = ['lib']
|
@@ -34,6 +36,7 @@ Gem::Specification.new do |spec|
|
|
34
36
|
spec.add_development_dependency 'rake', '>= 12.3.3'
|
35
37
|
spec.add_development_dependency 'rdoc'
|
36
38
|
spec.add_development_dependency 'rubocop'
|
39
|
+
spec.add_development_dependency "rake-compiler"
|
37
40
|
|
38
41
|
# Testing
|
39
42
|
spec.add_development_dependency 'climate_control'
|
@@ -42,4 +45,6 @@ Gem::Specification.new do |spec|
|
|
42
45
|
spec.add_development_dependency 'rspec'
|
43
46
|
spec.add_development_dependency 'selenium-webdriver'
|
44
47
|
spec.add_development_dependency 'webdrivers', '~> 4.0'
|
48
|
+
spec.add_development_dependency 'timecop'
|
49
|
+
spec.add_development_dependency 'hashie'
|
45
50
|
end
|
data/ext/appmap/appmap.c
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <ruby/intern.h>
|
3
|
+
|
4
|
+
// Seems like CLASS_OR_MODULE_P should really be in a header file in
|
5
|
+
// the ruby source -- it's in object.c and duplicated in eval.c. In
|
6
|
+
// the future, we'll fail if it does get moved to a header.
|
7
|
+
#define CLASS_OR_MODULE_P(obj) \
|
8
|
+
(!SPECIAL_CONST_P(obj) && \
|
9
|
+
(BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE))
|
10
|
+
|
11
|
+
#define ARITIES_KEY "__arities__"
|
12
|
+
|
13
|
+
VALUE am_AppMapHook;
|
14
|
+
|
15
|
+
static VALUE
|
16
|
+
singleton_method_owner_name(VALUE klass, VALUE method)
|
17
|
+
{
|
18
|
+
VALUE owner = rb_funcall(method, rb_intern("owner"), 0);
|
19
|
+
VALUE attached = rb_ivar_get(owner, rb_intern("__attached__"));
|
20
|
+
if (!CLASS_OR_MODULE_P(attached)) {
|
21
|
+
attached = rb_funcall(attached, rb_intern("class"), 0);
|
22
|
+
}
|
23
|
+
|
24
|
+
// Did __attached__.class return an object that's a Module or a
|
25
|
+
// Class?
|
26
|
+
if (CLASS_OR_MODULE_P(attached)) {
|
27
|
+
// Yup, get it's name
|
28
|
+
return rb_mod_name(attached);
|
29
|
+
}
|
30
|
+
|
31
|
+
// Nope (which seems weird, but whatever). Fall back to calling
|
32
|
+
// #to_s on the method's owner and hope for the best.
|
33
|
+
return rb_funcall(owner, rb_intern("to_s"), 0);
|
34
|
+
}
|
35
|
+
|
36
|
+
|
37
|
+
static VALUE
|
38
|
+
am_define_method_with_arity(VALUE mod, VALUE name, VALUE arity, VALUE proc)
|
39
|
+
{
|
40
|
+
VALUE arities_key = rb_intern(ARITIES_KEY);
|
41
|
+
VALUE arities = rb_ivar_get(mod, arities_key);
|
42
|
+
|
43
|
+
if (arities == Qundef || NIL_P(arities)) {
|
44
|
+
arities = rb_hash_new();
|
45
|
+
rb_ivar_set(mod, arities_key, arities);
|
46
|
+
}
|
47
|
+
rb_hash_aset(arities, name, arity);
|
48
|
+
|
49
|
+
return rb_funcall(mod, rb_intern("define_method"), 2, name, proc);
|
50
|
+
}
|
51
|
+
|
52
|
+
static VALUE
|
53
|
+
am_get_method_arity(VALUE method, VALUE orig_arity_method)
|
54
|
+
{
|
55
|
+
VALUE owner = rb_funcall(method, rb_intern("owner"), 0);
|
56
|
+
VALUE arities = rb_ivar_get(owner, rb_intern(ARITIES_KEY));
|
57
|
+
VALUE name = rb_funcall(method, rb_intern("name"), 0);
|
58
|
+
VALUE arity = Qnil;
|
59
|
+
// See if we saved an arity for the method.
|
60
|
+
if (!NIL_P(arities)) {
|
61
|
+
arity = rb_hash_aref(arities, name);
|
62
|
+
}
|
63
|
+
// Didn't find one, call the original method.
|
64
|
+
if (NIL_P(arity)) {
|
65
|
+
VALUE bound_method = rb_funcall(orig_arity_method, rb_intern("bind"), 1, method);
|
66
|
+
arity = rb_funcall(bound_method, rb_intern("call"), 0);
|
67
|
+
}
|
68
|
+
|
69
|
+
return arity;
|
70
|
+
}
|
71
|
+
|
72
|
+
static VALUE
|
73
|
+
am_unbound_method_arity(VALUE method)
|
74
|
+
{
|
75
|
+
VALUE orig_unbound_method_arity = rb_ivar_get(am_AppMapHook, rb_intern("@unbound_method_arity"));
|
76
|
+
return am_get_method_arity(method, orig_unbound_method_arity);
|
77
|
+
}
|
78
|
+
|
79
|
+
static VALUE
|
80
|
+
am_method_arity(VALUE method)
|
81
|
+
{
|
82
|
+
VALUE orig_method_arity = rb_ivar_get(am_AppMapHook, rb_intern("@method_arity"));
|
83
|
+
return am_get_method_arity(method, orig_method_arity);
|
84
|
+
}
|
85
|
+
|
86
|
+
void Init_appmap() {
|
87
|
+
VALUE appmap = rb_define_module("AppMap");
|
88
|
+
am_AppMapHook = rb_define_class_under(appmap, "Hook", rb_cObject);
|
89
|
+
|
90
|
+
rb_define_singleton_method(am_AppMapHook, "singleton_method_owner_name", singleton_method_owner_name, 1);
|
91
|
+
|
92
|
+
rb_define_method(rb_cModule, "define_method_with_arity", am_define_method_with_arity, 3);
|
93
|
+
rb_define_method(rb_cUnboundMethod, "arity", am_unbound_method_arity, 0);
|
94
|
+
rb_define_method(rb_cMethod, "arity", am_method_arity, 0);
|
95
|
+
}
|
data/lib/appmap.rb
CHANGED
@@ -16,6 +16,9 @@ require 'appmap/metadata'
|
|
16
16
|
require 'appmap/util'
|
17
17
|
require 'appmap/open'
|
18
18
|
|
19
|
+
# load extension
|
20
|
+
require 'appmap/appmap'
|
21
|
+
|
19
22
|
module AppMap
|
20
23
|
class << self
|
21
24
|
@configuration = nil
|
@@ -81,7 +84,7 @@ module AppMap
|
|
81
84
|
|
82
85
|
# Builds a class map from a config and a list of Ruby methods.
|
83
86
|
def class_map(methods)
|
84
|
-
ClassMap.build_from_methods(
|
87
|
+
ClassMap.build_from_methods(methods)
|
85
88
|
end
|
86
89
|
|
87
90
|
# Returns default metadata detected from the Ruby system and from the
|
data/lib/appmap/class_map.rb
CHANGED
@@ -61,25 +61,24 @@ module AppMap
|
|
61
61
|
location: location,
|
62
62
|
static: static,
|
63
63
|
labels: labels
|
64
|
-
}.delete_if { |
|
64
|
+
}.delete_if { |_, v| v.nil? || v == [] }
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
69
|
class << self
|
70
|
-
def build_from_methods(
|
70
|
+
def build_from_methods(methods)
|
71
71
|
root = Types::Root.new
|
72
72
|
methods.each do |method|
|
73
|
-
|
74
|
-
or raise "No package found for method #{method}"
|
75
|
-
add_function root, package, method
|
73
|
+
add_function root, method
|
76
74
|
end
|
77
75
|
root.children.map(&:to_h)
|
78
76
|
end
|
79
77
|
|
80
78
|
protected
|
81
79
|
|
82
|
-
def add_function(root,
|
80
|
+
def add_function(root, method)
|
81
|
+
package = method.package
|
83
82
|
static = method.static
|
84
83
|
|
85
84
|
object_infos = [
|
data/lib/appmap/config.rb
CHANGED
@@ -6,7 +6,7 @@ module AppMap
|
|
6
6
|
def initialize(path, package_name: nil, exclude: [], labels: [])
|
7
7
|
super path, package_name, exclude, labels
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def to_h
|
11
11
|
{
|
12
12
|
path: path,
|
@@ -105,7 +105,7 @@ module AppMap
|
|
105
105
|
hook = find_hook(defined_class)
|
106
106
|
return nil unless hook
|
107
107
|
|
108
|
-
Array(hook.method_names).include?(method_name) ? hook.package : nil
|
108
|
+
Array(hook.method_names).include?(method_name) ? hook.package : nil
|
109
109
|
end
|
110
110
|
|
111
111
|
def find_hook(defined_class)
|
data/lib/appmap/cucumber.rb
CHANGED
@@ -4,6 +4,8 @@ require 'appmap/util'
|
|
4
4
|
|
5
5
|
module AppMap
|
6
6
|
module Cucumber
|
7
|
+
APPMAP_OUTPUT_DIR = 'tmp/appmap/cucumber'
|
8
|
+
|
7
9
|
ScenarioAttributes = Struct.new(:name, :feature, :feature_group)
|
8
10
|
|
9
11
|
ProviderStruct = Struct.new(:scenario) do
|
@@ -38,18 +40,27 @@ module AppMap
|
|
38
40
|
end
|
39
41
|
|
40
42
|
class << self
|
43
|
+
def init
|
44
|
+
warn 'Configuring AppMap recorder for Cucumber'
|
45
|
+
|
46
|
+
FileUtils.mkdir_p APPMAP_OUTPUT_DIR
|
47
|
+
end
|
48
|
+
|
41
49
|
def write_scenario(scenario, appmap)
|
42
50
|
appmap['metadata'] = update_metadata(scenario, appmap['metadata'])
|
43
51
|
scenario_filename = AppMap::Util.scenario_filename(appmap['metadata']['name'])
|
44
52
|
|
45
|
-
|
46
|
-
File.write(File.join('tmp/appmap/cucumber', scenario_filename), JSON.generate(appmap))
|
53
|
+
File.write(File.join(APPMAP_OUTPUT_DIR, scenario_filename), JSON.generate(appmap))
|
47
54
|
end
|
48
55
|
|
49
56
|
def enabled?
|
50
57
|
ENV['APPMAP'] == 'true'
|
51
58
|
end
|
52
59
|
|
60
|
+
def run
|
61
|
+
init
|
62
|
+
end
|
63
|
+
|
53
64
|
protected
|
54
65
|
|
55
66
|
def cucumber_version
|
@@ -87,3 +98,9 @@ module AppMap
|
|
87
98
|
end
|
88
99
|
end
|
89
100
|
end
|
101
|
+
|
102
|
+
if AppMap::Cucumber.enabled?
|
103
|
+
require 'appmap'
|
104
|
+
|
105
|
+
AppMap::Cucumber.run
|
106
|
+
end
|
data/lib/appmap/event.rb
CHANGED
@@ -36,20 +36,38 @@ module AppMap
|
|
36
36
|
'*Error inspecting variable*'
|
37
37
|
end
|
38
38
|
|
39
|
-
value_string =
|
39
|
+
value_string = custom_display_string(value) || default_display_string(value)
|
40
|
+
|
41
|
+
(value_string||'')[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def custom_display_string(value)
|
47
|
+
case value
|
48
|
+
when File
|
49
|
+
"#{value.class}[path=#{value.path}]"
|
50
|
+
when Net::HTTP
|
51
|
+
"#{value.class}[#{value.address}:#{value.port}]"
|
52
|
+
when Net::HTTPGenericRequest
|
53
|
+
"#{value.class}[#{value.method} #{value.path}]"
|
54
|
+
end
|
55
|
+
rescue StandardError
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def default_display_string(value)
|
60
|
+
begin
|
61
|
+
value.to_s
|
62
|
+
rescue NoMethodError
|
40
63
|
begin
|
41
|
-
value.
|
42
|
-
rescue NoMethodError
|
43
|
-
begin
|
44
|
-
value.inspect
|
45
|
-
rescue StandardError
|
46
|
-
last_resort_string.call
|
47
|
-
end
|
64
|
+
value.inspect
|
48
65
|
rescue StandardError
|
49
66
|
last_resort_string.call
|
50
67
|
end
|
51
|
-
|
52
|
-
|
68
|
+
rescue StandardError
|
69
|
+
last_resort_string.call
|
70
|
+
end
|
53
71
|
end
|
54
72
|
end
|
55
73
|
end
|
data/lib/appmap/hook.rb
CHANGED
@@ -6,6 +6,9 @@ module AppMap
|
|
6
6
|
class Hook
|
7
7
|
LOG = (ENV['DEBUG'] == 'true')
|
8
8
|
|
9
|
+
@unbound_method_arity = ::UnboundMethod.instance_method(:arity)
|
10
|
+
@method_arity = ::Method.instance_method(:arity)
|
11
|
+
|
9
12
|
class << self
|
10
13
|
def lock_builtins
|
11
14
|
return if @builtins_hooked
|
@@ -17,18 +20,7 @@ module AppMap
|
|
17
20
|
# the given method.
|
18
21
|
def qualify_method_name(method)
|
19
22
|
if method.owner.singleton_class?
|
20
|
-
|
21
|
-
# #<Class:Foo> or
|
22
|
-
# #<Class:#<Bar:0x0123ABC>>. Retrieve the name of
|
23
|
-
# the class from the string.
|
24
|
-
#
|
25
|
-
# (There really isn't a better way to do this. The
|
26
|
-
# singleton's reference to the class it was created
|
27
|
-
# from is stored in an instance variable named
|
28
|
-
# '__attached__'. It doesn't have the '@' prefix, so
|
29
|
-
# it's internal only, and not accessible from user
|
30
|
-
# code.)
|
31
|
-
class_name = /#<Class:((#<(?<cls>.*?):)|((?<cls>.*?)>))/.match(method.owner.to_s)['cls']
|
23
|
+
class_name = singleton_method_owner_name(method)
|
32
24
|
[ class_name, '.', method.name ]
|
33
25
|
else
|
34
26
|
[ method.owner.name, '#', method.name ]
|
@@ -56,22 +48,23 @@ module AppMap
|
|
56
48
|
hook = lambda do |hook_cls|
|
57
49
|
lambda do |method_id|
|
58
50
|
method = hook_cls.public_instance_method(method_id)
|
59
|
-
hook_method = Hook::Method.new(hook_cls, method)
|
60
51
|
|
61
|
-
warn "AppMap: Examining #{
|
52
|
+
warn "AppMap: Examining #{hook_cls} #{method.name}" if LOG
|
62
53
|
|
63
54
|
disasm = RubyVM::InstructionSequence.disasm(method)
|
64
55
|
# Skip methods that have no instruction sequence, as they are obviously trivial.
|
65
56
|
next unless disasm
|
66
57
|
|
58
|
+
next unless \
|
59
|
+
config.always_hook?(hook_cls, method.name) ||
|
60
|
+
config.included_by_location?(method)
|
61
|
+
|
62
|
+
hook_method = Hook::Method.new(config.package_for_method(method), hook_cls, method)
|
63
|
+
|
67
64
|
# Don't try and trace the AppMap methods or there will be
|
68
65
|
# a stack overflow in the defined hook method.
|
69
66
|
next if /\AAppMap[:\.]/.match?(hook_method.method_display_name)
|
70
67
|
|
71
|
-
next unless \
|
72
|
-
config.always_hook?(hook_method.defined_class, method.name) ||
|
73
|
-
config.included_by_location?(method)
|
74
|
-
|
75
68
|
hook_method.activate
|
76
69
|
end
|
77
70
|
end
|
@@ -105,9 +98,9 @@ module AppMap
|
|
105
98
|
end
|
106
99
|
|
107
100
|
if method
|
108
|
-
Hook::Method.new(cls, method).activate
|
101
|
+
Hook::Method.new(hook.package, cls, method).activate
|
109
102
|
else
|
110
|
-
warn "Method #{method_name} not found on #{cls.name}"
|
103
|
+
warn "Method #{method_name} not found on #{cls.name}"
|
111
104
|
end
|
112
105
|
end
|
113
106
|
end
|