appmap 0.50.0 → 0.52.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|