appmap 0.71.0 → 0.72.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cac567f064d0d5059d29abbeb91341fcbfc7ede0ae449ef6731272bd4f36e313
4
- data.tar.gz: df9ce73e1770a9d6f171df8f8796cecd9dde98409167900fa575d26ef93ea6f4
3
+ metadata.gz: 3dffdfecec5017edcd8c551226e5915348ef7db45a3ab82e1ccc1ace4879d712
4
+ data.tar.gz: 462c0d8e46b2a7c278e95e526ff8b1de7fa4d966e38c481cf69c5e3d1d97817e
5
5
  SHA512:
6
- metadata.gz: 84e300cd56db7c9853d393d27efd9184bd35aa4933d939d1693782f2ab81d22f25049a350ca929067f688f60a63175e963932769978bbc142d64427d17a3ccbb
7
- data.tar.gz: bfd31a6d1998660bf04ef2346fa678518ad39ffd3f4b509627e0b739616e0c59a6d5e98ea4d2be9115f448b138d95af4760b2178592891a75b3d40cf6baa0136
6
+ metadata.gz: fc3e0a0c0488be776f924a457e04afd1ea9048ee43fd9bbcd557f79fd45212e2036ac38e2df021dcfa3c4a7c47f5401ae8e983dae236bd6de13481df103f552f
7
+ data.tar.gz: e369f73989da51222f65a50697c2fdcae367db5a0742d5b9e9a77dab321bfe2b74e09d49eb1d56359cc6b6ac64817e73ef55f0dfdfae63ff2c7e5dbf9c6f9a87
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
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
+
1
14
  # [0.71.0](https://github.com/applandinc/appmap-ruby/compare/v0.70.2...v0.71.0) (2022-01-19)
2
15
 
3
16
 
@@ -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,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
@@ -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
@@ -3,7 +3,7 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.71.0'
6
+ VERSION = '0.72.0'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.5.1'
9
9
 
data/spec/config_spec.rb CHANGED
@@ -20,235 +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
- "Logger::LogDevice": [
100
- {
101
- "package": "logger",
102
- "method_names": [
103
- "write"
104
- ]
105
- }
106
- ],
107
- "Net::HTTP": [
108
- {
109
- "package": "net/http",
110
- "method_names": [
111
- "request"
112
- ]
113
- }
114
- ],
115
- "OpenSSL::PKey::PKey": [
116
- {
117
- "package": "openssl",
118
- "method_names": [
119
- "sign"
120
- ]
121
- }
122
- ],
123
- "OpenSSL::X509::Request": [
124
- {
125
- "package": "openssl",
126
- "method_names": [
127
- "sign"
128
- ]
129
- },
130
- {
131
- "package": "openssl",
132
- "method_names": [
133
- "verify"
134
- ]
135
- }
136
- ],
137
- "OpenSSL::X509::Certificate": [
138
- {
139
- "package": "openssl",
140
- "method_names": [
141
- "sign"
142
- ]
143
- }
144
- ],
145
- "OpenSSL::PKCS5": [
146
- {
147
- "package": "openssl",
148
- "method_names": [
149
- "pbkdf2_hmac"
150
- ]
151
- },
152
- {
153
- "package": "openssl",
154
- "method_names": [
155
- "pbkdf2_hmac_sha1"
156
- ]
157
- }
158
- ],
159
- "OpenSSL::Cipher": [
160
- {
161
- "package": "openssl",
162
- "method_names": [
163
- "encrypt"
164
- ]
165
- },
166
- {
167
- "package": "openssl",
168
- "method_names": [
169
- "decrypt"
170
- ]
171
- }
172
- ],
173
- "Psych": [
174
- {
175
- "package": "yaml",
176
- "method_names": [
177
- "load"
178
- ]
179
- },
180
- {
181
- "package": "yaml",
182
- "method_names": [
183
- "load_stream"
184
- ]
185
- },
186
- {
187
- "package": "yaml",
188
- "method_names": [
189
- "parse"
190
- ]
191
- },
192
- {
193
- "package": "yaml",
194
- "method_names": [
195
- "parse_stream"
196
- ]
197
- },
198
- {
199
- "package": "yaml",
200
- "method_names": [
201
- "dump"
202
- ]
203
- },
204
- {
205
- "package": "yaml",
206
- "method_names": [
207
- "dump_stream"
208
- ]
209
- }
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
210
108
  ]
211
109
  },
212
- "gem_hooks": {
213
- "cls": [
214
- {
215
- "package": "pkg",
216
- "method_names": [
217
- "fn"
218
- ]
219
- },
220
- {
221
- "package": "pkg",
222
- "method_names": [
223
- "new_fn"
224
- ]
225
- }
226
- ],
227
- "ActiveSupport::Callbacks::CallbackSequence": [
228
- {
229
- "package": "activesupport",
230
- "method_names": [
231
- "invoke_before"
232
- ]
233
- },
234
- {
235
- "package": "activesupport",
236
- "method_names": [
237
- "invoke_after"
238
- ]
239
- }
240
- ],
241
- "ActiveSupport::SecurityUtils": [
242
- {
243
- "package": "activesupport",
244
- "method_names": [
245
- "secure_compare"
246
- ]
247
- }
110
+ {
111
+ "package" => "activesupport",
112
+ "method_names" => [
113
+ :invoke_after
248
114
  ]
249
115
  }
250
- }
251
- FIXTURE
116
+ ])
252
117
  end
253
118
 
254
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.71.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: 2022-01-19 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
@@ -3407,6 +3407,7 @@ files:
3407
3407
  - lib/appmap/agent.rb
3408
3408
  - lib/appmap/builtin_hooks/json.yml
3409
3409
  - lib/appmap/builtin_hooks/logger.yml
3410
+ - lib/appmap/builtin_hooks/marshal.yml
3410
3411
  - lib/appmap/builtin_hooks/net/http.yml
3411
3412
  - lib/appmap/builtin_hooks/openssl.yml
3412
3413
  - lib/appmap/builtin_hooks/yaml.yml
@@ -3509,6 +3510,7 @@ files:
3509
3510
  - spec/fixtures/hook/labels.rb
3510
3511
  - spec/fixtures/hook/method_named_call.rb
3511
3512
  - spec/fixtures/hook/pkg_a/a.rb
3513
+ - spec/fixtures/hook/prepended_override.rb
3512
3514
  - spec/fixtures/hook/protected_method.rb
3513
3515
  - spec/fixtures/hook/revoke_api_key.appmap.json
3514
3516
  - spec/fixtures/hook/singleton_method.rb