appmap 0.71.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: 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