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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91abfbaf6b18062625413f1a4ba9a465325af82734a04ab875bb8b4092f3bc34
|
4
|
+
data.tar.gz: 9fb260bc1fb09cc1a6bc6771114b8306f596d1595bcaf1234dd346abe871d3b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4eb0fe09e7657fbb3541c17b047e2c0c24cb171201828b684353fd2de94fcca216f84b2776ce4a1f57fe1e721aaeb66c55fbea5fc627d9529f4bf687805a1079
|
7
|
+
data.tar.gz: 938da5ae0d846bc3e2c7f571ef836fe35f4d0fefebe5af9f5b5846b949c87c1cc1812881a973168c014cc789a0b6bb1ee9eb556d11406e846f99fdecd0eeb04a
|
data/.travis.yml
CHANGED
@@ -26,7 +26,9 @@ before_install:
|
|
26
26
|
if [ ! -z "$DOCKERHUB_PASSWORD" ] && [ ! -z "$DOCKERHUB_USERNAME" ]; then
|
27
27
|
echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin ;
|
28
28
|
fi
|
29
|
-
|
29
|
+
- |
|
30
|
+
nvm install --lts \
|
31
|
+
&& nvm use --lts
|
30
32
|
|
31
33
|
# GEM_ALTERNATIVE_NAME only needed for deployment
|
32
34
|
jobs:
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
+
# [0.52.0](https://github.com/applandinc/appmap-ruby/compare/v0.51.3...v0.52.0) (2021-06-22)
|
2
|
+
|
3
|
+
|
4
|
+
### Features
|
5
|
+
|
6
|
+
* Bundle NPM package @appland/cli with this gem ([945e28c](https://github.com/applandinc/appmap-ruby/commit/945e28c699fff6bd97ae51983816e97955c4ff36))
|
7
|
+
|
8
|
+
## [0.51.3](https://github.com/applandinc/appmap-ruby/compare/v0.51.2...v0.51.3) (2021-06-22)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Remove outdate lore, command, and algorithm code ([d899989](https://github.com/applandinc/appmap-ruby/commit/d8999896c611c16f51a092f5f7afb3d7203d7e72))
|
14
|
+
|
15
|
+
## [0.51.2](https://github.com/applandinc/appmap-ruby/compare/v0.51.1...v0.51.2) (2021-06-22)
|
16
|
+
|
17
|
+
|
18
|
+
### Bug Fixes
|
19
|
+
|
20
|
+
* Be less verbose when logging config messages ([fba2fd0](https://github.com/applandinc/appmap-ruby/commit/fba2fd01dbb7b1830194b49285654d6657d1c786))
|
21
|
+
* Method objects must support eql? and hash to ensure they are unique in a Set ([f4d5b11](https://github.com/applandinc/appmap-ruby/commit/f4d5b11db90aa50bdd1f768e039927833e83c30f))
|
22
|
+
* Require rails, then appmap/railtie ([07967a1](https://github.com/applandinc/appmap-ruby/commit/07967a14609891544a7dd874c648b7ef5a505f21))
|
23
|
+
* Use a hybrid strategy to auto-requiring appmap modules ([6fb09b8](https://github.com/applandinc/appmap-ruby/commit/6fb09b8c0bd55b1e29967d459ce1e2bd5b1ba9fe))
|
24
|
+
|
25
|
+
## [0.51.1](https://github.com/applandinc/appmap-ruby/compare/v0.51.0...v0.51.1) (2021-06-21)
|
26
|
+
|
27
|
+
|
28
|
+
### Bug Fixes
|
29
|
+
|
30
|
+
* Add missing require 'yaml' ([1187a02](https://github.com/applandinc/appmap-ruby/commit/1187a023243caaab8cd48de5cbbddefa361636ad))
|
31
|
+
|
32
|
+
# [0.51.0](https://github.com/applandinc/appmap-ruby/compare/v0.50.0...v0.51.0) (2021-06-21)
|
33
|
+
|
34
|
+
|
35
|
+
### Features
|
36
|
+
|
37
|
+
* Provide default appmap.yml settings ([7fa8159](https://github.com/applandinc/appmap-ruby/commit/7fa8159b5020e35f13379017b44906d671e62e64))
|
38
|
+
|
1
39
|
# [0.50.0](https://github.com/applandinc/appmap-ruby/compare/v0.49.0...v0.50.0) (2021-06-17)
|
2
40
|
|
3
41
|
|
data/Rakefile
CHANGED
@@ -16,6 +16,22 @@ end
|
|
16
16
|
|
17
17
|
namespace 'gem' do
|
18
18
|
require 'bundler/gem_tasks'
|
19
|
+
|
20
|
+
module Bundler
|
21
|
+
class GemHelper
|
22
|
+
alias default_build_gem build_gem
|
23
|
+
|
24
|
+
# A handy tip - find the location of any Rake task using `rake -W`.
|
25
|
+
# rake -W build
|
26
|
+
# ~/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/gem_helper.rb:39:in `install'
|
27
|
+
def build_gem
|
28
|
+
# Ensure that NPM packages are installed before building.
|
29
|
+
sh('yarn install --prod'.shellsplit)
|
30
|
+
|
31
|
+
default_build_gem
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
19
35
|
end
|
20
36
|
|
21
37
|
RUBY_VERSIONS=%w[2.5 2.6 2.7]
|
@@ -34,18 +50,19 @@ def run_cmd(*cmd)
|
|
34
50
|
raise 'Docker build failed'
|
35
51
|
end
|
36
52
|
end
|
37
|
-
|
53
|
+
|
38
54
|
def build_base_image(ruby_version)
|
39
55
|
run_cmd "docker build" \
|
40
56
|
" --build-arg RUBY_VERSION=#{ruby_version}" \
|
41
57
|
" --build-arg GEM_VERSION=#{GEM_VERSION}" \
|
42
58
|
" -t appmap:#{GEM_VERSION} -f Dockerfile.appmap ."
|
43
59
|
end
|
44
|
-
|
60
|
+
|
45
61
|
def build_app_image(app, ruby_version)
|
46
62
|
Dir.chdir "spec/fixtures/#{app}" do
|
47
|
-
|
48
|
-
|
63
|
+
env = {"RUBY_VERSION" => ruby_version, "GEM_VERSION" => GEM_VERSION}
|
64
|
+
run_cmd(env,
|
65
|
+
"docker-compose build" \
|
49
66
|
" --build-arg RUBY_VERSION=#{ruby_version}" \
|
50
67
|
" --build-arg GEM_VERSION=#{GEM_VERSION}" )
|
51
68
|
end
|
@@ -139,4 +156,3 @@ task spec: %i[spec:all]
|
|
139
156
|
task test: %i[spec:all minitest]
|
140
157
|
|
141
158
|
task default: :test
|
142
|
-
|
data/appmap.gemspec
CHANGED
@@ -4,8 +4,6 @@ lib = File.expand_path('lib', __dir__)
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require 'appmap/version'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
7
|
Gem::Specification.new do |spec|
|
10
8
|
# ability to parameterize gem name is added intentionally,
|
11
9
|
# to support the possibility of unofficial releases, e.g. during CI tests
|
@@ -22,19 +20,26 @@ Gem::Specification.new do |spec|
|
|
22
20
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
21
|
spec.files = `git ls-files --no-deleted`.split("
|
24
22
|
")
|
25
|
-
spec.
|
23
|
+
spec.bindir = 'exe'
|
24
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
25
|
|
26
|
+
strip_dir = ->(file) { file.index(Dir.pwd) == 0 ? file[Dir.pwd.length+1...file.length] : file }
|
27
|
+
Dir.glob(File.join(__dir__, 'node_modules/**/*')).map(&strip_dir).each do |filename|
|
28
|
+
next if File.directory?(filename) || filename.length > 100
|
29
|
+
spec.files << filename
|
30
|
+
end
|
31
|
+
|
32
|
+
spec.extensions << "ext/appmap/extconf.rb"
|
27
33
|
spec.require_paths = ['lib']
|
28
34
|
|
29
35
|
spec.add_dependency 'activesupport'
|
30
|
-
spec.add_dependency 'faraday'
|
31
36
|
spec.add_dependency 'gli'
|
32
37
|
spec.add_dependency 'method_source'
|
33
|
-
spec.add_dependency 'parser'
|
34
38
|
spec.add_dependency 'rack'
|
39
|
+
spec.add_dependency 'reverse_markdown'
|
35
40
|
|
36
41
|
spec.add_development_dependency 'bundler', '>= 1.16'
|
37
|
-
spec.add_development_dependency 'minitest', '
|
42
|
+
spec.add_development_dependency 'minitest', '= 5.14.4'
|
38
43
|
spec.add_development_dependency 'pry-byebug'
|
39
44
|
spec.add_development_dependency 'rake', '>= 12.3.3'
|
40
45
|
spec.add_development_dependency 'rdoc'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'gli'
|
5
|
+
|
6
|
+
require 'appmap'
|
7
|
+
|
8
|
+
class App
|
9
|
+
extend GLI::App
|
10
|
+
|
11
|
+
program_desc 'CLI tool to be used by code editor plugins for AppMap setup and configuration'
|
12
|
+
|
13
|
+
version AppMap::VERSION
|
14
|
+
|
15
|
+
subcommand_option_handling :normal
|
16
|
+
arguments :strict
|
17
|
+
preserve_argv true
|
18
|
+
|
19
|
+
desc 'AppMap configuration file name'
|
20
|
+
default_value ENV['APPMAP_CONFIG'] || AppMap::DEFAULT_CONFIG_FILE_PATH
|
21
|
+
arg_name 'filename'
|
22
|
+
flag %i[c config]
|
23
|
+
|
24
|
+
desc 'Creates base configuration file for the current project'
|
25
|
+
command :init do |c|
|
26
|
+
c.action do
|
27
|
+
require 'appmap/command/agent_setup/init'
|
28
|
+
AppMap::Command::AgentSetup::Init.new(@config_file).perform
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
pre do |global, _, _, _|
|
33
|
+
@config_file = global[:config]
|
34
|
+
@config = interpret_config_option(@config_file) if File.exist?(@config_file)
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
protected
|
40
|
+
|
41
|
+
def interpret_config_option(fname)
|
42
|
+
AppMap::Config.load_from_file fname
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
exit App.run(ARGV)
|
data/exe/appmap-inspect
ADDED
data/lib/appmap.rb
CHANGED
@@ -8,12 +8,12 @@ rescue NameError
|
|
8
8
|
end
|
9
9
|
|
10
10
|
require 'appmap/version'
|
11
|
+
require 'appmap/util'
|
11
12
|
require 'appmap/hook'
|
12
13
|
require 'appmap/config'
|
13
14
|
require 'appmap/trace'
|
14
15
|
require 'appmap/class_map'
|
15
16
|
require 'appmap/metadata'
|
16
|
-
require 'appmap/util'
|
17
17
|
require 'appmap/open'
|
18
18
|
|
19
19
|
# load extension
|
@@ -27,7 +27,7 @@ module AppMap
|
|
27
27
|
# Gets the configuration. If there is no configuration, the default
|
28
28
|
# configuration is initialized.
|
29
29
|
def configuration
|
30
|
-
@configuration ||=
|
30
|
+
@configuration ||= initialize_configuration
|
31
31
|
end
|
32
32
|
|
33
33
|
# Sets the configuration. This is only expected to happen once per
|
@@ -38,13 +38,20 @@ module AppMap
|
|
38
38
|
@configuration = config
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
def default_config_file_path
|
42
|
+
ENV['APPMAP_CONFIG_FILE'] || 'appmap.yml'
|
43
|
+
end
|
44
|
+
|
45
|
+
# Configures AppMap for recording. Default behavior is to configure from
|
46
|
+
# APPMAP_CONFIG_FILE, or 'appmap.yml'. If no config file is available, a
|
47
|
+
# configuration will be automatically generated and used - and the user is prompted
|
48
|
+
# to create the config file.
|
49
|
+
#
|
42
50
|
# This method also activates the code hooks which record function calls as trace events.
|
43
51
|
# Call this function before the program code is loaded by the Ruby VM, otherwise
|
44
52
|
# the load events won't be seen and the hooks won't activate.
|
45
|
-
def
|
46
|
-
|
47
|
-
warn "Configuring AppMap from path #{config_file_path}"
|
53
|
+
def initialize_configuration(config_file_path = default_config_file_path)
|
54
|
+
Util.startup_message "Configuring AppMap from path #{config_file_path}"
|
48
55
|
Config.load_from_file(config_file_path).tap do |configuration|
|
49
56
|
self.configuration = configuration
|
50
57
|
Hook.new(configuration).enable
|
@@ -105,17 +112,49 @@ module AppMap
|
|
105
112
|
end
|
106
113
|
end
|
107
114
|
|
108
|
-
|
109
|
-
|
110
|
-
end
|
115
|
+
lambda do
|
116
|
+
Initializer = Struct.new(:class_name, :module_name, :gem_module_name)
|
111
117
|
|
112
|
-
|
113
|
-
|
114
|
-
|
118
|
+
INITIALIZERS = {
|
119
|
+
'Rails::Railtie' => Initializer.new('AppMap::Railtie', 'appmap/railtie', 'railtie'),
|
120
|
+
'RSpec' => Initializer.new('AppMap::RSpec', 'appmap/rspec', 'rspec-core'),
|
121
|
+
'Minitest::Unit::TestCase' => Initializer.new('AppMap::Minitest', 'appmap/minitest', 'minitest')
|
122
|
+
}
|
115
123
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
124
|
+
TracePoint.new(:class) do |tp|
|
125
|
+
cls_name = tp.self.name
|
126
|
+
initializers = INITIALIZERS.delete(cls_name)
|
127
|
+
if initializers
|
128
|
+
initializers = [ initializers ] unless initializers.is_a?(Array)
|
129
|
+
next if Object.const_defined?(initializers.first.class_name)
|
130
|
+
|
131
|
+
gem_module_name = initializers.first.gem_module_name
|
132
|
+
|
133
|
+
AppMap::Util.startup_message AppMap::Util.color(<<~LOAD_MSG, :magenta)
|
134
|
+
When 'appmap' was loaded, '#{gem_module_name}' had not been loaded yet. Now '#{gem_module_name}' has
|
135
|
+
just been loaded, so the following AppMap modules will be automatically required:
|
136
|
+
|
137
|
+
#{initializers.map(&:module_name).join("\n")}
|
138
|
+
|
139
|
+
To suppress this message, ensure '#{gem_module_name}' appears before 'appmap' in your Gemfile.
|
140
|
+
LOAD_MSG
|
141
|
+
initializers.each do |init|
|
142
|
+
require init.module_name
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end.enable
|
146
|
+
|
147
|
+
if defined?(::Rails::Railtie)
|
148
|
+
require 'appmap/railtie'
|
149
|
+
end
|
150
|
+
|
151
|
+
if defined?(::RSpec)
|
152
|
+
require 'appmap/rspec'
|
153
|
+
end
|
154
|
+
|
155
|
+
if defined?(::Minitest)
|
156
|
+
require 'appmap/minitest'
|
157
|
+
end
|
158
|
+
end.call
|
120
159
|
|
121
|
-
AppMap.
|
160
|
+
AppMap.initialize_configuration if ENV['APPMAP'] == 'true'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'appmap/service/guesser'
|
5
|
+
require 'appmap/util'
|
6
|
+
|
7
|
+
module AppMap
|
8
|
+
module Command
|
9
|
+
module AgentSetup
|
10
|
+
InitStruct = Struct.new(:config_file)
|
11
|
+
|
12
|
+
class Init < InitStruct
|
13
|
+
def perform
|
14
|
+
if File.exist?(config_file)
|
15
|
+
puts AppMap::Util.color(%(The AppMap config file #{config_file} already exists.), :magenta)
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
ensure_directory_exists
|
20
|
+
|
21
|
+
config = {
|
22
|
+
'name' => Service::Guesser.guess_name,
|
23
|
+
'packages' => Service::Guesser.guess_paths.map { |path| { 'path' => path } }
|
24
|
+
}
|
25
|
+
content = YAML.dump(config).gsub("---\n", '')
|
26
|
+
|
27
|
+
File.write(config_file, content)
|
28
|
+
puts AppMap::Util.color(
|
29
|
+
%(The following AppMap config file #{config_file} has been created:),
|
30
|
+
:green
|
31
|
+
)
|
32
|
+
puts content
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def ensure_directory_exists
|
38
|
+
dirname = File.dirname(config_file)
|
39
|
+
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'appmap/version'
|
2
|
+
require 'appmap/config'
|
3
|
+
require 'appmap/node_cli'
|
4
|
+
|
5
|
+
module AppMap
|
6
|
+
module Command
|
7
|
+
class Inspect < AppMap::NodeCLI
|
8
|
+
class << self
|
9
|
+
def run
|
10
|
+
command = Inspect.new(verbose: ENV['DEBUG'] == 'true')
|
11
|
+
command.inspect(ARGV)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect(arguments)
|
16
|
+
detect_nodejs
|
17
|
+
index_appmaps
|
18
|
+
|
19
|
+
arguments.unshift 'inspect'
|
20
|
+
arguments.unshift APPMAP_JS
|
21
|
+
arguments.unshift 'node'
|
22
|
+
|
23
|
+
exec(*arguments)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module AppMap
|
2
|
+
# Raised when a system / shell command fails.
|
3
|
+
class CommandError < StandardError
|
4
|
+
attr_reader :command, :msg
|
5
|
+
|
6
|
+
def initialize(command, msg = nil)
|
7
|
+
super [ "Command failed: #{command}", msg ].compact.join('; ')
|
8
|
+
|
9
|
+
@command = command
|
10
|
+
@msg = msg
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/appmap/config.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'yaml'
|
4
|
+
require 'appmap/util'
|
3
5
|
require 'appmap/handler/net_http'
|
4
6
|
require 'appmap/handler/rails/template'
|
7
|
+
require 'appmap/service/guesser'
|
5
8
|
|
6
9
|
module AppMap
|
7
10
|
class Config
|
@@ -52,7 +55,7 @@ module AppMap
|
|
52
55
|
if path
|
53
56
|
Package.new(path, gem, package_name, exclude, labels, shallow)
|
54
57
|
else
|
55
|
-
|
58
|
+
AppMap::Util.startup_message "#{gem} is not available in the bundle"
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
@@ -223,10 +226,14 @@ module AppMap
|
|
223
226
|
'JSON::Ext::Generator::State' => TargetMethods.new(:generate, Package.build_from_path('json', package_name: 'json', labels: %w[format.json.generate])),
|
224
227
|
}.freeze
|
225
228
|
|
226
|
-
attr_reader :name, :packages, :exclude, :hooked_methods, :builtin_hooks
|
229
|
+
attr_reader :name, :appmap_dir, :packages, :exclude, :hooked_methods, :builtin_hooks
|
227
230
|
|
228
|
-
def initialize(name,
|
231
|
+
def initialize(name,
|
232
|
+
packages: [],
|
233
|
+
exclude: [],
|
234
|
+
functions: [])
|
229
235
|
@name = name
|
236
|
+
@appmap_dir = AppMap::DEFAULT_APPMAP_DIR
|
230
237
|
@packages = packages
|
231
238
|
@hook_paths = Set.new(packages.map(&:path))
|
232
239
|
@exclude = exclude
|
@@ -253,38 +260,98 @@ module AppMap
|
|
253
260
|
class << self
|
254
261
|
# Loads configuration data from a file, specified by the file name.
|
255
262
|
def load_from_file(config_file_name)
|
256
|
-
|
257
|
-
|
263
|
+
logo = lambda do
|
264
|
+
Util.color(<<~LOGO, :magenta)
|
265
|
+
___ __ ___
|
266
|
+
/ _ | ___ ___ / |/ /__ ____
|
267
|
+
/ __ |/ _ \\/ _ \\/ /|_/ / _ `/ _ \\
|
268
|
+
/_/ |_/ .__/ .__/_/ /_/\\_,_/ .__/
|
269
|
+
/_/ /_/ /_/
|
270
|
+
LOGO
|
271
|
+
end
|
272
|
+
|
273
|
+
config_present = true if File.exists?(config_file_name)
|
274
|
+
|
275
|
+
config_data = if config_present
|
276
|
+
YAML.safe_load(::File.read(config_file_name))
|
277
|
+
else
|
278
|
+
warn logo.()
|
279
|
+
warn ''
|
280
|
+
warn Util.color(%Q|NOTICE: The AppMap config file #{config_file_name} was not found!|, :magenta, bold: true)
|
281
|
+
warn ''
|
282
|
+
warn Util.color(<<~MISSING_FILE_MSG, :magenta)
|
283
|
+
AppMap uses this file to customize its behavior. For example, you can use
|
284
|
+
the 'packages' setting to indicate which local file paths and dependency
|
285
|
+
gems you want to include in the AppMap. Since you haven't provided specific
|
286
|
+
settings, the appmap gem will try and guess some reasonable defaults.
|
287
|
+
To suppress this message, create the file:
|
288
|
+
|
289
|
+
#{Pathname.new(config_file_name).expand_path}
|
290
|
+
|
291
|
+
Here are the default settings that will be used in the meantime. You can
|
292
|
+
copy and paste this example to start your appmap.yml.
|
293
|
+
MISSING_FILE_MSG
|
294
|
+
{}
|
295
|
+
end
|
296
|
+
load(config_data).tap do |config|
|
297
|
+
config_yaml = {
|
298
|
+
'name' => config.name,
|
299
|
+
'packages' => config.packages.select{|p| p.path}.map do |pkg|
|
300
|
+
{ 'path' => pkg.path }
|
301
|
+
end,
|
302
|
+
'exclude' => []
|
303
|
+
}.compact
|
304
|
+
unless config_present
|
305
|
+
warn Util.color(YAML.dump(config_yaml), :magenta)
|
306
|
+
warn logo.()
|
307
|
+
end
|
308
|
+
end
|
258
309
|
end
|
259
310
|
|
260
311
|
# Loads configuration from a Hash.
|
261
312
|
def load(config_data)
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
313
|
+
name = config_data['name'] || Service::Guesser.guess_name
|
314
|
+
config_params = {
|
315
|
+
exclude: config_data['exclude']
|
316
|
+
}.compact
|
317
|
+
|
318
|
+
if config_data['functions']
|
319
|
+
config_params[:functions] = config_data['functions'].map do |function_data|
|
320
|
+
package = function_data['package']
|
321
|
+
cls = function_data['class']
|
322
|
+
functions = function_data['function'] || function_data['functions']
|
323
|
+
raise %q(AppMap config 'function' element should specify 'package', 'class' and 'function' or 'functions') unless package && cls && functions
|
324
|
+
|
325
|
+
functions = Array(functions).map(&:to_sym)
|
326
|
+
labels = function_data['label'] || function_data['labels']
|
327
|
+
labels = Array(labels).map(&:to_s) if labels
|
328
|
+
Function.new(package, cls, labels, functions)
|
329
|
+
end
|
271
330
|
end
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
331
|
+
|
332
|
+
config_params[:packages] = \
|
333
|
+
if config_data['packages']
|
334
|
+
config_data['packages'].map do |package|
|
335
|
+
gem = package['gem']
|
336
|
+
path = package['path']
|
337
|
+
raise %q(AppMap config 'package' element should specify 'gem' or 'path', not both) if gem && path
|
338
|
+
|
339
|
+
if gem
|
340
|
+
shallow = package['shallow']
|
341
|
+
# shallow is true by default for gems
|
342
|
+
shallow = true if shallow.nil?
|
343
|
+
Package.build_from_gem(gem, exclude: package['exclude'] || [], shallow: shallow)
|
344
|
+
else
|
345
|
+
Package.build_from_path(path, exclude: package['exclude'] || [], shallow: package['shallow'])
|
346
|
+
end
|
347
|
+
end.compact
|
282
348
|
else
|
283
|
-
|
349
|
+
Array(Service::Guesser.guess_paths).map do |path|
|
350
|
+
Package.build_from_path(path)
|
351
|
+
end
|
284
352
|
end
|
285
|
-
|
286
|
-
|
287
|
-
Config.new config_data['name'], packages, exclude: exclude, functions: functions
|
353
|
+
|
354
|
+
Config.new name, config_params
|
288
355
|
end
|
289
356
|
end
|
290
357
|
|
@@ -294,7 +361,7 @@ module AppMap
|
|
294
361
|
packages: packages.map(&:to_h),
|
295
362
|
functions: @functions.map(&:to_h),
|
296
363
|
exclude: exclude
|
297
|
-
}
|
364
|
+
}.compact
|
298
365
|
end
|
299
366
|
|
300
367
|
# Determines if methods defined in a file path should possibly be hooked.
|