appmap 0.54.0 → 0.55.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/.travis.yml +16 -10
- data/CHANGELOG.md +45 -0
- data/Rakefile +13 -4
- data/appmap.gemspec +1 -0
- data/lib/appmap.rb +6 -7
- data/lib/appmap/config.rb +1 -1
- data/lib/appmap/event.rb +32 -2
- data/lib/appmap/handler/net_http.rb +1 -1
- data/lib/appmap/handler/rails/template.rb +2 -1
- data/lib/appmap/hook.rb +35 -3
- data/lib/appmap/hook/method.rb +41 -28
- data/lib/appmap/trace.rb +2 -0
- data/lib/appmap/util.rb +18 -2
- data/lib/appmap/version.rb +1 -1
- data/release.sh +0 -1
- data/spec/fixtures/hook/kwargs.rb +11 -0
- data/spec/hook_spec.rb +10 -1
- data/spec/record_net_http_spec.rb +1 -0
- 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: dfd518bd44a86f1270fe90e70c397e213763dd582260ace7c5a01898b94030d2
|
4
|
+
data.tar.gz: cf449bff5700a1bfd5efabda40ccd59c5281d595aa34ca551d6a3b4b1f89f5f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1824e49817ccceca6571fb2cb6f4a3033fb4873bb184577ec3989af3d74d09aecbf7685f9ce9f7efeb2a43e811f9477b0cfc5c6f6778ba3ec8d141c37560112c
|
7
|
+
data.tar.gz: da796d7072dab9b505f6fe1220ae3987e0577be458dfb1253b3d4b860df41d7a4856640629dd300ebcb6588f350f4f55af2b867bf730d0a65e90788c0f2eeb0d
|
data/.travis.yml
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
|
+
rbenv:
|
4
|
+
- 2.5
|
5
|
+
- 2.6
|
6
|
+
- 2.7
|
7
|
+
|
3
8
|
addons:
|
4
9
|
apt:
|
5
10
|
packages:
|
@@ -29,28 +34,29 @@ before_install:
|
|
29
34
|
- |
|
30
35
|
nvm install --lts \
|
31
36
|
&& nvm use --lts
|
32
|
-
|
37
|
+
|
33
38
|
# GEM_ALTERNATIVE_NAME only needed for deployment
|
34
39
|
jobs:
|
35
40
|
include:
|
36
41
|
- stage: test
|
37
42
|
script:
|
43
|
+
- set -e
|
38
44
|
- mkdir tmp
|
39
|
-
-
|
45
|
+
- npm i -g yarn
|
46
|
+
- GEM_ALTERNATIVE_NAME='' bundle exec rake gem:build test
|
40
47
|
|
41
|
-
|
42
48
|
before_deploy:
|
43
49
|
- |
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
semantic-release-rubygem
|
50
|
+
npm i -g \
|
51
|
+
yarn \
|
52
|
+
semantic-release \
|
53
|
+
@semantic-release/git \
|
54
|
+
@semantic-release/changelog \
|
55
|
+
semantic-release-rubygem
|
51
56
|
|
52
57
|
deploy:
|
53
58
|
- provider: script
|
54
59
|
script: ./release.sh
|
55
60
|
on:
|
56
61
|
branch: master
|
62
|
+
condition: "$TRAVIS_RUBY_VERSION = 2.7"
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,48 @@
|
|
1
|
+
# [0.55.0](https://github.com/applandinc/appmap-ruby/compare/v0.54.4...v0.55.0) (2021-06-28)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* Avoid calling == ([f30ed9f](https://github.com/applandinc/appmap-ruby/commit/f30ed9f309753252df35e372d925db3b914260d4))
|
7
|
+
* Log dynamic loading of appmap helpers at info level ([15dcd3c](https://github.com/applandinc/appmap-ruby/commit/15dcd3c913fa1c32aea034b28ddae59668efa217))
|
8
|
+
* Remove dynamic loading of rake and rspec helpers ([6790970](https://github.com/applandinc/appmap-ruby/commit/67909702f3c8a52081ef1e23a87c292908883334))
|
9
|
+
|
10
|
+
|
11
|
+
### Features
|
12
|
+
|
13
|
+
* APPMAP_PROFILE_DISPLAY_STRING and APPMAP_OBJECT_STRING ([3f5daa8](https://github.com/applandinc/appmap-ruby/commit/3f5daa890bfbfd39b7f825794d0c43da509b3201))
|
14
|
+
* Package name to require can be specified when hooking a gem ([fcc5eb6](https://github.com/applandinc/appmap-ruby/commit/fcc5eb691a0330444560eb4c2afe7fc3c4c8afa8))
|
15
|
+
* Profile packaging hooking ([c020a31](https://github.com/applandinc/appmap-ruby/commit/c020a312f4545348ec7cc302443269c57a7fc026))
|
16
|
+
|
17
|
+
## [0.54.4](https://github.com/applandinc/appmap-ruby/compare/v0.54.3...v0.54.4) (2021-06-27)
|
18
|
+
|
19
|
+
|
20
|
+
### Bug Fixes
|
21
|
+
|
22
|
+
* Only allow trace_end once per location ([10e48cf](https://github.com/applandinc/appmap-ruby/commit/10e48cf855907f9029479b4b7b63bc4d25d664ab))
|
23
|
+
|
24
|
+
## [0.54.3](https://github.com/applandinc/appmap-ruby/compare/v0.54.2...v0.54.3) (2021-06-25)
|
25
|
+
|
26
|
+
|
27
|
+
### Bug Fixes
|
28
|
+
|
29
|
+
* Get deployment working with packaging of NodeJS code ([733c5b8](https://github.com/applandinc/appmap-ruby/commit/733c5b85ec1a0c17ada81be524fa572f78f52500))
|
30
|
+
|
31
|
+
## [0.54.2](https://github.com/applandinc/appmap-ruby/compare/v0.54.1...v0.54.2) (2021-06-25)
|
32
|
+
|
33
|
+
|
34
|
+
### Bug Fixes
|
35
|
+
|
36
|
+
* Require appmap/railtie if Rails is defined ([66b4cbd](https://github.com/applandinc/appmap-ruby/commit/66b4cbd4d418695b0e69150d253dfd5a6f9096cf))
|
37
|
+
|
38
|
+
## [0.54.1](https://github.com/applandinc/appmap-ruby/compare/v0.54.0...v0.54.1) (2021-06-25)
|
39
|
+
|
40
|
+
|
41
|
+
### Bug Fixes
|
42
|
+
|
43
|
+
* Add missing imports and remove deprecation warnings ([f1cb087](https://github.com/applandinc/appmap-ruby/commit/f1cb087f80cad88093227ebf8b4a4cd574853667))
|
44
|
+
* Workaround Ruby bug in 2.7.3 with kwrest ([26e34ca](https://github.com/applandinc/appmap-ruby/commit/26e34ca421fdae6602b27fee5653c8fe26b3793b))
|
45
|
+
|
1
46
|
# [0.54.0](https://github.com/applandinc/appmap-ruby/compare/v0.53.0...v0.54.0) (2021-06-24)
|
2
47
|
|
3
48
|
|
data/Rakefile
CHANGED
@@ -6,8 +6,7 @@ require 'rake/testtask'
|
|
6
6
|
require 'rdoc/task'
|
7
7
|
|
8
8
|
require 'open3'
|
9
|
-
|
10
|
-
require "rake/extensiontask"
|
9
|
+
require 'rake/extensiontask'
|
11
10
|
|
12
11
|
desc 'build the native extension'
|
13
12
|
Rake::ExtensionTask.new("appmap") do |ext|
|
@@ -26,7 +25,7 @@ namespace 'gem' do
|
|
26
25
|
# ~/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/gem_helper.rb:39:in `install'
|
27
26
|
def build_gem
|
28
27
|
# Ensure that NPM packages are installed before building.
|
29
|
-
sh('yarn install --prod'
|
28
|
+
sh('yarn install --prod')
|
30
29
|
|
31
30
|
default_build_gem
|
32
31
|
end
|
@@ -34,7 +33,17 @@ namespace 'gem' do
|
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
|
-
RUBY_VERSIONS=%w[2.5 2.6 2.7]
|
36
|
+
RUBY_VERSIONS=%w[2.5 2.6 2.7].select do |version|
|
37
|
+
travis_ruby_version = ENV['TRAVIS_RUBY_VERSION']
|
38
|
+
next true unless travis_ruby_version
|
39
|
+
|
40
|
+
if travis_ruby_version.index(version) == 0
|
41
|
+
warn "Testing Ruby version #{version}, since it matches TRAVIS_RUBY_VERSION=#{travis_ruby_version}"
|
42
|
+
next true
|
43
|
+
end
|
44
|
+
|
45
|
+
false
|
46
|
+
end
|
38
47
|
FIXTURE_APPS=%w[rack_users_app rails6_users_app rails5_users_app]
|
39
48
|
|
40
49
|
def run_cmd(*cmd)
|
data/appmap.gemspec
CHANGED
data/lib/appmap.rb
CHANGED
@@ -26,12 +26,11 @@ lambda do
|
|
26
26
|
Initializer = Struct.new(:class_name, :module_name, :gem_module_name)
|
27
27
|
|
28
28
|
INITIALIZERS = {
|
29
|
-
|
30
|
-
'
|
29
|
+
# In a Rails app, Rails is always defined by the time the other gems are loaded. Therefore, we
|
30
|
+
# don't try and trap the loading of Rails itself here.
|
31
|
+
# Emperically, Rake and RSpec are also defined before appmap is loaded whenever a Rake task or
|
32
|
+
# RSpec tests are being run. Therefore, the only hook we need here is Minitest.
|
31
33
|
'Minitest::Unit::TestCase' => Initializer.new('AppMap::Minitest', 'appmap/minitest', 'minitest'),
|
32
|
-
'Rake' => [
|
33
|
-
Initializer.new('AppMap::Swagger', 'appmap/swagger', 'rake')
|
34
|
-
]
|
35
34
|
}
|
36
35
|
|
37
36
|
TracePoint.new(:class) do |tp|
|
@@ -57,7 +56,7 @@ lambda do
|
|
57
56
|
end
|
58
57
|
end.enable
|
59
58
|
|
60
|
-
if defined?(::Rails
|
59
|
+
if defined?(::Rails)
|
61
60
|
require 'appmap/railtie'
|
62
61
|
end
|
63
62
|
|
@@ -68,7 +67,7 @@ lambda do
|
|
68
67
|
if defined?(::Minitest)
|
69
68
|
require 'appmap/minitest'
|
70
69
|
end
|
71
|
-
|
70
|
+
|
72
71
|
if defined?(::Rake)
|
73
72
|
require 'appmap/swagger'
|
74
73
|
end
|
data/lib/appmap/config.rb
CHANGED
@@ -343,7 +343,7 @@ module AppMap
|
|
343
343
|
shallow = package['shallow']
|
344
344
|
# shallow is true by default for gems
|
345
345
|
shallow = true if shallow.nil?
|
346
|
-
Package.build_from_gem(gem, exclude: package['exclude'] || [], shallow: shallow)
|
346
|
+
Package.build_from_gem(gem, package_name: package['package'], exclude: package['exclude'] || [], shallow: shallow)
|
347
347
|
else
|
348
348
|
Package.build_from_path(path, exclude: package['exclude'] || [], shallow: package['shallow'])
|
349
349
|
end
|
data/lib/appmap/event.rb
CHANGED
@@ -29,11 +29,31 @@ module AppMap
|
|
29
29
|
|
30
30
|
# Gets a display string for a value. This is not meant to be a machine deserializable value.
|
31
31
|
def display_string(value)
|
32
|
-
return nil
|
32
|
+
return nil if value.equal?(nil)
|
33
33
|
|
34
|
+
# With setting APPMAP_PROFILE_DISPLAY_STRING, stringifying this class is shown to take 9 seconds(!) of a 17 second test run.
|
35
|
+
return nil if best_class_name(value) == 'ActiveSupport::Callbacks::Filters::Environment'
|
36
|
+
|
37
|
+
if @times.nil? && ENV['APPMAP_PROFILE_DISPLAY_STRING'] == 'true'
|
38
|
+
@times = Hash.new {|memo,key| memo[key] = 0}
|
39
|
+
Thread.new do
|
40
|
+
sleep 0.5
|
41
|
+
while true
|
42
|
+
warn @times.to_a.sort{|a,b| b[1] <=> a[1]}[0..9].join("\n")
|
43
|
+
sleep 3
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
start = Time.now
|
34
49
|
value_string = custom_display_string(value) || default_display_string(value)
|
35
50
|
|
36
|
-
|
51
|
+
if @times
|
52
|
+
elapsed = Time.now - start
|
53
|
+
@times[best_class_name(value)] += elapsed
|
54
|
+
end
|
55
|
+
|
56
|
+
encode_dislay_string(value_string)
|
37
57
|
end
|
38
58
|
|
39
59
|
def object_properties(hash_like)
|
@@ -57,8 +77,16 @@ module AppMap
|
|
57
77
|
value_cls.name
|
58
78
|
end
|
59
79
|
|
80
|
+
def encode_dislay_string(value)
|
81
|
+
(value||'')[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
|
82
|
+
end
|
83
|
+
|
60
84
|
def custom_display_string(value)
|
61
85
|
case value
|
86
|
+
when NilClass, TrueClass, FalseClass, Numeric, Time, Date
|
87
|
+
value.to_s
|
88
|
+
when String
|
89
|
+
value[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
|
62
90
|
when File
|
63
91
|
"#{value.class}[path=#{value.path}]"
|
64
92
|
when Net::HTTP
|
@@ -71,6 +99,8 @@ module AppMap
|
|
71
99
|
end
|
72
100
|
|
73
101
|
def default_display_string(value)
|
102
|
+
return nil if ENV['APPMAP_OBJECT_STRING'] == 'false'
|
103
|
+
|
74
104
|
last_resort_string = lambda do
|
75
105
|
warn "AppMap encountered an error inspecting a #{value.class.name}: #{$!.message}"
|
76
106
|
'*Error inspecting variable*'
|
data/lib/appmap/hook.rb
CHANGED
@@ -9,6 +9,7 @@ module AppMap
|
|
9
9
|
|
10
10
|
OBJECT_INSTANCE_METHODS = %i[! != !~ <=> == === =~ __id__ __send__ class clone define_singleton_method display dup enum_for eql? equal? extend freeze frozen? hash inspect instance_eval instance_exec instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method methods nil? object_id private_methods protected_methods public_method public_methods public_send remove_instance_variable respond_to? send singleton_class singleton_method singleton_methods taint tainted? tap then to_enum to_s to_h to_a trust untaint untrust untrusted? yield_self].freeze
|
11
11
|
OBJECT_STATIC_METHODS = %i[! != !~ < <= <=> == === =~ > >= __id__ __send__ alias_method allocate ancestors attr attr_accessor attr_reader attr_writer autoload autoload? class class_eval class_exec class_variable_defined? class_variable_get class_variable_set class_variables clone const_defined? const_get const_missing const_set constants define_method define_singleton_method deprecate_constant display dup enum_for eql? equal? extend freeze frozen? hash include include? included_modules inspect instance_eval instance_exec instance_method instance_methods instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method method_defined? methods module_eval module_exec name new nil? object_id prepend private_class_method private_constant private_instance_methods private_method_defined? private_methods protected_instance_methods protected_method_defined? protected_methods public_class_method public_constant public_instance_method public_instance_methods public_method public_method_defined? public_methods public_send remove_class_variable remove_instance_variable remove_method respond_to? send singleton_class singleton_class? singleton_method singleton_methods superclass taint tainted? tap then to_enum to_s trust undef_method untaint untrust untrusted? yield_self].freeze
|
12
|
+
SLOW_PACKAGE_THRESHOLD = 0.05
|
12
13
|
|
13
14
|
@unbound_method_arity = ::UnboundMethod.instance_method(:arity)
|
14
15
|
@method_arity = ::Method.instance_method(:arity)
|
@@ -37,8 +38,6 @@ module AppMap
|
|
37
38
|
def initialize(config)
|
38
39
|
@config = config
|
39
40
|
@trace_enabled = []
|
40
|
-
# Paths that are known to be non-tracing
|
41
|
-
@notrace_paths = Set.new
|
42
41
|
end
|
43
42
|
|
44
43
|
# Observe class loading and hook all methods which match the config.
|
@@ -47,6 +46,32 @@ module AppMap
|
|
47
46
|
|
48
47
|
hook_builtins
|
49
48
|
|
49
|
+
# Paths that are known to be non-tracing.
|
50
|
+
@notrace_paths = Set.new
|
51
|
+
# Locations that have already been visited.
|
52
|
+
@trace_locations = Set.new
|
53
|
+
@module_load_times = Hash.new {|memo,k| memo[k] = 0}
|
54
|
+
@slow_packages = Set.new
|
55
|
+
|
56
|
+
if ENV['APPMAP_PROFILE_HOOK'] == 'true'
|
57
|
+
Thread.new do
|
58
|
+
sleep 1
|
59
|
+
while true
|
60
|
+
@module_load_times
|
61
|
+
.keys
|
62
|
+
.select { |key| !@slow_packages.member?(key) }
|
63
|
+
.each do |key|
|
64
|
+
elapsed = @module_load_times[key]
|
65
|
+
if elapsed >= SLOW_PACKAGE_THRESHOLD
|
66
|
+
@slow_packages.add(key)
|
67
|
+
warn "AppMap: Package #{key} took #{@module_load_times[key]} seconds to hook"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
sleep 5
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
50
75
|
@trace_end = TracePoint.new(:end, &method(:trace_end))
|
51
76
|
@trace_end.enable(&block)
|
52
77
|
end
|
@@ -100,7 +125,8 @@ module AppMap
|
|
100
125
|
|
101
126
|
def trace_end(trace_point)
|
102
127
|
location = trace_location(trace_point)
|
103
|
-
warn "Class or module ends at location #{
|
128
|
+
warn "Class or module ends at location #{location}" if Hook::LOG || Hook::LOG_HOOK
|
129
|
+
return unless @trace_locations.add?(location)
|
104
130
|
|
105
131
|
path = trace_point.path
|
106
132
|
enabled = !@notrace_paths.member?(path) && config.path_enabled?(path)
|
@@ -153,6 +179,7 @@ module AppMap
|
|
153
179
|
end
|
154
180
|
end
|
155
181
|
|
182
|
+
start = Time.now
|
156
183
|
instance_methods.each(&hook.(cls))
|
157
184
|
begin
|
158
185
|
# NoMethodError: private method `singleton_class' called for Rack::MiniProfiler:Class
|
@@ -162,6 +189,11 @@ module AppMap
|
|
162
189
|
# uninitialized constant Faraday::Connection
|
163
190
|
warn "NameError in #{__FILE__}: #{$!.message}"
|
164
191
|
end
|
192
|
+
elapsed = Time.now - start
|
193
|
+
if location.index(Bundler.bundle_path.to_s) == 0
|
194
|
+
package_tokens = location[Bundler.bundle_path.to_s.length + 1..-1].split('/')
|
195
|
+
@module_load_times[package_tokens[1]] += elapsed
|
196
|
+
end
|
165
197
|
end
|
166
198
|
end
|
167
199
|
end
|
data/lib/appmap/hook/method.rb
CHANGED
@@ -18,6 +18,8 @@ module AppMap
|
|
18
18
|
TIME_NOW = Time.method(:now)
|
19
19
|
private_constant :TIME_NOW
|
20
20
|
|
21
|
+
ARRAY_OF_EMPTY_HASH = [{}.freeze].freeze
|
22
|
+
|
21
23
|
def initialize(hook_package, hook_class, hook_method)
|
22
24
|
@hook_package = hook_package
|
23
25
|
@hook_class = hook_class
|
@@ -45,42 +47,53 @@ module AppMap
|
|
45
47
|
after_hook = self.method(:after_hook)
|
46
48
|
with_disabled_hook = self.method(:with_disabled_hook)
|
47
49
|
|
48
|
-
hook_method_def =
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
hook_method_def = Proc.new do |*args, &block|
|
51
|
+
instance_method = hook_method.bind(self).to_proc
|
52
|
+
|
53
|
+
is_array_containing_empty_hash = ->(obj) {
|
54
|
+
obj.is_a?(Array) && obj.length == 1 && obj[0].is_a?(Hash) && obj[0].size == 0
|
55
|
+
}
|
53
56
|
|
54
|
-
|
55
|
-
#
|
56
|
-
|
57
|
-
|
57
|
+
call_instance_method = -> {
|
58
|
+
# https://github.com/applandinc/appmap-ruby/issues/153
|
59
|
+
if Util.ruby_minor_version >= 2.7 && is_array_containing_empty_hash.(args) && hook_method.arity == 1
|
60
|
+
instance_method.call({}, &block)
|
61
|
+
else
|
62
|
+
instance_method.call(*args, &block)
|
63
|
+
end
|
64
|
+
}
|
58
65
|
|
59
|
-
|
60
|
-
|
61
|
-
|
66
|
+
# We may not have gotten the class for the method during
|
67
|
+
# initialization (e.g. for a singleton method on an embedded
|
68
|
+
# struct), so make sure we have it now.
|
69
|
+
defined_class, = Hook.qualify_method_name(hook_method) unless defined_class
|
62
70
|
|
63
|
-
|
71
|
+
reentrant = Thread.current[HOOK_DISABLE_KEY]
|
72
|
+
disabled_by_shallow_flag = \
|
73
|
+
-> { hook_package&.shallow? && AppMap.tracing.last_package_for_current_thread == hook_package }
|
64
74
|
|
65
|
-
|
75
|
+
enabled = true if AppMap.tracing.enabled? && !reentrant && !disabled_by_shallow_flag.call
|
66
76
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
return call_instance_method.call unless enabled
|
78
|
+
|
79
|
+
call_event, start_time = with_disabled_hook.call do
|
80
|
+
before_hook.call(self, defined_class, args)
|
81
|
+
end
|
82
|
+
return_value = nil
|
83
|
+
exception = nil
|
84
|
+
begin
|
85
|
+
return_value = call_instance_method.call
|
86
|
+
rescue
|
87
|
+
exception = $ERROR_INFO
|
88
|
+
raise
|
89
|
+
ensure
|
90
|
+
with_disabled_hook.call do
|
91
|
+
after_hook.call(self, call_event, start_time, return_value, exception) if call_event
|
81
92
|
end
|
82
93
|
end
|
83
94
|
end
|
95
|
+
hook_method_def = hook_method_def.ruby2_keywords if hook_method_def.respond_to?(:ruby2_keywords)
|
96
|
+
|
84
97
|
hook_class.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
|
85
98
|
end
|
86
99
|
|
data/lib/appmap/trace.rb
CHANGED
data/lib/appmap/util.rb
CHANGED
@@ -124,7 +124,7 @@ module AppMap
|
|
124
124
|
path = path.split('(.')[0]
|
125
125
|
tokens = path.split('/')
|
126
126
|
tokens.map do |token|
|
127
|
-
token.gsub
|
127
|
+
token.gsub(/^:(.*)/, '{\1}')
|
128
128
|
end.join('/')
|
129
129
|
end
|
130
130
|
|
@@ -154,6 +154,18 @@ module AppMap
|
|
154
154
|
word.split(/[\-_]/).map(&:capitalize).join
|
155
155
|
end
|
156
156
|
|
157
|
+
# https://api.rubyonrails.org/v6.1.3.2/classes/ActiveSupport/Inflector.html#method-i-underscore
|
158
|
+
def underscore(camel_cased_word)
|
159
|
+
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
160
|
+
word = camel_cased_word.to_s.gsub("::", "/")
|
161
|
+
# word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
|
162
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
163
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
164
|
+
word.tr!("-", "_")
|
165
|
+
word.downcase!
|
166
|
+
word
|
167
|
+
end
|
168
|
+
|
157
169
|
def deep_dup(hash)
|
158
170
|
# This is a simple way to avoid the need for deep_dup from activesupport.
|
159
171
|
Marshal.load(Marshal.dump(hash))
|
@@ -173,11 +185,15 @@ module AppMap
|
|
173
185
|
|
174
186
|
def startup_message(msg)
|
175
187
|
if defined?(::Rails) && defined?(::Rails.logger) && ::Rails.logger
|
176
|
-
::Rails.logger.
|
188
|
+
::Rails.logger.info msg
|
177
189
|
elsif ENV['DEBUG'] == 'true'
|
178
190
|
warn msg
|
179
191
|
end
|
180
192
|
end
|
193
|
+
|
194
|
+
def ruby_minor_version
|
195
|
+
@ruby_minor_version ||= RUBY_VERSION.split('.')[0..1].join('.').to_f
|
196
|
+
end
|
181
197
|
end
|
182
198
|
end
|
183
199
|
end
|
data/lib/appmap/version.rb
CHANGED
data/release.sh
CHANGED
data/spec/hook_spec.rb
CHANGED
@@ -970,7 +970,7 @@ describe 'AppMap class Hooking', docker: false do
|
|
970
970
|
tz = ENV['TZ']
|
971
971
|
ENV['TZ'] = 'UTC'
|
972
972
|
Timecop.freeze(Time.utc('2020-01-01')) do
|
973
|
-
expect(Time).to receive(:now).
|
973
|
+
expect(Time).to receive(:now).at_least(3).times.and_call_original
|
974
974
|
expect(InstanceMethod.new.say_the_time).to be
|
975
975
|
end
|
976
976
|
ensure
|
@@ -985,4 +985,13 @@ describe 'AppMap class Hooking', docker: false do
|
|
985
985
|
expect(InstanceMethod.new.method(:say_echo).arity).to be(1)
|
986
986
|
end
|
987
987
|
end
|
988
|
+
|
989
|
+
describe 'kwargs handling' do
|
990
|
+
# https://github.com/applandinc/appmap-ruby/issues/153
|
991
|
+
it 'empty hash for **kwrest can be proxied as a regular function argument', github_issue: 153 do
|
992
|
+
invoke_test_file 'spec/fixtures/hook/kwargs.rb' do
|
993
|
+
expect(Kwargs.has_kwrest_calls_no_kwargs(nil, {})).to eq({})
|
994
|
+
end
|
995
|
+
end
|
996
|
+
end
|
988
997
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.55.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gilpin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -276,6 +276,20 @@ dependencies:
|
|
276
276
|
- - ">="
|
277
277
|
- !ruby/object:Gem::Version
|
278
278
|
version: '0'
|
279
|
+
- !ruby/object:Gem::Dependency
|
280
|
+
name: webrick
|
281
|
+
requirement: !ruby/object:Gem::Requirement
|
282
|
+
requirements:
|
283
|
+
- - ">="
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: '0'
|
286
|
+
type: :development
|
287
|
+
prerelease: false
|
288
|
+
version_requirements: !ruby/object:Gem::Requirement
|
289
|
+
requirements:
|
290
|
+
- - ">="
|
291
|
+
- !ruby/object:Gem::Version
|
292
|
+
version: '0'
|
279
293
|
description:
|
280
294
|
email:
|
281
295
|
- kgilpin@gmail.com
|
@@ -364,6 +378,7 @@ files:
|
|
364
378
|
- spec/fixtures/hook/exception_method.rb
|
365
379
|
- spec/fixtures/hook/exclude.rb
|
366
380
|
- spec/fixtures/hook/instance_method.rb
|
381
|
+
- spec/fixtures/hook/kwargs.rb
|
367
382
|
- spec/fixtures/hook/labels.rb
|
368
383
|
- spec/fixtures/hook/method_named_call.rb
|
369
384
|
- spec/fixtures/hook/revoke_api_key.appmap.json
|