appmap 0.50.0 → 0.52.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 +4 -4
- data/.travis.yml +3 -1
- data/CHANGELOG.md +38 -0
- data/Rakefile +21 -5
- data/appmap.gemspec +11 -6
- data/exe/appmap-agent-setup +47 -0
- data/exe/appmap-inspect +7 -0
- data/lib/appmap.rb +56 -17
- data/lib/appmap/command/agent_setup/init.rb +44 -0
- data/lib/appmap/command/inspect.rb +27 -0
- data/lib/appmap/command_error.rb +13 -0
- data/lib/appmap/config.rb +96 -29
- data/lib/appmap/handler/rails/template.rb +19 -5
- data/lib/appmap/node_cli.rb +59 -0
- data/lib/appmap/service/guesser.rb +26 -0
- data/lib/appmap/trace.rb +4 -2
- data/lib/appmap/util.rb +52 -2
- data/lib/appmap/version.rb +4 -1
- data/package.json +6 -7
- data/spec/config_spec.rb +21 -0
- data/spec/fixtures/rails5_users_app/docker-compose.yml +1 -1
- data/spec/fixtures/rails6_users_app/Dockerfile +9 -0
- data/spec/fixtures/rails6_users_app/docker-compose.yml +1 -1
- data/spec/hook_spec.rb +2 -2
- data/spec/{abstract_controller_base_spec.rb → rails_recording_spec.rb} +39 -19
- data/spec/rails_spec_helper.rb +22 -0
- data/spec/record_net_http_spec.rb +1 -1
- data/test/agent_setup_cli_test.rb +37 -0
- data/test/fixtures/gem_test/Gemfile +1 -0
- data/test/inspect_cli_test.rb +12 -0
- data/yarn.lock +477 -0
- metadata +23 -47
- data/lib/appmap/algorithm/prune_class_map.rb +0 -67
- data/lib/appmap/algorithm/stats.rb +0 -91
- data/lib/appmap/command/record.rb +0 -38
- data/lib/appmap/command/stats.rb +0 -14
- data/lore/pages/2019-05-21-install-and-record/index.pug +0 -51
- data/lore/pages/2019-05-21-install-and-record/install_example_appmap.png +0 -0
- data/lore/pages/2019-05-21-install-and-record/metadata.yml +0 -5
- data/lore/pages/layout.pug +0 -66
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css +0 -1912
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css +0 -7
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css +0 -331
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css +0 -8
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.css +0 -9030
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css +0 -7
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css.map +0 -1
- data/lore/public/stylesheets/style.css +0 -8
- data/package-lock.json +0 -1064
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.
|
4
|
+
version: 0.52.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gilpin
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: faraday
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: gli
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,7 +53,7 @@ dependencies:
|
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
56
|
+
name: rack
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - ">="
|
@@ -81,7 +67,7 @@ dependencies:
|
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: reverse_markdown
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - ">="
|
@@ -112,16 +98,16 @@ dependencies:
|
|
112
98
|
name: minitest
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - '='
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
103
|
+
version: 5.14.4
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
|
-
- -
|
108
|
+
- - '='
|
123
109
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
110
|
+
version: 5.14.4
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
112
|
name: pry-byebug
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -307,7 +293,9 @@ dependencies:
|
|
307
293
|
description:
|
308
294
|
email:
|
309
295
|
- kgilpin@gmail.com
|
310
|
-
executables:
|
296
|
+
executables:
|
297
|
+
- appmap-agent-setup
|
298
|
+
- appmap-inspect
|
311
299
|
extensions:
|
312
300
|
- ext/appmap/extconf.rb
|
313
301
|
extra_rdoc_files: []
|
@@ -335,14 +323,15 @@ files:
|
|
335
323
|
- examples/mock_webapp/lib/mock_webapp/controller.rb
|
336
324
|
- examples/mock_webapp/lib/mock_webapp/request.rb
|
337
325
|
- examples/mock_webapp/lib/mock_webapp/user.rb
|
326
|
+
- exe/appmap-agent-setup
|
327
|
+
- exe/appmap-inspect
|
338
328
|
- ext/appmap/appmap.c
|
339
329
|
- ext/appmap/extconf.rb
|
340
330
|
- lib/appmap.rb
|
341
|
-
- lib/appmap/algorithm/prune_class_map.rb
|
342
|
-
- lib/appmap/algorithm/stats.rb
|
343
331
|
- lib/appmap/class_map.rb
|
344
|
-
- lib/appmap/command/
|
345
|
-
- lib/appmap/command/
|
332
|
+
- lib/appmap/command/agent_setup/init.rb
|
333
|
+
- lib/appmap/command/inspect.rb
|
334
|
+
- lib/appmap/command_error.rb
|
346
335
|
- lib/appmap/config.rb
|
347
336
|
- lib/appmap/cucumber.rb
|
348
337
|
- lib/appmap/event.rb
|
@@ -356,34 +345,17 @@ files:
|
|
356
345
|
- lib/appmap/metadata.rb
|
357
346
|
- lib/appmap/middleware/remote_recording.rb
|
358
347
|
- lib/appmap/minitest.rb
|
348
|
+
- lib/appmap/node_cli.rb
|
359
349
|
- lib/appmap/open.rb
|
360
350
|
- lib/appmap/railtie.rb
|
361
351
|
- lib/appmap/record.rb
|
362
352
|
- lib/appmap/rspec.rb
|
353
|
+
- lib/appmap/service/guesser.rb
|
363
354
|
- lib/appmap/trace.rb
|
364
355
|
- lib/appmap/util.rb
|
365
356
|
- lib/appmap/version.rb
|
366
|
-
- lore/pages/2019-05-21-install-and-record/index.pug
|
367
|
-
- lore/pages/2019-05-21-install-and-record/install_example_appmap.png
|
368
|
-
- lore/pages/2019-05-21-install-and-record/metadata.yml
|
369
|
-
- lore/pages/layout.pug
|
370
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css
|
371
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css.map
|
372
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css
|
373
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css.map
|
374
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css
|
375
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css.map
|
376
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css
|
377
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css.map
|
378
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap.css
|
379
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap.css.map
|
380
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css
|
381
|
-
- lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css.map
|
382
|
-
- lore/public/stylesheets/style.css
|
383
|
-
- package-lock.json
|
384
357
|
- package.json
|
385
358
|
- release.sh
|
386
|
-
- spec/abstract_controller_base_spec.rb
|
387
359
|
- spec/class_map_spec.rb
|
388
360
|
- spec/config_spec.rb
|
389
361
|
- spec/fixtures/hook/attr_accessor.rb
|
@@ -548,6 +520,7 @@ files:
|
|
548
520
|
- spec/fixtures/rails6_users_app/users_app/.gitignore
|
549
521
|
- spec/hook_spec.rb
|
550
522
|
- spec/open_spec.rb
|
523
|
+
- spec/rails_recording_spec.rb
|
551
524
|
- spec/rails_spec_helper.rb
|
552
525
|
- spec/railtie_spec.rb
|
553
526
|
- spec/record_net_http_spec.rb
|
@@ -555,6 +528,7 @@ files:
|
|
555
528
|
- spec/remote_recording_spec.rb
|
556
529
|
- spec/spec_helper.rb
|
557
530
|
- spec/util_spec.rb
|
531
|
+
- test/agent_setup_cli_test.rb
|
558
532
|
- test/bundle_vendor_test.rb
|
559
533
|
- test/cucumber_test.rb
|
560
534
|
- test/expectations/openssl_test_key_sign1.json
|
@@ -599,11 +573,13 @@ files:
|
|
599
573
|
- test/fixtures/rspec_recorder/spec/labeled_hello_spec.rb
|
600
574
|
- test/fixtures/rspec_recorder/spec/plain_hello_spec.rb
|
601
575
|
- test/gem_test.rb
|
576
|
+
- test/inspect_cli_test.rb
|
602
577
|
- test/minitest_test.rb
|
603
578
|
- test/openssl_test.rb
|
604
579
|
- test/record_process_test.rb
|
605
580
|
- test/rspec_test.rb
|
606
581
|
- test/test_helper.rb
|
582
|
+
- yarn.lock
|
607
583
|
homepage: https://github.com/applandinc/appmap-ruby
|
608
584
|
licenses:
|
609
585
|
- MIT
|
@@ -1,67 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AppMap
|
4
|
-
module Algorithm
|
5
|
-
# Prune a class map so that only functions, classes and packages which are referenced
|
6
|
-
# by some event are retained.
|
7
|
-
class PruneClassMap
|
8
|
-
attr_reader :class_map
|
9
|
-
# Set this attribute to a function which will log algorithm events.
|
10
|
-
attr_writer :logger
|
11
|
-
attr_accessor :events
|
12
|
-
|
13
|
-
# Construct the algorithm, with a class map that will be pruned in place.
|
14
|
-
def initialize(class_map)
|
15
|
-
@class_map = class_map
|
16
|
-
@logger = ->(msg) {}
|
17
|
-
end
|
18
|
-
|
19
|
-
def perform
|
20
|
-
# This proc counts the number of objects in the class map whose type is 'k'
|
21
|
-
count = proc do |k, e|
|
22
|
-
n = 0
|
23
|
-
n += 1 if e['type'] == k
|
24
|
-
n += (e['children'] || []).map { |child| count.call(k, child) }.reduce(0, :+)
|
25
|
-
n
|
26
|
-
end
|
27
|
-
|
28
|
-
@logger.call "Full classMap contains #{class_map.map { |m| count.call('class', m) }.reduce(0, :+)} classes"
|
29
|
-
|
30
|
-
# Prune all the classes which fail a test.
|
31
|
-
reject = proc do |list, test|
|
32
|
-
list.tap do |_|
|
33
|
-
list.each do |item|
|
34
|
-
children = item['children']
|
35
|
-
next unless children
|
36
|
-
|
37
|
-
reject.call(children, test)
|
38
|
-
end
|
39
|
-
list.reject!(&test)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
if events
|
44
|
-
locations = \
|
45
|
-
Set.new(events.select { |e| e['event'] == 'call' }
|
46
|
-
.map { |e| [ e['path'], e['lineno'] ].join(':') })
|
47
|
-
|
48
|
-
# Prune all functions which aren't called
|
49
|
-
reject.call class_map,
|
50
|
-
->(e) { e['type'] == 'function' && !locations.member?(e['location']) }
|
51
|
-
end
|
52
|
-
|
53
|
-
# Prune all empty classes
|
54
|
-
reject.call class_map,
|
55
|
-
->(e) { e['type'] == 'class' && (e['children'] || []).empty? }
|
56
|
-
|
57
|
-
# Prune all empty packages
|
58
|
-
reject.call class_map,
|
59
|
-
->(e) { e['type'] == 'package' && (e['children'] || []).empty? }
|
60
|
-
|
61
|
-
@logger.call "Pruned classMap contains #{class_map.map { |m| count.call('class', m) }.reduce(0, :+)} classes"
|
62
|
-
|
63
|
-
class_map
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AppMap
|
4
|
-
module Algorithm
|
5
|
-
StatsStruct = Struct.new(:appmap)
|
6
|
-
|
7
|
-
# Compute AppMap statistics.
|
8
|
-
class Stats < StatsStruct
|
9
|
-
Result = Struct.new(:class_frequency, :method_frequency) do
|
10
|
-
def merge!(other)
|
11
|
-
merge = lambda do |freq, other_freq|
|
12
|
-
freq_by_name = freq.inject({}) do |table, entry|
|
13
|
-
table.tap do
|
14
|
-
table[entry.name] = entry
|
15
|
-
end
|
16
|
-
end
|
17
|
-
other_freq.each do |other_entry|
|
18
|
-
entry = freq_by_name[other_entry.name]
|
19
|
-
if entry
|
20
|
-
entry.count += other_entry.count
|
21
|
-
else
|
22
|
-
freq << other_entry
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
merge.call(class_frequency, other.class_frequency)
|
27
|
-
merge.call(method_frequency, other.method_frequency)
|
28
|
-
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
def sort!
|
33
|
-
comparator = ->(a,b) { b.count <=> a.count }
|
34
|
-
class_frequency.sort!(&comparator)
|
35
|
-
method_frequency.sort!(&comparator)
|
36
|
-
|
37
|
-
self
|
38
|
-
end
|
39
|
-
|
40
|
-
def limit!(limit)
|
41
|
-
self.class_frequency = class_frequency[0...limit]
|
42
|
-
self.method_frequency = method_frequency[0...limit]
|
43
|
-
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
47
|
-
def as_text
|
48
|
-
lines = [
|
49
|
-
"Class frequency:",
|
50
|
-
"----------------",
|
51
|
-
] + class_frequency.map(&:to_a).map(&:reverse).map { |line | line.join("\t") } + [
|
52
|
-
"",
|
53
|
-
"Method frequency:",
|
54
|
-
"----------------",
|
55
|
-
] + method_frequency.map(&:to_a).map(&:reverse).map { |line | line.join("\t") }
|
56
|
-
lines.join("\n")
|
57
|
-
end
|
58
|
-
end
|
59
|
-
Frequency = Struct.new(:name, :count)
|
60
|
-
|
61
|
-
def perform(limit: nil)
|
62
|
-
events = appmap['events'] || []
|
63
|
-
frequency_calc = lambda do |key_func|
|
64
|
-
events_by_key = events.inject(Hash.new(0)) do |memo, event|
|
65
|
-
key = key_func.call(event)
|
66
|
-
memo.tap do
|
67
|
-
memo[key] += 1 if key
|
68
|
-
end
|
69
|
-
end
|
70
|
-
events_by_key.map do |key, count|
|
71
|
-
Frequency.new(key, count)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
class_name_func = ->(event) { event['defined_class'] }
|
76
|
-
full_name_func = lambda do |event|
|
77
|
-
call = event['event'] == 'call'
|
78
|
-
class_name = event['defined_class']
|
79
|
-
static = event['static']
|
80
|
-
function_name = event['method_id']
|
81
|
-
[ class_name, static ? '.' : '#', function_name ].join if call && class_name && !static.nil? && function_name
|
82
|
-
end
|
83
|
-
|
84
|
-
class_frequency = frequency_calc.call(class_name_func)
|
85
|
-
method_frequency = frequency_calc.call(full_name_func)
|
86
|
-
|
87
|
-
Result.new(class_frequency, method_frequency)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AppMap
|
4
|
-
module Command
|
5
|
-
RecordStruct = Struct.new(:config, :program)
|
6
|
-
|
7
|
-
class Record < RecordStruct
|
8
|
-
def perform(&block)
|
9
|
-
tracer = AppMap.tracing.trace
|
10
|
-
|
11
|
-
events = []
|
12
|
-
quit = false
|
13
|
-
event_thread = Thread.new do
|
14
|
-
while tracer.event? || !quit
|
15
|
-
event = tracer.next_event
|
16
|
-
if event
|
17
|
-
events << event.to_h
|
18
|
-
else
|
19
|
-
sleep 0.0001
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
event_thread.abort_on_exception = true
|
24
|
-
|
25
|
-
at_exit do
|
26
|
-
quit = true
|
27
|
-
event_thread.join
|
28
|
-
yield AppMap::APPMAP_FORMAT_VERSION,
|
29
|
-
AppMap.detect_metadata,
|
30
|
-
AppMap.class_map(tracer.event_methods),
|
31
|
-
events
|
32
|
-
end
|
33
|
-
|
34
|
-
load program if program
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
data/lib/appmap/command/stats.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AppMap
|
4
|
-
module Command
|
5
|
-
StatsStruct = Struct.new(:appmap)
|
6
|
-
|
7
|
-
class Stats < StatsStruct
|
8
|
-
def perform(limit: nil)
|
9
|
-
require 'appmap/algorithm/stats'
|
10
|
-
AppMap::Algorithm::Stats.new(appmap).perform(limit: limit)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
extends ../layout
|
2
|
-
|
3
|
-
block objective
|
4
|
-
div.
|
5
|
-
Installation of the AppMap client for Ruby is a key step in the user adoption flow.
|
6
|
-
Let's create an example program which installs the #[code appmap] Ruby gem and runs it to record a
|
7
|
-
scenario of a sample app.
|
8
|
-
|
9
|
-
block approach
|
10
|
-
:markdown-it
|
11
|
-
The [examples](https://github.com/applandinc/appmap-ruby/blob/master/examples/) folder in this project contains a sample project called `mock_webapp`, which
|
12
|
-
performs the following:
|
13
|
-
|
14
|
-
* Requests a `User` object by id ("alice").
|
15
|
-
* The request is handled by a `Controller`.
|
16
|
-
* The `Controller` looks up the id in a `User` model.
|
17
|
-
* The `User` model looks up the id and returns a `User` object, or raises an error.
|
18
|
-
* The `Controller` renders the response as a Hash and returns it to the client.
|
19
|
-
|
20
|
-
A test program called `install.rb` installs the `appmap` Ruby gem and then records the `mock_webapp`.
|
21
|
-
To create an appmap of `install.rb`:
|
22
|
-
|
23
|
-
```
|
24
|
-
bundle exec exe/record examples/install.rb
|
25
|
-
```
|
26
|
-
|
27
|
-
To upload the AppMap to AppLand:
|
28
|
-
|
29
|
-
```
|
30
|
-
bundle exec exe/upload appmap.json
|
31
|
-
```
|
32
|
-
|
33
|
-
block results
|
34
|
-
:markdown-it
|
35
|
-
## AppMap of `install.rb`
|
36
|
-
|
37
|
-
[](https://appland-staging.herokuapp.com/scenarios/ba2fc385-a96d-42bf-9ef8-cdbdab8a475d)
|
38
|
-
|
39
|
-
button(onclick="document.querySelector('#show-test-program').style.display = 'block';") Show test program code
|
40
|
-
div#show-test-program(style='display: none;')
|
41
|
-
pre
|
42
|
-
include ../../../examples/install.rb
|
43
|
-
|
44
|
-
block next_steps
|
45
|
-
:markdown-it
|
46
|
-
|
47
|
-
A related feature is the AppLand server receiving the scenario file and displaying it.
|
48
|
-
|
49
|
-
Here is an [AppMap of the server receiving a scenario file](https://appland-staging.herokuapp.com/scenarios/beb49bc7-b2ca-49b6-bac3-5d2eec2df062).
|
50
|
-
|
51
|
-
|
Binary file
|