appmap 0.70.0 → 0.72.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64006e414b4b6cece101a113b5b5359c370b77b96761cfcb02818c07e621d8c5
4
- data.tar.gz: e7ab888c17031adb8ae993dae863539b32359e967c706b2cc2b13f1f2bb11761
3
+ metadata.gz: 3dffdfecec5017edcd8c551226e5915348ef7db45a3ab82e1ccc1ace4879d712
4
+ data.tar.gz: 462c0d8e46b2a7c278e95e526ff8b1de7fa4d966e38c481cf69c5e3d1d97817e
5
5
  SHA512:
6
- metadata.gz: e9b9fbf621b59dfb72875365d2c4485e174b4532b159d62854883e77fd741451f1e8ca4609b0a5323cccc562fcf31ead2ef19923bd3be3e6b0d5d28d5c188635
7
- data.tar.gz: 4a079f0b5ae28e45a065187e0044446bdbef6a5a91df88f9072b71a825a18c86e3ba6eaf8dc54102b224eb16f3eae1ea0b9e3b8da3958b209bdd9f5d78d0ac50
6
+ metadata.gz: fc3e0a0c0488be776f924a457e04afd1ea9048ee43fd9bbcd557f79fd45212e2036ac38e2df021dcfa3c4a7c47f5401ae8e983dae236bd6de13481df103f552f
7
+ data.tar.gz: e369f73989da51222f65a50697c2fdcae367db5a0742d5b9e9a77dab321bfe2b74e09d49eb1d56359cc6b6ac64817e73ef55f0dfdfae63ff2c7e5dbf9c6f9a87
data/CHANGELOG.md CHANGED
@@ -1,3 +1,37 @@
1
+ # [0.72.0](https://github.com/applandinc/appmap-ruby/compare/v0.71.0...v0.72.0) (2022-01-24)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Fix a stack overflow when an override is prepended ([540907b](https://github.com/applandinc/appmap-ruby/commit/540907b1a9fa063d25ddbaf406674f2e16b11bfe))
7
+ * Hook the first class or module in the ancestor chain ([8143f14](https://github.com/applandinc/appmap-ruby/commit/8143f145691a98e6e83563635db783ba8d393d9c))
8
+
9
+
10
+ ### Features
11
+
12
+ * Label JSON, Marshal and YAML with (de)serialize ([318d294](https://github.com/applandinc/appmap-ruby/commit/318d294c1d921dacb18f1d3e1776282d9f208215))
13
+
14
+ # [0.71.0](https://github.com/applandinc/appmap-ruby/compare/v0.70.2...v0.71.0) (2022-01-19)
15
+
16
+
17
+ ### Features
18
+
19
+ * Add labels for http.session.clear, dao.materialize, log ([8e6784b](https://github.com/applandinc/appmap-ruby/commit/8e6784b82959eb5924d4675b43f6b98c7bd1b779))
20
+
21
+ ## [0.70.2](https://github.com/applandinc/appmap-ruby/compare/v0.70.1...v0.70.2) (2022-01-12)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * switch to activesupport's deep_dup implementation ([7715f28](https://github.com/applandinc/appmap-ruby/commit/7715f28285fbdabdb4c8d652fb9ac31eb8d86eab))
27
+
28
+ ## [0.70.1](https://github.com/applandinc/appmap-ruby/compare/v0.70.0...v0.70.1) (2021-12-10)
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * Use require_name as the default package 'path' for builtins ([bcb4367](https://github.com/applandinc/appmap-ruby/commit/bcb4367811992c924c76950a22d11ddc3057c1ee))
34
+
1
35
  # [0.70.0](https://github.com/applandinc/appmap-ruby/compare/v0.69.0...v0.70.0) (2021-12-08)
2
36
 
3
37
 
@@ -1,4 +1,8 @@
1
1
  - method: JSON::Ext::Parser#parse
2
- label: format.json.parse
2
+ labels:
3
+ - format.json.parse
4
+ - deserialize
3
5
  - method: JSON::Ext::Generator::State#generate
4
- label: format.json.generate
6
+ label:
7
+ - format.json.generate
8
+ - serialize
@@ -0,0 +1,3 @@
1
+ - method: Logger::LogDevice#write
2
+ require_name: logger
3
+ label: log
@@ -0,0 +1,12 @@
1
+ - methods:
2
+ - Marshal#load
3
+ - Marshal#restore
4
+ require_name: ruby
5
+ label:
6
+ - deserialize
7
+ - deserialize.unsafe
8
+ - methods:
9
+ - Marshal#dump
10
+ require_name: ruby
11
+ label:
12
+ - deserialize
@@ -1,10 +1,23 @@
1
1
  - methods:
2
2
  - Psych#load
3
+ - Psych#unsafe_load
4
+ - Psych#load_file
5
+ - Psych#unsafe_load_file
3
6
  - Psych#load_stream
4
7
  - Psych#parse
5
8
  - Psych#parse_stream
6
- label: format.yaml.parse
9
+ label:
10
+ - format.yaml.parse
11
+ - deserialize
12
+ - deserialize.unsafe
13
+ - methods:
14
+ - Psych#safe_load
15
+ label:
16
+ - format.yaml.parse
17
+ - deserialize
7
18
  - methods:
8
19
  - Psych#dump
9
20
  - Psych#dump_stream
10
- label: format.yaml.generate
21
+ label:
22
+ - format.yaml.generate
23
+ - serialize
data/lib/appmap/config.rb CHANGED
@@ -163,7 +163,7 @@ module AppMap
163
163
  def package_hooks(methods, path: nil, gem: nil, force: false, builtin: false, handler_class: nil, require_name: nil)
164
164
  Array(methods).map do |method|
165
165
  package = if builtin
166
- Package.build_from_builtin(path, require_name: require_name, labels: method.labels, shallow: false)
166
+ Package.build_from_builtin(path || require_name, require_name: require_name, labels: method.labels, shallow: false)
167
167
  elsif gem
168
168
  Package.build_from_gem(gem, require_name: require_name, labels: method.labels, shallow: false, force: force, optional: true)
169
169
  elsif path
@@ -10,17 +10,22 @@
10
10
  - methods:
11
11
  - ActionDispatch::Request::Session#destroy
12
12
  - ActionDispatch::Request::Session#[]=
13
- - ActionDispatch::Request::Session#clear
14
13
  - ActionDispatch::Request::Session#update
15
14
  - ActionDispatch::Request::Session#delete
16
15
  - ActionDispatch::Request::Session#merge
17
16
  - ActionDispatch::Cookies::CookieJar#[]=
18
- - ActionDispatch::Cookies::CookieJar#clear
19
17
  - ActionDispatch::Cookies::CookieJar#update
20
18
  - ActionDispatch::Cookies::CookieJar#delete
21
19
  - ActionDispatch::Cookies::CookieJar#recycle!
22
20
  label: http.session.write
23
21
  require_name: action_dispatch
22
+ - methods:
23
+ - ActionDispatch::Request::Session#clear
24
+ - ActionDispatch::Cookies::CookieJar#clear
25
+ labels:
26
+ - http.session.write
27
+ - http.session.clear
28
+ require_name: action_dispatch
24
29
  - methods:
25
30
  - ActionDispatch::Cookies::EncryptedCookieJar#[]=
26
31
  - ActionDispatch::Cookies::EncryptedCookieJar#clear
@@ -0,0 +1,2 @@
1
+ - method: ActiveRecord::Relation#records
2
+ label: dao.materialize
@@ -94,7 +94,7 @@ module AppMap
94
94
  end
95
95
  hook_method_def = hook_method_def.ruby2_keywords if hook_method_def.respond_to?(:ruby2_keywords)
96
96
 
97
- hook_class.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
97
+ hook_class.ancestors.first.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
98
98
  end
99
99
 
100
100
  protected
data/lib/appmap/util.rb CHANGED
@@ -195,8 +195,7 @@ module AppMap
195
195
  end
196
196
 
197
197
  def deep_dup(hash)
198
- # This is a simple way to avoid the need for deep_dup from activesupport.
199
- Marshal.load(Marshal.dump(hash))
198
+ hash.deep_dup
200
199
  end
201
200
 
202
201
  def blank?(obj)
@@ -3,7 +3,7 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.70.0'
6
+ VERSION = '0.72.0'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.5.1'
9
9
 
data/lib/appmap.rb CHANGED
@@ -20,6 +20,13 @@
20
20
  # - appmap/swagger (Rake task)
21
21
  # - appmap/depends (Rake task)
22
22
 
23
+ begin
24
+ require 'active_support'
25
+ require 'active_support/core_ext'
26
+ rescue NameError
27
+ warn 'active_support is not available. AppMap execution will continue optimistically without it...'
28
+ end
29
+
23
30
  require 'appmap/version'
24
31
  require 'appmap/agent'
25
32
 
@@ -60,11 +67,11 @@ lambda do
60
67
  if defined?(::Rails)
61
68
  require 'appmap/railtie'
62
69
  end
63
-
70
+
64
71
  if defined?(::RSpec)
65
72
  require 'appmap/rspec'
66
73
  end
67
-
74
+
68
75
  if defined?(::Minitest)
69
76
  require 'appmap/minitest'
70
77
  end
@@ -73,7 +80,7 @@ lambda do
73
80
  require 'appmap/swagger'
74
81
  require 'appmap/depends'
75
82
  end
76
-
83
+
77
84
  end.call unless ENV['APPMAP_AUTOREQUIRE'] == 'false'
78
85
 
79
86
  AppMap.initialize_configuration if ENV['APPMAP'] == 'true' && ENV['APPMAP_INITIALIZE'] != 'false'
data/spec/config_spec.rb CHANGED
@@ -20,227 +20,100 @@ describe AppMap::Config, docker: false do
20
20
  }.deep_stringify_keys!
21
21
  config = AppMap::Config.load(config_data)
22
22
 
23
- expect(JSON.parse(JSON.generate(config.as_json))).to eq(JSON.parse(<<~FIXTURE))
24
- {
25
- "name": "test",
26
- "appmap_dir": "tmp/appmap",
27
- "packages": [
23
+ expect(config.as_json.keys.sort).to eq(["appmap_dir", "builtin_hooks", "depends_config", "exclude", "functions", "gem_hooks", "hook_paths", "name", "packages", "swagger_config"])
24
+ expect(config.as_json['appmap_dir']).to eq('tmp/appmap')
25
+ expect(config.as_json['name']).to eq('test')
26
+ expect(config.as_json['packages']).to eq([])
27
+ expect(config.as_json['depends_config']).to eq({
28
+ "base_dir" => nil,
29
+ "base_branches" => [
30
+ "remotes/origin/main",
31
+ "remotes/origin/master"
28
32
  ],
29
- "swagger_config": {
30
- "project_name": null,
31
- "project_version": "1.0",
32
- "output_dir": "swagger",
33
- "description": "Generate Swagger from AppMaps"
34
- },
35
- "depends_config": {
36
- "base_dir": null,
37
- "base_branches": [
38
- "remotes/origin/main",
39
- "remotes/origin/master"
40
- ],
41
- "test_file_patterns": [
42
- "spec/**/*_spec.rb",
43
- "test/**/*_test.rb"
44
- ],
45
- "dependent_tasks": [
46
- "swagger"
47
- ],
48
- "description": "Bring AppMaps up to date with local file modifications, and updated derived data such as Swagger files",
49
- "rspec_environment_method": "AppMap::Depends.test_env",
50
- "minitest_environment_method": "AppMap::Depends.test_env",
51
- "rspec_select_tests_method": "AppMap::Depends.select_rspec_tests",
52
- "minitest_select_tests_method": "AppMap::Depends.select_minitest_tests",
53
- "rspec_test_command_method": "AppMap::Depends.rspec_test_command",
54
- "minitest_test_command_method": "AppMap::Depends.minitest_test_command"
55
- },
56
- "hook_paths": [
57
- "pkg",
58
- "#{Gem.loaded_specs['activesupport'].gem_dir}"
33
+ "test_file_patterns" => [
34
+ "spec/**/*_spec.rb",
35
+ "test/**/*_test.rb"
59
36
  ],
60
- "exclude": [
37
+ "dependent_tasks" => [
38
+ "swagger"
61
39
  ],
62
- "functions": [
63
- {
64
- "cls": "cls",
65
- "target_methods": {
66
- "package": "pkg",
67
- "method_names": [
68
- "fn"
69
- ]
70
- }
71
- },
72
- {
73
- "cls": "cls",
74
- "target_methods": {
75
- "package": "pkg",
76
- "method_names": [
77
- "new_fn"
78
- ]
79
- }
40
+ "description" => "Bring AppMaps up to date with local file modifications, and updated derived data such as Swagger files",
41
+ "rspec_environment_method" => "AppMap::Depends.test_env",
42
+ "minitest_environment_method" => "AppMap::Depends.test_env",
43
+ "rspec_select_tests_method" => "AppMap::Depends.select_rspec_tests",
44
+ "minitest_select_tests_method" => "AppMap::Depends.select_minitest_tests",
45
+ "rspec_test_command_method" => "AppMap::Depends.rspec_test_command",
46
+ "minitest_test_command_method" => "AppMap::Depends.minitest_test_command"
47
+ })
48
+ expect(config.as_json['swagger_config']).to eq({
49
+ "project_name" => nil,
50
+ "project_version" => "1.0",
51
+ "output_dir" => "swagger",
52
+ "description" => "Generate Swagger from AppMaps"
53
+ })
54
+ expect(config.as_json['hook_paths']).to eq([
55
+ "pkg",
56
+ "#{Gem.loaded_specs['activesupport'].gem_dir}"
57
+ ])
58
+ expect(config.as_json['exclude']).to eq([])
59
+ expect(config.as_json['functions'].map(&:deep_stringify_keys)).to eq([
60
+ {
61
+ "cls" => "cls",
62
+ "target_methods" => {
63
+ "package" => "pkg",
64
+ "method_names" => [
65
+ :fn
66
+ ]
80
67
  }
81
- ],
82
- "builtin_hooks": {
83
- "JSON::Ext::Parser": [
84
- {
85
- "package": "json",
86
- "method_names": [
87
- "parse"
88
- ]
89
- }
90
- ],
91
- "JSON::Ext::Generator::State": [
92
- {
93
- "package": "json",
94
- "method_names": [
95
- "generate"
96
- ]
97
- }
98
- ],
99
- "Net::HTTP": [
100
- {
101
- "package": "net/http",
102
- "method_names": [
103
- "request"
104
- ]
105
- }
106
- ],
107
- "OpenSSL::PKey::PKey": [
108
- {
109
- "package": "openssl",
110
- "method_names": [
111
- "sign"
112
- ]
113
- }
114
- ],
115
- "OpenSSL::X509::Request": [
116
- {
117
- "package": "openssl",
118
- "method_names": [
119
- "sign"
120
- ]
121
- },
122
- {
123
- "package": "openssl",
124
- "method_names": [
125
- "verify"
126
- ]
127
- }
128
- ],
129
- "OpenSSL::X509::Certificate": [
130
- {
131
- "package": "openssl",
132
- "method_names": [
133
- "sign"
134
- ]
135
- }
136
- ],
137
- "OpenSSL::PKCS5": [
138
- {
139
- "package": "openssl",
140
- "method_names": [
141
- "pbkdf2_hmac"
142
- ]
143
- },
144
- {
145
- "package": "openssl",
146
- "method_names": [
147
- "pbkdf2_hmac_sha1"
148
- ]
149
- }
150
- ],
151
- "OpenSSL::Cipher": [
152
- {
153
- "package": "openssl",
154
- "method_names": [
155
- "encrypt"
156
- ]
157
- },
158
- {
159
- "package": "openssl",
160
- "method_names": [
161
- "decrypt"
162
- ]
163
- }
164
- ],
165
- "Psych": [
166
- {
167
- "package": "yaml",
168
- "method_names": [
169
- "load"
170
- ]
171
- },
172
- {
173
- "package": "yaml",
174
- "method_names": [
175
- "load_stream"
176
- ]
177
- },
178
- {
179
- "package": "yaml",
180
- "method_names": [
181
- "parse"
182
- ]
183
- },
184
- {
185
- "package": "yaml",
186
- "method_names": [
187
- "parse_stream"
188
- ]
189
- },
190
- {
191
- "package": "yaml",
192
- "method_names": [
193
- "dump"
194
- ]
195
- },
196
- {
197
- "package": "yaml",
198
- "method_names": [
199
- "dump_stream"
200
- ]
201
- }
68
+ },
69
+ {
70
+ "cls" => "cls",
71
+ "target_methods" => {
72
+ "package" => "pkg",
73
+ "method_names" => [
74
+ :new_fn
75
+ ]
76
+ }
77
+ }
78
+ ])
79
+ expect(config.as_json['builtin_hooks']).to have_key('JSON::Ext::Parser')
80
+ expect(config.as_json['builtin_hooks']['JSON::Ext::Parser'].map(&:deep_stringify_keys)).to eq([{
81
+ "package" => "json",
82
+ "method_names" => [
83
+ :parse
84
+ ]
85
+ }
86
+ ])
87
+ expect(config.as_json['gem_hooks']).to have_key('cls')
88
+ expect(config.as_json['gem_hooks']['cls'].map(&:deep_stringify_keys)).to eq([
89
+ {
90
+ "package" => "pkg",
91
+ "method_names" => [
92
+ :fn
93
+ ]
94
+ },
95
+ {
96
+ "package" => "pkg",
97
+ "method_names" => [
98
+ :new_fn
99
+ ]
100
+ }
101
+ ])
102
+ expect(config.as_json['gem_hooks']).to have_key('ActiveSupport::Callbacks::CallbackSequence')
103
+ expect(config.as_json['gem_hooks']['ActiveSupport::Callbacks::CallbackSequence'].map(&:deep_stringify_keys)).to eq([
104
+ {
105
+ "package" => "activesupport",
106
+ "method_names" => [
107
+ :invoke_before
202
108
  ]
203
109
  },
204
- "gem_hooks": {
205
- "cls": [
206
- {
207
- "package": "pkg",
208
- "method_names": [
209
- "fn"
210
- ]
211
- },
212
- {
213
- "package": "pkg",
214
- "method_names": [
215
- "new_fn"
216
- ]
217
- }
218
- ],
219
- "ActiveSupport::Callbacks::CallbackSequence": [
220
- {
221
- "package": "activesupport",
222
- "method_names": [
223
- "invoke_before"
224
- ]
225
- },
226
- {
227
- "package": "activesupport",
228
- "method_names": [
229
- "invoke_after"
230
- ]
231
- }
232
- ],
233
- "ActiveSupport::SecurityUtils": [
234
- {
235
- "package": "activesupport",
236
- "method_names": [
237
- "secure_compare"
238
- ]
239
- }
110
+ {
111
+ "package" => "activesupport",
112
+ "method_names" => [
113
+ :invoke_after
240
114
  ]
241
115
  }
242
- }
243
- FIXTURE
116
+ ])
244
117
  end
245
118
 
246
119
  describe AppMap::Config::Package do
@@ -0,0 +1,14 @@
1
+
2
+ module PrependedModule
3
+ def say_hello
4
+ 'please allow me to ' + super
5
+ end
6
+ end
7
+
8
+ class PrependedClass
9
+ prepend PrependedModule
10
+
11
+ def say_hello
12
+ 'introduce myself'
13
+ end
14
+ end
data/spec/hook_spec.rb CHANGED
@@ -1110,4 +1110,30 @@ describe 'AppMap class Hooking', docker: false do
1110
1110
  end
1111
1111
  end
1112
1112
  end
1113
+
1114
+ describe 'prepended override' do
1115
+ it 'does not cause stack overflow error' do
1116
+ # For the purposes of this test, the code must be statically required, then hooked,
1117
+ # then executed.
1118
+
1119
+ require_relative './fixtures/hook/prepended_override'
1120
+ require 'appmap/hook/method'
1121
+
1122
+ pkg = AppMap::Config::Package.new('fixtures/hook/prependend_override')
1123
+ AppMap::Hook::Method.new(pkg, PrependedClass, PrependedClass.public_instance_method(:say_hello)).activate
1124
+
1125
+ tracer = AppMap.tracing.trace
1126
+ AppMap::Event.reset_id_counter
1127
+ begin
1128
+ expect(PrependedClass.new.say_hello).to eq('please allow me to introduce myself')
1129
+ ensure
1130
+ AppMap.tracing.delete(tracer)
1131
+ end
1132
+
1133
+ events = collect_events(tracer)
1134
+ expect(events.length).to eq(2)
1135
+ expect(events.first[:method_id]).to eq('say_hello')
1136
+ expect(events.second[:return_value][:value]).to eq('please allow me to introduce myself')
1137
+ end
1138
+ end
1113
1139
  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.70.0
4
+ version: 0.72.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-12-08 00:00:00.000000000 Z
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -3406,6 +3406,8 @@ files:
3406
3406
  - lib/appmap.rb
3407
3407
  - lib/appmap/agent.rb
3408
3408
  - lib/appmap/builtin_hooks/json.yml
3409
+ - lib/appmap/builtin_hooks/logger.yml
3410
+ - lib/appmap/builtin_hooks/marshal.yml
3409
3411
  - lib/appmap/builtin_hooks/net/http.yml
3410
3412
  - lib/appmap/builtin_hooks/openssl.yml
3411
3413
  - lib/appmap/builtin_hooks/yaml.yml
@@ -3431,6 +3433,7 @@ files:
3431
3433
  - lib/appmap/gem_hooks/actionview.yml
3432
3434
  - lib/appmap/gem_hooks/activejob-cancel.yml
3433
3435
  - lib/appmap/gem_hooks/activejob.yml
3436
+ - lib/appmap/gem_hooks/activerecord.yml
3434
3437
  - lib/appmap/gem_hooks/activesupport.yml
3435
3438
  - lib/appmap/gem_hooks/cancancan.yml
3436
3439
  - lib/appmap/gem_hooks/resque.yml
@@ -3507,6 +3510,7 @@ files:
3507
3510
  - spec/fixtures/hook/labels.rb
3508
3511
  - spec/fixtures/hook/method_named_call.rb
3509
3512
  - spec/fixtures/hook/pkg_a/a.rb
3513
+ - spec/fixtures/hook/prepended_override.rb
3510
3514
  - spec/fixtures/hook/protected_method.rb
3511
3515
  - spec/fixtures/hook/revoke_api_key.appmap.json
3512
3516
  - spec/fixtures/hook/singleton_method.rb