appmap 0.35.0 → 0.37.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +1 -1
  3. data/.gitignore +2 -1
  4. data/.rubocop.yml +10 -0
  5. data/CHANGELOG.md +22 -0
  6. data/README.md +11 -8
  7. data/Rakefile +3 -2
  8. data/appmap.gemspec +2 -1
  9. data/appmap.yml +1 -7
  10. data/lib/appmap.rb +2 -2
  11. data/lib/appmap/class_map.rb +20 -6
  12. data/lib/appmap/config.rb +53 -23
  13. data/lib/appmap/event.rb +21 -6
  14. data/lib/appmap/hook.rb +1 -1
  15. data/lib/appmap/rails/request_handler.rb +8 -1
  16. data/lib/appmap/railtie.rb +1 -1
  17. data/lib/appmap/rspec.rb +1 -1
  18. data/lib/appmap/version.rb +2 -2
  19. data/spec/abstract_controller4_base_spec.rb +27 -28
  20. data/spec/abstract_controller_base_spec.rb +43 -39
  21. data/spec/class_map_spec.rb +36 -0
  22. data/spec/fixtures/hook/exception_method.rb +44 -0
  23. data/spec/fixtures/hook/instance_method.rb +4 -0
  24. data/spec/fixtures/{rails_users_app → rails5_users_app}/.dockerignore +0 -0
  25. data/spec/fixtures/{rails_users_app → rails5_users_app}/.gitignore +0 -0
  26. data/spec/fixtures/{rails_users_app → rails5_users_app}/.rspec +0 -0
  27. data/{.ruby-version → spec/fixtures/rails5_users_app/.ruby-version} +0 -0
  28. data/spec/fixtures/{rails_users_app → rails5_users_app}/Dockerfile +0 -0
  29. data/spec/fixtures/{rails_users_app → rails5_users_app}/Dockerfile.pg +0 -0
  30. data/spec/fixtures/rails5_users_app/Gemfile +51 -0
  31. data/spec/fixtures/{rails_users_app → rails5_users_app}/Rakefile +0 -0
  32. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/controllers/api/users_controller.rb +0 -0
  33. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/controllers/application_controller.rb +0 -0
  34. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/controllers/concerns/.keep +0 -0
  35. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/controllers/health_controller.rb +0 -0
  36. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/controllers/users_controller.rb +0 -0
  37. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/models/activerecord/user.rb +0 -0
  38. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/models/concerns/.keep +0 -0
  39. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/models/sequel/user.rb +0 -0
  40. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/views/layouts/application.html.haml +0 -0
  41. data/spec/fixtures/{rails_users_app → rails5_users_app}/app/views/users/index.html.haml +0 -0
  42. data/spec/fixtures/{rails_users_app → rails5_users_app}/appmap.yml +1 -1
  43. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/appmap +0 -0
  44. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/byebug +0 -0
  45. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/gli +0 -0
  46. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/htmldiff +0 -0
  47. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/ldiff +0 -0
  48. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/nokogiri +0 -0
  49. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/rackup +0 -0
  50. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/rails +0 -0
  51. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/rake +0 -0
  52. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/rspec +0 -0
  53. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/ruby-parse +0 -0
  54. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/ruby-rewrite +0 -0
  55. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/sequel +0 -0
  56. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/setup +0 -0
  57. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/sprockets +0 -0
  58. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/thor +0 -0
  59. data/spec/fixtures/{rails_users_app → rails5_users_app}/bin/update +0 -0
  60. data/spec/fixtures/{rails_users_app → rails5_users_app}/config.ru +0 -0
  61. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/application.rb +0 -0
  62. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/boot.rb +0 -0
  63. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/credentials.yml.enc +0 -0
  64. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/database.yml +0 -0
  65. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/environment.rb +0 -0
  66. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/environments/development.rb +0 -0
  67. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/environments/production.rb +0 -0
  68. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/environments/test.rb +0 -0
  69. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/initializers/application_controller_renderer.rb +0 -0
  70. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/initializers/backtrace_silencers.rb +0 -0
  71. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/initializers/cors.rb +0 -0
  72. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/initializers/filter_parameter_logging.rb +0 -0
  73. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/initializers/inflections.rb +0 -0
  74. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/initializers/mime_types.rb +0 -0
  75. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/initializers/record_button.rb +0 -0
  76. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/initializers/wrap_parameters.rb +0 -0
  77. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/locales/en.yml +0 -0
  78. data/spec/fixtures/{rails_users_app → rails5_users_app}/config/routes.rb +0 -0
  79. data/spec/fixtures/{rails_users_app → rails5_users_app}/create_app +0 -0
  80. data/spec/fixtures/{rails_users_app → rails5_users_app}/db/migrate/20190728211408_create_users.rb +0 -0
  81. data/spec/fixtures/{rails_users_app → rails5_users_app}/db/schema.rb +0 -0
  82. data/spec/fixtures/{rails_users_app → rails5_users_app}/docker-compose.yml +0 -0
  83. data/spec/fixtures/{rails_users_app → rails5_users_app}/features/api_users.feature +0 -0
  84. data/spec/fixtures/{rails_users_app → rails5_users_app}/features/support/env.rb +0 -0
  85. data/spec/fixtures/{rails_users_app → rails5_users_app}/features/support/hooks.rb +0 -0
  86. data/spec/fixtures/{rails_users_app → rails5_users_app}/features/support/steps.rb +0 -0
  87. data/spec/fixtures/{rails_users_app → rails5_users_app}/lib/tasks/.keep +0 -0
  88. data/spec/fixtures/{rails_users_app → rails5_users_app}/log/.keep +0 -0
  89. data/spec/fixtures/{rails_users_app → rails5_users_app}/public/robots.txt +0 -0
  90. data/spec/fixtures/{rails_users_app → rails5_users_app}/spec/controllers/users_controller_api_spec.rb +0 -0
  91. data/spec/fixtures/{rails_users_app → rails5_users_app}/spec/models/user_spec.rb +0 -0
  92. data/spec/fixtures/{rails_users_app → rails5_users_app}/spec/rails_helper.rb +0 -0
  93. data/spec/fixtures/{rails_users_app → rails5_users_app}/spec/spec_helper.rb +0 -0
  94. data/spec/fixtures/{rails_users_app → rails5_users_app}/users_app/.gitignore +0 -0
  95. data/spec/fixtures/rails6_users_app/.dockerignore +1 -0
  96. data/spec/fixtures/rails6_users_app/.gitignore +39 -0
  97. data/spec/fixtures/rails6_users_app/.rspec +1 -0
  98. data/spec/fixtures/{rails_users_app → rails6_users_app}/.ruby-version +0 -0
  99. data/spec/fixtures/rails6_users_app/Dockerfile +29 -0
  100. data/spec/fixtures/rails6_users_app/Dockerfile.pg +3 -0
  101. data/spec/fixtures/{rails_users_app → rails6_users_app}/Gemfile +0 -0
  102. data/spec/fixtures/rails6_users_app/Rakefile +6 -0
  103. data/spec/fixtures/rails6_users_app/app/controllers/api/users_controller.rb +27 -0
  104. data/spec/fixtures/rails6_users_app/app/controllers/application_controller.rb +2 -0
  105. data/spec/fixtures/rails6_users_app/app/controllers/concerns/.keep +0 -0
  106. data/spec/fixtures/rails6_users_app/app/controllers/health_controller.rb +5 -0
  107. data/spec/fixtures/rails6_users_app/app/controllers/users_controller.rb +5 -0
  108. data/spec/fixtures/rails6_users_app/app/models/activerecord/user.rb +18 -0
  109. data/spec/fixtures/rails6_users_app/app/models/concerns/.keep +0 -0
  110. data/spec/fixtures/rails6_users_app/app/models/sequel/user.rb +25 -0
  111. data/spec/fixtures/rails6_users_app/app/views/layouts/application.html.haml +7 -0
  112. data/spec/fixtures/rails6_users_app/app/views/users/index.html.haml +7 -0
  113. data/spec/fixtures/rails6_users_app/appmap.yml +3 -0
  114. data/spec/fixtures/rails6_users_app/bin/appmap +29 -0
  115. data/spec/fixtures/rails6_users_app/bin/byebug +29 -0
  116. data/spec/fixtures/rails6_users_app/bin/gli +29 -0
  117. data/spec/fixtures/rails6_users_app/bin/htmldiff +29 -0
  118. data/spec/fixtures/rails6_users_app/bin/ldiff +29 -0
  119. data/spec/fixtures/rails6_users_app/bin/nokogiri +29 -0
  120. data/spec/fixtures/rails6_users_app/bin/rackup +29 -0
  121. data/spec/fixtures/rails6_users_app/bin/rails +4 -0
  122. data/spec/fixtures/rails6_users_app/bin/rake +29 -0
  123. data/spec/fixtures/rails6_users_app/bin/rspec +29 -0
  124. data/spec/fixtures/rails6_users_app/bin/ruby-parse +29 -0
  125. data/spec/fixtures/rails6_users_app/bin/ruby-rewrite +29 -0
  126. data/spec/fixtures/rails6_users_app/bin/sequel +29 -0
  127. data/spec/fixtures/rails6_users_app/bin/setup +25 -0
  128. data/spec/fixtures/rails6_users_app/bin/sprockets +29 -0
  129. data/spec/fixtures/rails6_users_app/bin/thor +29 -0
  130. data/spec/fixtures/rails6_users_app/bin/update +25 -0
  131. data/spec/fixtures/rails6_users_app/config.ru +5 -0
  132. data/spec/fixtures/rails6_users_app/config/application.rb +51 -0
  133. data/spec/fixtures/rails6_users_app/config/boot.rb +3 -0
  134. data/spec/fixtures/rails6_users_app/config/credentials.yml.enc +1 -0
  135. data/spec/fixtures/rails6_users_app/config/database.yml +18 -0
  136. data/spec/fixtures/rails6_users_app/config/environment.rb +5 -0
  137. data/spec/fixtures/rails6_users_app/config/environments/development.rb +40 -0
  138. data/spec/fixtures/rails6_users_app/config/environments/production.rb +68 -0
  139. data/spec/fixtures/rails6_users_app/config/environments/test.rb +36 -0
  140. data/spec/fixtures/rails6_users_app/config/initializers/application_controller_renderer.rb +8 -0
  141. data/spec/fixtures/rails6_users_app/config/initializers/backtrace_silencers.rb +7 -0
  142. data/spec/fixtures/rails6_users_app/config/initializers/cors.rb +16 -0
  143. data/spec/fixtures/rails6_users_app/config/initializers/filter_parameter_logging.rb +4 -0
  144. data/spec/fixtures/rails6_users_app/config/initializers/inflections.rb +16 -0
  145. data/spec/fixtures/rails6_users_app/config/initializers/mime_types.rb +4 -0
  146. data/spec/fixtures/rails6_users_app/config/initializers/record_button.rb +3 -0
  147. data/spec/fixtures/rails6_users_app/config/initializers/wrap_parameters.rb +9 -0
  148. data/spec/fixtures/rails6_users_app/config/locales/en.yml +33 -0
  149. data/spec/fixtures/rails6_users_app/config/routes.rb +11 -0
  150. data/spec/fixtures/rails6_users_app/create_app +27 -0
  151. data/spec/fixtures/rails6_users_app/db/migrate/20190728211408_create_users.rb +9 -0
  152. data/spec/fixtures/rails6_users_app/db/schema.rb +23 -0
  153. data/spec/fixtures/rails6_users_app/docker-compose.yml +28 -0
  154. data/spec/fixtures/rails6_users_app/features/api_users.feature +13 -0
  155. data/spec/fixtures/rails6_users_app/features/support/env.rb +4 -0
  156. data/spec/fixtures/rails6_users_app/features/support/hooks.rb +11 -0
  157. data/spec/fixtures/rails6_users_app/features/support/steps.rb +18 -0
  158. data/spec/fixtures/rails6_users_app/lib/tasks/.keep +0 -0
  159. data/spec/fixtures/rails6_users_app/log/.keep +0 -0
  160. data/spec/fixtures/rails6_users_app/public/robots.txt +1 -0
  161. data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_api_spec.rb +29 -0
  162. data/spec/fixtures/rails6_users_app/spec/models/user_spec.rb +39 -0
  163. data/spec/fixtures/rails6_users_app/spec/rails_helper.rb +66 -0
  164. data/spec/fixtures/rails6_users_app/spec/spec_helper.rb +96 -0
  165. data/spec/fixtures/rails6_users_app/users_app/.gitignore +20 -0
  166. data/spec/hook_spec.rb +196 -11
  167. data/spec/rails_spec_helper.rb +5 -5
  168. data/spec/railtie_spec.rb +31 -32
  169. data/spec/record_sql_rails4_pg_spec.rb +47 -48
  170. data/spec/record_sql_rails_pg_spec.rb +62 -63
  171. data/spec/remote_recording_spec.rb +90 -89
  172. data/spec/rspec_feature_metadata_spec.rb +17 -18
  173. data/test/cli_test.rb +0 -10
  174. data/test/expectations/openssl_test_key_sign1.json +55 -0
  175. data/test/expectations/openssl_test_key_sign2.json +58 -0
  176. data/test/fixtures/gem_test/Gemfile +6 -0
  177. data/test/fixtures/gem_test/appmap.yml +3 -0
  178. data/test/fixtures/gem_test/test/to_param_test.rb +14 -0
  179. data/test/gem_test.rb +34 -0
  180. data/test/minitest_test.rb +2 -2
  181. data/test/openssl_test.rb +10 -165
  182. metadata +171 -80
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 587d9e4e90152c5ab6b04d4fa6b95d3071419563d82f4ed3c609def87111757b
4
- data.tar.gz: b1867167f44a1f244e165a628293415dd54bcaacb0b4471c5d30c26dce3bef64
3
+ metadata.gz: 0211b21334945f6786d150fdf1a0dea8a062cbc2d59c4b347f72555232ec6480
4
+ data.tar.gz: ac2785471ed35210ba1c3801e8a7d186adb99d9b9369c24eb2c9f4d41a352e33
5
5
  SHA512:
6
- metadata.gz: 23a6e927bda905ce13666aa514040415bbaf0b8f317ffac524b1f0f94de58de17c175e001c921825ac0cbe05287a3e137899e5a5f86609cdbd9ce4000b4cbe4f
7
- data.tar.gz: dcd2ad0a96709cc28f383726c56e133a75ba81e3edbd6679913afc7c1ae4097c3767c79b07ebf5bc9357c40660be00d39205dcbf4c1316a7add323b613a2f1a3
6
+ metadata.gz: d5049f8c464b5f6e6afd7567fcfe62d481c70b7db6d473f93a832763e4352c04b6d2cff3d3d03a452f82033f4220cb821f36152c003794c7adba89432a2b513a
7
+ data.tar.gz: 631f8ab86e132e45c1b95b667d7789b870eab393293d62c7e1f77daf3cf3f9a5c7174e913fa0bc20ec92a87f88f278bee69f41c6b2c14d166b1745df71321d0b
@@ -1,5 +1,5 @@
1
1
  vendor
2
2
  node_modules
3
- spec/fixtures/rails_users_app
3
+ spec/fixtures/rails*_users_app
4
4
  spec/fixtures/rack_users_app
5
5
 
data/.gitignore CHANGED
@@ -14,4 +14,5 @@ Gemfile.lock
14
14
  appmap.json
15
15
  .vscode
16
16
  .byebug_history
17
- /lib/appmap/appmap.bundle
17
+ /lib/appmap/appmap.bundle
18
+ *.so
@@ -1,3 +1,9 @@
1
+ AllCops:
2
+ NewCops: enable
3
+
4
+ Layout/CaseIndentation:
5
+ EnforcedStyle: end
6
+
1
7
  Layout/SpaceInsideArrayLiteralBrackets:
2
8
  Enabled: false
3
9
 
@@ -8,6 +14,10 @@ Layout/HeredocIndentation:
8
14
  Layout/LineLength:
9
15
  Max: 120
10
16
 
17
+ Metrics/BlockLength:
18
+ ExcludedMethods:
19
+ - it
20
+
11
21
  Style/MultilineBlockChain:
12
22
  Enabled: false
13
23
 
@@ -1,3 +1,25 @@
1
+ # v0.37.2
2
+ * Fix ParameterFilter deprecation warning.
3
+
4
+ # v0.37.1
5
+ * Fix parameter mapping with keyword and rest arguments.
6
+
7
+ # v0.37.0
8
+ * Capture method source and comment.
9
+
10
+ # v0.36.0
11
+ * *appmap.yml* package definition may specify `gem`.
12
+ * Skip loading the railtie if `APPMAP_INITIALIZE` environment variable
13
+ is set to `false`.
14
+
15
+ # v0.35.2
16
+ * Make sure `MethodEvent#display_string` works when the value's `#to_s` and/or `#inspect`
17
+ methods have problems.
18
+
19
+ # v0.35.1
20
+ * Take out hooking of `IO` and `Logger` methods.
21
+ * Enable logging if either `APPMAP_DEBUG` or `DEBUG` is `true`.
22
+
1
23
  # v0.35.0
2
24
  * Provide a custom display string for files and HTTP requests.
3
25
  * Report `mime_type` on HTTP response.
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  - [About](#about)
2
3
  - [Installation](#installation)
3
4
  - [Configuration](#configuration)
@@ -13,7 +14,7 @@
13
14
  - [Using fixture apps](#using-fixture-apps)
14
15
  - [`test/fixtures`](#testfixtures)
15
16
  - [`spec/fixtures`](#specfixtures)
16
- - [Build status](#build-status)
17
+
17
18
 
18
19
  # About
19
20
 
@@ -27,8 +28,9 @@ granular than a full debug trace. It's designed to be optimal for understanding
27
28
  There are several ways to record AppMaps of your Ruby program using the `appmap` gem:
28
29
 
29
30
  * Run your RSpec tests with the environment variable `APPMAP=true`. An AppMap will be generated for each spec.
30
- * Run your application server with AppMap remote recording enabled, and use the AppMap.
31
- browser extension to start, stop, and upload recordings.
31
+ * Run your application server with AppMap remote recording enabled, and use the [AppLand
32
+ browser extension](https://github.com/applandinc/appland-browser-extension) to start,
33
+ stop, and upload recordings.
32
34
  * Run the command `appmap record <program>` to record the entire execution of a program.
33
35
 
34
36
  Once you have recorded some AppMaps (for example, by running RSpec tests), you use the `appland upload` command
@@ -76,6 +78,7 @@ name: MyProject
76
78
  packages:
77
79
  - path: app/controllers
78
80
  - path: app/models
81
+ - gem: activerecord
79
82
  ```
80
83
 
81
84
  * **name** Provides the project name (required)
@@ -87,6 +90,7 @@ Each entry in the `packages` list is a YAML object which has the following keys:
87
90
 
88
91
  * **path** The path to the source code directory. The path may be relative to the current working directory, or it may
89
92
  be an absolute path.
93
+ * **gem** As an alternative to specifying the path, specify the name of a dependency gem. When using `gem`, don't specify `path`.
90
94
  * **exclude** A list of files and directories which will be ignored. By default, all modules, classes and public
91
95
  functions are inspected.
92
96
 
@@ -248,11 +252,11 @@ end
248
252
  $ bundle exec rails server
249
253
  ```
250
254
 
251
- 4. Open the AppApp browser extension and push `Start`.
255
+ 4. Open the AppLand browser extension and push `Start`.
252
256
 
253
257
  5. Use your app. For example, perform a login flow, or run through a manual UI test.
254
258
 
255
- 6. Open the AppApp browser extension and push `Stop`. The recording will be transferred to the AppLand website and opened in your browser.
259
+ 6. Open the AppLand browser extension and push `Stop`. The recording will be transferred to the AppLand website and opened in your browser.
256
260
 
257
261
  ## Ruby on Rails
258
262
 
@@ -265,6 +269,7 @@ Note that using this method is kind of a blunt instrument. Recording RSpecs and
265
269
  For instructions on uploading, see the documentation of the [AppLand CLI](https://github.com/applandinc/appland-cli).
266
270
 
267
271
  # Development
272
+ [![Build Status](https://travis-ci.org/applandinc/appmap-ruby.svg?branch=master)](https://travis-ci.org/applandinc/appmap-ruby)
268
273
 
269
274
  ## Running tests
270
275
 
@@ -289,7 +294,7 @@ $ bundle exec rake compile
289
294
  ### `test/fixtures`
290
295
 
291
296
  The fixture apps in `test/fixtures` are plain Ruby projects that exercise the basic functionality of the
292
- `appmap` gem. To develop in a fixture, simple enter the fixture directory and `bundle`.
297
+ `appmap` gem. To develop in a fixture, simply enter the fixture directory and `bundle`.
293
298
 
294
299
  ### `spec/fixtures`
295
300
 
@@ -339,5 +344,3 @@ Finished in 0.07357 seconds (files took 2.1 seconds to load)
339
344
  4 examples, 0 failures
340
345
  ```
341
346
 
342
- # Build status
343
- [![Build Status](https://travis-ci.org/applandinc/appmap-ruby.svg?branch=master)](https://travis-ci.org/applandinc/appmap-ruby)
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ $: << File.join(__dir__, 'lib')
1
2
  require 'appmap/version'
2
3
  GEM_VERSION = AppMap::VERSION
3
4
 
@@ -18,7 +19,7 @@ namespace 'gem' do
18
19
  end
19
20
 
20
21
  RUBY_VERSIONS=%w[2.5 2.6]
21
- FIXTURE_APPS=%w[rack_users_app rails_users_app rails4_users_app]
22
+ FIXTURE_APPS=%w[rack_users_app rails6_users_app rails5_users_app rails4_users_app]
22
23
 
23
24
  def run_cmd(*cmd)
24
25
  $stderr.puts "Running: #{cmd}"
@@ -113,7 +114,7 @@ namespace :spec do
113
114
  desc ruby_version
114
115
  task ruby_version, [:specs] => ["compile", "build:fixtures:#{ruby_version}:all"] do |_, task_args|
115
116
  run_specs(ruby_version, task_args)
116
- end.tap do|t|
117
+ end.tap do |t|
117
118
  desc "Run all specs"
118
119
  task :all, [:specs] => t
119
120
  end
@@ -27,10 +27,11 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency 'activesupport'
28
28
  spec.add_dependency 'faraday'
29
29
  spec.add_dependency 'gli'
30
+ spec.add_dependency 'method_source'
30
31
  spec.add_dependency 'parser'
31
32
  spec.add_dependency 'rack'
32
33
 
33
- spec.add_development_dependency 'bundler', '~> 1.16'
34
+ spec.add_development_dependency 'bundler', '>= 1.16'
34
35
  spec.add_development_dependency 'minitest', '~> 5.0'
35
36
  spec.add_development_dependency 'pry-byebug'
36
37
  spec.add_development_dependency 'rake', '>= 12.3.3'
data/appmap.yml CHANGED
@@ -1,8 +1,2 @@
1
1
  name: AppMap Rubygem
2
- packages:
3
- - path: lib/appmap
4
- exclude:
5
- - server
6
- - trace
7
-
8
- - path: examples
2
+ packages: []
@@ -83,8 +83,8 @@ module AppMap
83
83
  end
84
84
 
85
85
  # Builds a class map from a config and a list of Ruby methods.
86
- def class_map(methods)
87
- ClassMap.build_from_methods(methods)
86
+ def class_map(methods, options = {})
87
+ ClassMap.build_from_methods(methods, options)
88
88
  end
89
89
 
90
90
  # Returns default metadata detected from the Ruby system and from the
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'method_source'
4
+
3
5
  module AppMap
4
6
  class ClassMap
5
7
  module HasChildren
@@ -48,7 +50,7 @@ module AppMap
48
50
  end
49
51
  end
50
52
  Function = Struct.new(:name) do
51
- attr_accessor :static, :location, :labels
53
+ attr_accessor :static, :location, :labels, :comment, :source
52
54
 
53
55
  def type
54
56
  'function'
@@ -60,30 +62,32 @@ module AppMap
60
62
  type: type,
61
63
  location: location,
62
64
  static: static,
63
- labels: labels
65
+ labels: labels,
66
+ comment: comment,
67
+ source: source
64
68
  }.delete_if { |_, v| v.nil? || v == [] }
65
69
  end
66
70
  end
67
71
  end
68
72
 
69
73
  class << self
70
- def build_from_methods(methods)
74
+ def build_from_methods(methods, options = {})
71
75
  root = Types::Root.new
72
76
  methods.each do |method|
73
- add_function root, method
77
+ add_function root, method, options
74
78
  end
75
79
  root.children.map(&:to_h)
76
80
  end
77
81
 
78
82
  protected
79
83
 
80
- def add_function(root, method)
84
+ def add_function(root, method, include_source: true)
81
85
  package = method.package
82
86
  static = method.static
83
87
 
84
88
  object_infos = [
85
89
  {
86
- name: package.path,
90
+ name: package.name,
87
91
  type: 'package'
88
92
  }
89
93
  ]
@@ -109,6 +113,16 @@ module AppMap
109
113
  [ method.defined_class, static ? '.' : '#', method.name ].join
110
114
  end
111
115
 
116
+ if include_source
117
+ begin
118
+ function_info[:source] = method.source
119
+ comment = method.comment || ''
120
+ function_info[:comment] = comment unless comment.empty?
121
+ rescue MethodSource::SourceNotFoundError
122
+ # pass
123
+ end
124
+ end
125
+
112
126
  function_info[:labels] = package.labels if package.labels
113
127
  object_infos << function_info
114
128
 
@@ -2,15 +2,39 @@
2
2
 
3
3
  module AppMap
4
4
  class Config
5
- Package = Struct.new(:path, :package_name, :exclude, :labels) do
6
- def initialize(path, package_name: nil, exclude: [], labels: [])
7
- super path, package_name, exclude, labels
5
+ Package = Struct.new(:path, :gem, :package_name, :exclude, :labels) do
6
+ class << self
7
+ def build_from_path(path, package_name: nil, exclude: [], labels: [])
8
+ Package.new(path, nil, package_name, exclude, labels)
9
+ end
10
+
11
+ def build_from_gem(gem, package_name: nil, exclude: [], labels: [])
12
+ gem_paths(gem).map do |gem_path|
13
+ Package.new(gem_path, gem, package_name, exclude, labels)
14
+ end
15
+ end
16
+
17
+ private_class_method :new
18
+
19
+ protected
20
+
21
+ def gem_paths(gem)
22
+ gemspec = Gem.loaded_specs[gem] or raise "Gem #{gem.inspect} not found"
23
+ gemspec.source_paths.map do |path|
24
+ File.join(gemspec.gem_dir, path)
25
+ end
26
+ end
27
+ end
28
+
29
+ def name
30
+ gem || path
8
31
  end
9
32
 
10
33
  def to_h
11
34
  {
12
35
  path: path,
13
36
  package_name: package_name,
37
+ gem: gem,
14
38
  exclude: exclude.blank? ? nil : exclude,
15
39
  labels: labels.blank? ? nil : labels
16
40
  }.compact
@@ -20,31 +44,29 @@ module AppMap
20
44
  Hook = Struct.new(:method_names, :package) do
21
45
  end
22
46
 
23
- OPENSSL_PACKAGE = Package.new('openssl', package_name: 'openssl', labels: %w[security crypto])
47
+ OPENSSL_PACKAGES = Package.build_from_path('openssl', package_name: 'openssl', labels: %w[security crypto])
24
48
 
25
49
  # Methods that should always be hooked, with their containing
26
50
  # package and labels that should be applied to them.
27
51
  HOOKED_METHODS = {
28
- 'ActiveSupport::SecurityUtils' => Hook.new(:secure_compare, Package.new('active_support', package_name: 'active_support', labels: %w[security crypto]))
52
+ 'ActiveSupport::SecurityUtils' => Hook.new(:secure_compare, Package.build_from_path('active_support', package_name: 'active_support', labels: %w[security crypto]))
29
53
  }.freeze
30
54
 
31
55
  BUILTIN_METHODS = {
32
- 'OpenSSL::PKey::PKey' => Hook.new(:sign, OPENSSL_PACKAGE),
33
- 'Digest::Instance' => Hook.new(:digest, OPENSSL_PACKAGE),
34
- 'OpenSSL::X509::Request' => Hook.new(%i[sign verify], OPENSSL_PACKAGE),
35
- 'OpenSSL::PKCS5' => Hook.new(%i[pbkdf2_hmac_sha1 pbkdf2_hmac], OPENSSL_PACKAGE),
36
- 'OpenSSL::Cipher' => Hook.new(%i[encrypt decrypt final], OPENSSL_PACKAGE),
37
- 'OpenSSL::X509::Certificate' => Hook.new(:sign, OPENSSL_PACKAGE),
38
- 'Logger' => Hook.new(:add, Package.new('logger', labels: %w[log io])),
39
- 'Net::HTTP' => Hook.new(:request, Package.new('net/http', package_name: 'net/http', labels: %w[http io])),
40
- 'Net::SMTP' => Hook.new(:send, Package.new('net/smtp', package_name: 'net/smtp', labels: %w[smtp email io])),
41
- 'Net::POP3' => Hook.new(:mails, Package.new('net/pop3', package_name: 'net/pop', labels: %w[pop pop3 email io])),
42
- 'Net::IMAP' => Hook.new(:send_command, Package.new('net/imap', package_name: 'net/imap', labels: %w[imap email io])),
43
- 'IO' => Hook.new(%i[read write open close], Package.new('io', labels: %w[io])),
44
- 'Marshal' => Hook.new(%i[dump load], Package.new('marshal', labels: %w[serialization marshal])),
45
- 'Psych' => Hook.new(%i[dump dump_stream load load_stream parse parse_stream], Package.new('yaml', package_name: 'psych', labels: %w[serialization yaml])),
46
- 'JSON::Ext::Parser' => Hook.new(:parse, Package.new('json', package_name: 'json', labels: %w[serialization json])),
47
- 'JSON::Ext::Generator::State' => Hook.new(:generate, Package.new('json', package_name: 'json', labels: %w[serialization json]))
56
+ 'OpenSSL::PKey::PKey' => Hook.new(:sign, OPENSSL_PACKAGES),
57
+ 'Digest::Instance' => Hook.new(:digest, OPENSSL_PACKAGES),
58
+ 'OpenSSL::X509::Request' => Hook.new(%i[sign verify], OPENSSL_PACKAGES),
59
+ 'OpenSSL::PKCS5' => Hook.new(%i[pbkdf2_hmac_sha1 pbkdf2_hmac], OPENSSL_PACKAGES),
60
+ 'OpenSSL::Cipher' => Hook.new(%i[encrypt decrypt final], OPENSSL_PACKAGES),
61
+ 'OpenSSL::X509::Certificate' => Hook.new(:sign, OPENSSL_PACKAGES),
62
+ 'Net::HTTP' => Hook.new(:request, Package.build_from_path('net/http', package_name: 'net/http', labels: %w[http io])),
63
+ 'Net::SMTP' => Hook.new(:send, Package.build_from_path('net/smtp', package_name: 'net/smtp', labels: %w[smtp email io])),
64
+ 'Net::POP3' => Hook.new(:mails, Package.build_from_path('net/pop3', package_name: 'net/pop', labels: %w[pop pop3 email io])),
65
+ 'Net::IMAP' => Hook.new(:send_command, Package.build_from_path('net/imap', package_name: 'net/imap', labels: %w[imap email io])),
66
+ 'Marshal' => Hook.new(%i[dump load], Package.build_from_path('marshal', labels: %w[serialization marshal])),
67
+ 'Psych' => Hook.new(%i[dump dump_stream load load_stream parse parse_stream], Package.build_from_path('yaml', package_name: 'psych', labels: %w[serialization yaml])),
68
+ 'JSON::Ext::Parser' => Hook.new(:parse, Package.build_from_path('json', package_name: 'json', labels: %w[serialization json])),
69
+ 'JSON::Ext::Generator::State' => Hook.new(:generate, Package.build_from_path('json', package_name: 'json', labels: %w[serialization json]))
48
70
  }.freeze
49
71
 
50
72
  attr_reader :name, :packages
@@ -64,8 +86,16 @@ module AppMap
64
86
  # Loads configuration from a Hash.
65
87
  def load(config_data)
66
88
  packages = (config_data['packages'] || []).map do |package|
67
- Package.new(package['path'], exclude: package['exclude'] || [])
68
- end
89
+ gem = package['gem']
90
+ path = package['path']
91
+ raise 'AppMap package configuration should specify gem or path, not both' if gem && path
92
+
93
+ if gem
94
+ Package.build_from_gem(gem, exclude: package['exclude'] || [])
95
+ else
96
+ [ Package.build_from_path(path, exclude: package['exclude'] || []) ]
97
+ end
98
+ end.flatten
69
99
  Config.new config_data['name'], packages
70
100
  end
71
101
  end
@@ -31,11 +31,6 @@ module AppMap
31
31
  def display_string(value)
32
32
  return nil unless value
33
33
 
34
- last_resort_string = lambda do
35
- warn "AppMap encountered an error inspecting a #{value.class.name}: #{$!.message}"
36
- '*Error inspecting variable*'
37
- end
38
-
39
34
  value_string = custom_display_string(value) || default_display_string(value)
40
35
 
41
36
  (value_string||'')[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
@@ -57,6 +52,11 @@ module AppMap
57
52
  end
58
53
 
59
54
  def default_display_string(value)
55
+ last_resort_string = lambda do
56
+ warn "AppMap encountered an error inspecting a #{value.class.name}: #{$!.message}"
57
+ '*Error inspecting variable*'
58
+ end
59
+
60
60
  begin
61
61
  value.to_s
62
62
  rescue NoMethodError
@@ -89,10 +89,25 @@ module AppMap
89
89
  else
90
90
  mc.path = [ defined_class, static ? '.' : '#', method.name ].join
91
91
  end
92
+
93
+ # Check if the method has key parameters. If there are any they'll always be last.
94
+ # If yes, then extract it from arguments.
95
+ has_key = [[:dummy], *method.parameters].last.first.to_s.start_with?('key') && arguments[-1].is_a?(Hash)
96
+ kwargs = has_key && arguments[-1].dup || {}
97
+
92
98
  mc.parameters = method.parameters.map.with_index do |method_param, idx|
93
99
  param_type, param_name = method_param
94
100
  param_name ||= 'arg'
95
- value = arguments[idx]
101
+ value = case param_type
102
+ when :keyrest
103
+ kwargs
104
+ when /^key/
105
+ kwargs.delete param_name
106
+ when :rest
107
+ arguments[idx..(has_key ? -2 : -1)]
108
+ else
109
+ arguments[idx]
110
+ end
96
111
  {
97
112
  name: param_name,
98
113
  class: value.class.name,
@@ -4,7 +4,7 @@ require 'English'
4
4
 
5
5
  module AppMap
6
6
  class Hook
7
- LOG = (ENV['DEBUG'] == 'true')
7
+ LOG = (ENV['APPMAP_DEBUG'] == 'true' || ENV['DEBUG'] == 'true')
8
8
 
9
9
  @unbound_method_arity = ::UnboundMethod.instance_method(:arity)
10
10
  @method_arity = ::Method.instance_method(:arity)