appmap 0.23.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +17 -8
  4. data/.travis.yml +6 -0
  5. data/CHANGELOG.md +43 -0
  6. data/README.md +33 -21
  7. data/Rakefile +3 -3
  8. data/appmap.gemspec +3 -1
  9. data/exe/appmap +5 -73
  10. data/lib/appmap.rb +61 -6
  11. data/lib/appmap/algorithm/prune_class_map.rb +2 -0
  12. data/lib/appmap/algorithm/stats.rb +4 -2
  13. data/lib/appmap/class_map.rb +143 -0
  14. data/lib/appmap/command/record.rb +8 -6
  15. data/lib/appmap/command/stats.rb +2 -0
  16. data/lib/appmap/event.rb +168 -0
  17. data/lib/appmap/hook.rb +152 -0
  18. data/lib/appmap/middleware/remote_recording.rb +14 -21
  19. data/lib/appmap/rails/action_handler.rb +10 -6
  20. data/lib/appmap/rails/sql_handler.rb +10 -13
  21. data/lib/appmap/railtie.rb +31 -18
  22. data/lib/appmap/rspec.rb +247 -260
  23. data/lib/appmap/trace.rb +88 -0
  24. data/lib/appmap/version.rb +1 -1
  25. data/package-lock.json +90 -92
  26. data/spec/abstract_controller4_base_spec.rb +1 -1
  27. data/spec/abstract_controller_base_spec.rb +7 -3
  28. data/spec/config_spec.rb +25 -0
  29. data/spec/fixtures/hook/attr_accessor.rb +5 -0
  30. data/spec/fixtures/hook/class_method.rb +17 -0
  31. data/spec/fixtures/hook/constructor.rb +7 -0
  32. data/spec/fixtures/hook/exception_method.rb +11 -0
  33. data/spec/fixtures/hook/instance_method.rb +23 -0
  34. data/spec/fixtures/rails4_users_app/app/controllers/api/users_controller.rb +3 -3
  35. data/spec/fixtures/rails4_users_app/config/database.yml +2 -1
  36. data/spec/fixtures/rails4_users_app/docker-compose.yml +2 -0
  37. data/spec/fixtures/rails_users_app/.ruby-version +1 -1
  38. data/spec/fixtures/rails_users_app/app/controllers/api/users_controller.rb +2 -2
  39. data/spec/fixtures/rails_users_app/config/database.yml +2 -1
  40. data/spec/fixtures/rails_users_app/create_app +1 -0
  41. data/spec/fixtures/rails_users_app/docker-compose.yml +4 -0
  42. data/spec/fixtures/rails_users_app/spec/models/user_spec.rb +1 -1
  43. data/spec/hook_spec.rb +369 -0
  44. data/spec/rails_spec_helper.rb +25 -16
  45. data/spec/railtie_spec.rb +1 -1
  46. data/spec/record_sql_rails_pg_spec.rb +1 -2
  47. data/spec/remote_recording_spec.rb +117 -0
  48. data/spec/spec_helper.rb +5 -0
  49. data/test/cli_test.rb +4 -46
  50. data/test/fixtures/cli_record_test/appmap.yml +2 -1
  51. data/test/fixtures/cli_record_test/lib/cli_record_test/main.rb +4 -2
  52. data/test/fixtures/rspec_recorder/Gemfile +1 -1
  53. data/test/fixtures/rspec_recorder/spec/decorated_hello_spec.rb +12 -0
  54. data/test/rspec_test.rb +5 -0
  55. data/test/test_helper.rb +0 -42
  56. metadata +46 -63
  57. data/exe/_appmap-record-self +0 -49
  58. data/lib/appmap/command/inspect.rb +0 -14
  59. data/lib/appmap/command/upload.rb +0 -99
  60. data/lib/appmap/config.rb +0 -65
  61. data/lib/appmap/config/directory.rb +0 -65
  62. data/lib/appmap/config/file.rb +0 -13
  63. data/lib/appmap/config/named_function.rb +0 -21
  64. data/lib/appmap/config/package_dir.rb +0 -52
  65. data/lib/appmap/config/path.rb +0 -25
  66. data/lib/appmap/feature.rb +0 -262
  67. data/lib/appmap/inspect.rb +0 -91
  68. data/lib/appmap/inspect/inspector.rb +0 -99
  69. data/lib/appmap/inspect/parse_node.rb +0 -170
  70. data/lib/appmap/inspect/parser.rb +0 -15
  71. data/lib/appmap/parser.rb +0 -60
  72. data/lib/appmap/rspec/parse_node.rb +0 -41
  73. data/lib/appmap/rspec/parser.rb +0 -15
  74. data/lib/appmap/trace/event_handler/rack_handler_webrick.rb +0 -65
  75. data/lib/appmap/trace/tracer.rb +0 -356
  76. data/spec/fixtures/rails_users_app/bin/_appmap-record-self +0 -29
  77. data/spec/rack_handler_webrick_spec.rb +0 -59
  78. data/test/config_test.rb +0 -149
  79. data/test/explict_inspect_test.rb +0 -29
  80. data/test/fixtures/active_record_like/active_record.rb +0 -2
  81. data/test/fixtures/active_record_like/active_record/aggregations.rb +0 -4
  82. data/test/fixtures/active_record_like/active_record/association.rb +0 -4
  83. data/test/fixtures/active_record_like/active_record/associations/join_dependency.rb +0 -6
  84. data/test/fixtures/active_record_like/active_record/associations/join_dependency/join_base.rb +0 -8
  85. data/test/fixtures/active_record_like/active_record/associations/join_dependency/join_part.rb +0 -8
  86. data/test/fixtures/active_record_like/active_record/caps/caps.rb +0 -4
  87. data/test/fixtures/ignore_non_ruby_file/class.rb +0 -3
  88. data/test/fixtures/ignore_non_ruby_file/non-ruby.txt +0 -1
  89. data/test/fixtures/includes_excludes/lib/a/a_1.rb +0 -6
  90. data/test/fixtures/includes_excludes/lib/a/a_2.rb +0 -6
  91. data/test/fixtures/includes_excludes/lib/a/x/x_1.rb +0 -8
  92. data/test/fixtures/includes_excludes/lib/b/b_1.rb +0 -6
  93. data/test/fixtures/includes_excludes/lib/root_1.rb +0 -4
  94. data/test/fixtures/inspect_multiple_subdirs/module_a.rb +0 -2
  95. data/test/fixtures/inspect_multiple_subdirs/module_a/class_a.rb +0 -5
  96. data/test/fixtures/inspect_multiple_subdirs/module_b.rb +0 -2
  97. data/test/fixtures/inspect_multiple_subdirs/module_b/class_b.rb +0 -5
  98. data/test/fixtures/inspect_multiple_subdirs/module_b/class_c.rb +0 -5
  99. data/test/fixtures/inspect_package/module_a/module_b/class_in_module.rb +0 -6
  100. data/test/fixtures/parse_file/defs_static_function.rb +0 -96
  101. data/test/fixtures/parse_file/function_within_class.rb +0 -36
  102. data/test/fixtures/parse_file/include_public_methods.rb +0 -127
  103. data/test/fixtures/parse_file/instance_function.rb +0 -17
  104. data/test/fixtures/parse_file/modules.rb +0 -71
  105. data/test/fixtures/parse_file/sclass_static_function.rb +0 -88
  106. data/test/fixtures/parse_file/toplevel_class.rb +0 -13
  107. data/test/fixtures/parse_file/toplevel_function.rb +0 -14
  108. data/test/fixtures/trace_test/trace_program_1.rb +0 -44
  109. data/test/implicit_inspect_test.rb +0 -33
  110. data/test/include_exclude_test.rb +0 -48
  111. data/test/prerecorded_trace_test.rb +0 -76
  112. data/test/trace_test.rb +0 -92
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ba1394503aa1c8f498901ed3c7b903af4bcf5b60b16fe48eee08d9c64f66d67
4
- data.tar.gz: 665c48d0d450b2500277b2bdcb54dc356e0b31d442c1f7d9fcb47d0c5c054de6
3
+ metadata.gz: fd23faab460498cfac79b397c4fc87920df8d1a984142909542f524057d1e4cb
4
+ data.tar.gz: a967224c65d6a479287768389feb73a378e6e1be133f1033d06be6034a43b18e
5
5
  SHA512:
6
- metadata.gz: 279932323e5ca1ba95eb42a7bc4410e795fb308b2861c1b3ee2bb29ece31e54664983731648967e82ce4367813eb67557791c21bab16cfc67192d743b34d7568
7
- data.tar.gz: 0141f02617969b168a2dd0c158e8fbfd5b85caa5bc3fa23691c049ae37adefa269d8e76c3c37b4f08f139bc20071b53bf7b31056b2df1c5dfafef44123a7136b
6
+ metadata.gz: 7822e4c821cb5e57579163fdd080bc3b74fb5ad0c8999bc6e3d29ace636301d8ed931966abfe9a59a6a59603f83af03e82130c241293ee198173ef6f6f41ebd1
7
+ data.tar.gz: 8ba03667929d4571e13439ab53420934e0b1c9ee4605dfd71e9a7ff82b984d34e37ca43e206cbf5dc750201df93dc8dc9babbdafbadf12a86051e52efc6ef985
data/.gitignore CHANGED
@@ -13,5 +13,7 @@ vendor
13
13
  node_modules
14
14
  Gemfile.lock
15
15
  appmap.json
16
+ .vscode
16
17
  .byebug_history
17
18
 
19
+ /test/fixtures/rspec_recorder/.bundle/
@@ -1,18 +1,27 @@
1
- Style/MultilineBlockChain:
1
+ Layout/SpaceInsideArrayLiteralBrackets:
2
2
  Enabled: false
3
3
 
4
- Style/NumericPredicate:
4
+ # We have squiggly heredocs
5
+ Layout/HeredocIndentation:
5
6
  Enabled: false
6
7
 
7
- Layout/SpaceInsideArrayLiteralBrackets:
8
- Enabled: false
8
+ Layout/LineLength:
9
+ Max: 120
9
10
 
10
- # We have squiggly heredocs
11
- Layout/IndentHeredoc:
11
+ Style/MultilineBlockChain:
12
12
  Enabled: false
13
13
 
14
+ Style/NumericPredicate:
15
+ Enabled: false
16
+
14
17
  Style/AndOr:
15
18
  Enabled: false
16
19
 
17
- Metrics/LineLength:
18
- Max: 120
20
+ Style/HashEachMethods:
21
+ Enabled: true
22
+
23
+ Style/HashTransformKeys:
24
+ Enabled: true
25
+
26
+ Style/HashTransformValues:
27
+ Enabled: true
@@ -1,5 +1,11 @@
1
1
  language: ruby
2
2
 
3
+ addons:
4
+ apt:
5
+ packages:
6
+ # https://docs.travis-ci.com/user/docker/#installing-a-newer-docker-version
7
+ - docker-ce
8
+
3
9
  services:
4
10
  - docker
5
11
 
@@ -1,3 +1,46 @@
1
+ # v0.27.0
2
+
3
+ * Add **AppMap.record** to programatically record and capture an AppMap of a Ruby block.
4
+
5
+ # v0.26.1
6
+
7
+ * Fix a bug that caused duplicate entries in the list of frameworks that appear
8
+ in the `metadata` section of an appmap.
9
+
10
+ # v0.26.0
11
+
12
+ * **appmap upload** is removed. Upload functionality has been moved to
13
+ the [AppLand CLI](https://github.com/applandinc/appland-cli).
14
+
15
+ # v0.25.2
16
+
17
+ * Stop checking a whitelist to see if each SQL query should be recorded. Record
18
+ all queries.
19
+
20
+ # v0.25.1
21
+
22
+ * Ensure that caught exceptions are re-raised.
23
+ * Add safety around indexing potentially nil backtrace locations.
24
+
25
+ # v0.25.0
26
+
27
+ * Reports `exceptions` in [function return attributes](https://github.com/applandinc/appmap#function-return-attributes).
28
+
29
+ # v0.24.1
30
+ * Fixes an issue which prevented a remote recording from returning scenario data successfully.
31
+ * Remote recording routes now return descriptive status codes as intended.
32
+ * Remote recording routes now have the correct `Content-Type` header.
33
+
34
+ # v0.24.0
35
+
36
+ Internals of `appmap-ruby` have been changed to record each method event using `alias_method`,
37
+ rather than `TracePoint`. Performance is much better as a result.
38
+
39
+ **WARNING** Breaking changes
40
+
41
+ * **Rack** apps no longer generate `http_server_request` events.
42
+ * **appmap inspect** has been removed. `appmap-ruby` no longer parses the source tree. Instead, it observes the methods as they are loaded by the VM. So, to get a class map, you have to create a recording. The `RSpec` recorder still prints an inventory to `Inventory.appmap.json` when it exits. The class map in this file contains every class and method which was loaded by any of the tests.
43
+
1
44
  # v0.23.0
2
45
 
3
46
  * **appmap stats** command added.
data/README.md CHANGED
@@ -1,31 +1,47 @@
1
1
  - [About](#about)
2
+ - [Testing](#testing)
2
3
  - [Installation](#installation)
3
4
  - [Configuration](#configuration)
4
5
  - [Running](#running)
5
6
  - [RSpec](#rspec)
6
7
  - [Remote recording](#remote-recording)
8
+ - [Ruby on Rails](#ruby-on-rails)
7
9
  - [Uploading AppMaps](#uploading-appmaps)
8
10
  - [Build status](#build-status)
9
11
 
10
12
  # About
11
13
 
12
- `appmap-ruby` is a Ruby Gem for recording and uploading
14
+ `appmap-ruby` is a Ruby Gem for recording
13
15
  [AppMaps](https://github.com/applandinc/appmap) of your code.
14
- AppMap is a data format which records code structure (modules, classes, and methods), code execution events
16
+ "AppMap" is a data format which records code structure (modules, classes, and methods), code execution events
15
17
  (function calls and returns), and code metadata (repo name, repo URL, commit
16
- SHA, etc). It's more granular than a performance profile, but it's less
18
+ SHA, labels, etc). It's more granular than a performance profile, but it's less
17
19
  granular than a full debug trace. It's designed to be optimal for understanding the design intent and behavior of code.
18
20
 
19
21
  There are several ways to record AppMaps of your Ruby program using the `appmap` gem:
20
22
 
21
- * Run your RSpec tests. An AppMap will be generated for each one.
22
- * Run your application server with AppMap remote recording enabled, and use the AppMap
23
+ * Run your RSpec tests with the environment variable `APPMAP=true`. An AppMap will be generated for each spec.
24
+ * Run your application server with AppMap remote recording enabled, and use the AppMap.
23
25
  browser extension to start, stop, and upload recordings.
26
+ * Run the command `appmap record <program>` to record the entire execution of a program.
24
27
 
25
- When you record AppMaps on the command line (for example, by running RSpec tests), you use the `appmap upload` command to
26
- upload them to the AppLand website. On the AppLand website, you'll be able to
28
+ Once you have recorded some AppMaps (for example, by running RSpec tests), you use the `appland upload` command
29
+ to upload them to the AppLand server. This command, and some others, is provided
30
+ by the [AppLand CLI](https://github.com/applandinc/appland-cli/releases), to
31
+ Then, on the [AppLand website](https://app.land), you can
27
32
  visualize the design of your code and share links with collaborators.
28
33
 
34
+ # Testing
35
+ Before running tests, configure `local.appmap` to point to your local `appmap-ruby` directory.
36
+ ```
37
+ $ bundle config local.appmap $(pwd)
38
+ ```
39
+
40
+ Run the tests via `rake`:
41
+ ```
42
+ $ bundle exec rake test
43
+ ```
44
+
29
45
  # Installation
30
46
 
31
47
  Add `gem 'appmap'` to your Gemfile just as you would any other dependency.
@@ -60,8 +76,6 @@ packages:
60
76
 
61
77
  * **name** Provides the project name (required)
62
78
  * **packages** A list of source code directories which should be instrumented.
63
- * **files** A list of individual files which should be instrumented. This is only used for files which are
64
- not part of the `packages` list.
65
79
 
66
80
  **packages**
67
81
 
@@ -69,9 +83,7 @@ Each entry in the `packages` list is a YAML object which has the following keys:
69
83
 
70
84
  * **path** The path to the source code directory. The path may be relative to the current working directory, or it may
71
85
  be an absolute path.
72
- * **name** A name for the code package. By default, the package name will be the name of the directory in which the code
73
- is located. In the example above, "controllers" or "models".
74
- * **excludes** A list of files and directories which will be ignored. By default, all modules, classes and public
86
+ * **exclude** A list of files and directories which will be ignored. By default, all modules, classes and public
75
87
  functions are inspected.
76
88
 
77
89
  # Running
@@ -129,6 +141,8 @@ If you include the `feature` and `feature_group` metadata, these attributes will
129
141
  }
130
142
  ```
131
143
 
144
+ If you don't explicitly declare `feature` and `feature_group`, then they will be inferred from the spec name and example descriptions.
145
+
132
146
  ## Remote recording
133
147
 
134
148
  To manually record ad-hoc AppMaps of your Ruby app, use AppMap remote recording.
@@ -159,17 +173,15 @@ $ bundle exec rails server
159
173
 
160
174
  6. Open the AppApp browser extension and push `Stop`. The recording will be transferred to the AppLand website and opened in your browser.
161
175
 
162
- # Uploading AppMaps
176
+ ## Ruby on Rails
163
177
 
164
- To upload an AppMap file to AppLand, run the `appmap upload` command. For example:
178
+ If your app uses Ruby on Rails, the AppMap Railtie will be automatically enabled. Set the Rails config flag `app.config.appmap.enabled = true` to record the entire execution of your Rails app.
165
179
 
166
- ```sh-session
167
- $ appmap upload tmp/appmap/rspec/Hello_app_says_hello_when_prompted.appmap.json
168
- Uploading "tmp/appmap/rspec/Hello_app_says_hello_when_prompted.appmap.json"
169
- Scenario Id: 4da4f267-bdea-48e8-bf67-f39463844230
170
- Batch Id: a116f1df-ee57-4bde-8eef-851af0f3d7bc
171
- ```
180
+ Note that using this method is kind of a blunt instrument. Recording RSpecs and using Remote Recording are usually better options.
181
+
182
+ # Uploading AppMaps
183
+
184
+ For instructions on uploading, see the documentation of the [AppLand CLI](https://github.com/applandinc/appland-cli).
172
185
 
173
186
  # Build status
174
187
  [![Build Status](https://travis-ci.org/applandinc/appmap-ruby.svg?branch=master)](https://travis-ci.org/applandinc/appmap-ruby)
175
-
data/Rakefile CHANGED
@@ -54,7 +54,7 @@ namespace :build do
54
54
  end
55
55
  end
56
56
  end
57
-
57
+
58
58
  namespace :fixtures do
59
59
  RUBY_VERSIONS.each do |ruby_version|
60
60
  namespace ruby_version do
@@ -69,7 +69,7 @@ namespace :build do
69
69
  end
70
70
  end
71
71
  end
72
-
72
+
73
73
  desc "Build all fixture images"
74
74
  task all: ["#{ruby_version}:all"]
75
75
  end
@@ -93,7 +93,7 @@ def run_specs(ruby_version, task_args)
93
93
  task.rspec_opts = args.to_a.join(' ')
94
94
  end
95
95
  end
96
-
96
+
97
97
  # Set up the environment, then execute the rspec task we
98
98
  # created above.
99
99
  ClimateControl.modify(RUBY_VERSION: ruby_version) do
@@ -30,11 +30,13 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency 'bundler', '~> 1.16'
31
31
  spec.add_development_dependency 'minitest', '~> 5.0'
32
32
  spec.add_development_dependency 'pry-byebug'
33
- spec.add_development_dependency 'rake', '~> 10.0'
33
+ spec.add_development_dependency 'rake', '>= 12.3.3'
34
34
  spec.add_development_dependency 'rdoc'
35
+ spec.add_development_dependency 'rubocop'
35
36
 
36
37
  # Testing
37
38
  spec.add_development_dependency 'climate_control'
39
+ spec.add_development_dependency 'diffy'
38
40
  spec.add_development_dependency 'launchy'
39
41
  spec.add_development_dependency 'rspec'
40
42
  spec.add_development_dependency 'selenium-webdriver'
data/exe/appmap CHANGED
@@ -42,17 +42,6 @@ module AppMap
42
42
  arg_name 'filename'
43
43
  flag %i[c config]
44
44
 
45
- desc 'Inspect code and generate a classmap file'
46
- command :inspect do |c|
47
- output_file_flag(c, default_value: default_appmap_file)
48
-
49
- c.action do
50
- require 'appmap/command/inspect'
51
- appmap = AppMap::Command::Inspect.new(@config).perform
52
- @output_file.write JSON.pretty_generate(appmap)
53
- end
54
- end
55
-
56
45
  desc 'Record the execution of a program and generate an AppMap.'
57
46
  arg_name 'program'
58
47
  command :record do |c|
@@ -76,10 +65,10 @@ module AppMap
76
65
  ARGV.shift
77
66
 
78
67
  require 'appmap/command/record'
79
- AppMap::Command::Record.new(@config, program).perform do |features, events|
80
- @output_file.write JSON.generate(version: AppMap::APPMAP_FORMAT_VERSION,
81
- classMap: features,
82
- metadata: AppMap::Command::Record.detect_metadata,
68
+ AppMap::Command::Record.new(@config, program).perform do |version, metadata, class_map, events|
69
+ @output_file.write JSON.generate(version: version,
70
+ metadata: metadata,
71
+ classMap: class_map,
83
72
  events: events)
84
73
  end
85
74
  end
@@ -136,62 +125,6 @@ module AppMap
136
125
  end
137
126
  end
138
127
 
139
- desc 'Upload a scenario file to AppLand.'
140
- arg_name 'filename'
141
- command :upload do |c|
142
- output_file_flag(c, default_value: '-')
143
-
144
- c.desc 'Whether to open the new scenario in the browser'
145
- c.default_value true
146
- c.switch [:open]
147
-
148
- c.desc 'AppLand website URL'
149
- c.default_value ENV['APPLAND_URL'] || 'https://appland-staging.herokuapp.com'
150
- c.flag :url
151
-
152
- # TODO: This will be replaced with proper login
153
- c.desc 'User id to own the scenario'
154
- c.default_value(ENV['APPLAND_USER'])
155
- c.flag :user
156
-
157
- c.desc 'Organization id to own the scenario'
158
- c.default_value(ENV['APPLAND_ORG'])
159
- c.flag :org
160
-
161
- c.action do |_, options, args|
162
- require 'appmap/command/upload'
163
-
164
- filenames = args
165
- help_now!("'filename' argument is required") if filenames.empty?
166
-
167
- url = options[:url]
168
- user = options[:user]
169
- org = options[:org]
170
-
171
- batch_id = nil
172
- uuids = filenames.map do |filename|
173
- appmap = JSON.parse(File.read(filename))
174
-
175
- warn "Uploading #{filename.inspect}"
176
- upload = AppMap::Command::Upload.new(@config, appmap, url, user, org)
177
- upload.batch_id = batch_id if batch_id
178
- upload.perform.tap do |response|
179
- batch_id ||= response.batch_id
180
- @output_file.puts "Scenario Id: #{response.scenario_uuid}"
181
- end.scenario_uuid
182
- end
183
- @output_file.puts "Batch Id: #{batch_id}"
184
-
185
- if options[:open] && STDIN.tty?
186
- if uuids.length == 1
187
- system "open #{url}/scenarios/#{uuids.first}"
188
- else
189
- system "open #{url}/scenario_batches/#{batch_id}"
190
- end
191
- end
192
- end
193
- end
194
-
195
128
  pre do |global, _, options, _|
196
129
  @config = interpret_config_option(global[:config])
197
130
  @output_file = interpret_output_file_option(options[:output])
@@ -203,8 +136,7 @@ module AppMap
203
136
  protected
204
137
 
205
138
  def interpret_config_option(fname)
206
- require 'appmap/config'
207
- AppMap::Config.load_from_file fname
139
+ AppMap.configure fname
208
140
  end
209
141
 
210
142
  def interpret_output_file_option(file_name)
@@ -13,12 +13,67 @@ module AppMap
13
13
  BATCH_HEADER_NAME = 'AppLand-Scenario-Batch'
14
14
 
15
15
  class << self
16
- # Simplified entry point to inspect code for features.
17
- def inspect(config)
18
- require 'appmap/inspect'
19
- features = config.source_locations.map(&AppMap::Inspect.method(:detect_features)).flatten.compact
20
- features = features.map(&:reparent)
21
- features.each(&:prune)
16
+ @config = nil
17
+ @config_file_path = nil
18
+
19
+ # configuration gets the AppMap configuration.
20
+ def configuration
21
+ raise "AppMap is not configured" unless @config
22
+
23
+ @config
24
+ end
25
+
26
+ # configure applies the configuration from a file. This method can only be performed once.
27
+ # Be sure and call it before +hook+ if you want non-default configuration.
28
+ #
29
+ # Default behavior is to configure from "appmap.yml".
30
+ def configure(config_file_path = 'appmap.yml')
31
+ if @config
32
+ return @config if @config_file_path == config_file_path
33
+
34
+ raise "AppMap is already configured from #{@config_file_path}, can't reconfigure from #{config_file_path}"
35
+ end
36
+
37
+ warn "Configuring AppMap from path #{config_file_path}"
38
+ require 'appmap/hook'
39
+ AppMap::Hook::Config.load_from_file(config_file_path).tap do |config|
40
+ @config = config
41
+ @config_file_path = config_file_path
42
+ end
43
+ end
44
+
45
+ # Activate the code hooks which record function calls as trace events.
46
+ # Call this function before the program code is loaded by the Ruby VM, otherwise
47
+ # the load events won't be seen and the hooks won't activate.
48
+ def hook(config = configure)
49
+ require 'appmap/hook'
50
+ AppMap::Hook.hook(config)
51
+ end
52
+
53
+ # Access the AppMap::Tracers, which can be used to start tracing, stop tracing, and record events.
54
+ def tracing
55
+ require 'appmap/trace'
56
+ @tracing ||= Trace::Tracers.new
57
+ end
58
+
59
+ # Record a block and return the array of events.
60
+ def record
61
+ tracer = tracing.trace
62
+ begin
63
+ yield
64
+ ensure
65
+ tracing.delete(tracer)
66
+ end
67
+
68
+ [].tap do |events|
69
+ events << tracer.next_event.to_h while tracer.event?
70
+ end
71
+ end
72
+
73
+ # Build a class map from a config and a list of Ruby methods.
74
+ def class_map(config, methods)
75
+ require 'appmap/class_map'
76
+ AppMap::ClassMap.build_from_methods(config, methods)
22
77
  end
23
78
  end
24
79
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AppMap
2
4
  module Algorithm
3
5
  # Prune a class map so that only functions, classes and packages which are referenced