appmap 0.51.1 → 0.53.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -1
  3. data/CHANGELOG.md +38 -0
  4. data/Rakefile +21 -5
  5. data/appmap.gemspec +11 -7
  6. data/exe/appmap-agent-init +19 -0
  7. data/exe/appmap-inspect +7 -0
  8. data/lib/appmap.rb +44 -12
  9. data/lib/appmap/command/agent_setup/init.rb +44 -0
  10. data/lib/appmap/command/inspect.rb +27 -0
  11. data/lib/appmap/command_error.rb +13 -0
  12. data/lib/appmap/config.rb +6 -24
  13. data/lib/appmap/handler/rails/template.rb +19 -5
  14. data/lib/appmap/node_cli.rb +59 -0
  15. data/lib/appmap/service/guesser.rb +19 -0
  16. data/lib/appmap/trace.rb +4 -2
  17. data/lib/appmap/util.rb +31 -2
  18. data/lib/appmap/version.rb +2 -1
  19. data/package.json +6 -7
  20. data/spec/fixtures/rails5_users_app/docker-compose.yml +1 -1
  21. data/spec/fixtures/rails6_users_app/Dockerfile +9 -0
  22. data/spec/fixtures/rails6_users_app/docker-compose.yml +1 -1
  23. data/spec/{abstract_controller_base_spec.rb → rails_recording_spec.rb} +2 -21
  24. data/spec/rails_spec_helper.rb +22 -0
  25. data/test/agent_setup_init_test.rb +37 -0
  26. data/test/fixtures/gem_test/Gemfile +1 -0
  27. data/test/inspect_cli_test.rb +12 -0
  28. data/yarn.lock +477 -0
  29. metadata +23 -61
  30. data/lib/appmap/algorithm/prune_class_map.rb +0 -67
  31. data/lib/appmap/algorithm/stats.rb +0 -91
  32. data/lib/appmap/command/record.rb +0 -38
  33. data/lib/appmap/command/stats.rb +0 -14
  34. data/lore/pages/2019-05-21-install-and-record/index.pug +0 -51
  35. data/lore/pages/2019-05-21-install-and-record/install_example_appmap.png +0 -0
  36. data/lore/pages/2019-05-21-install-and-record/metadata.yml +0 -5
  37. data/lore/pages/layout.pug +0 -66
  38. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css +0 -1912
  39. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css.map +0 -1
  40. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css +0 -7
  41. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css.map +0 -1
  42. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css +0 -331
  43. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css.map +0 -1
  44. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css +0 -8
  45. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css.map +0 -1
  46. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.css +0 -9030
  47. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.css.map +0 -1
  48. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css +0 -7
  49. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css.map +0 -1
  50. data/lore/public/stylesheets/style.css +0 -8
  51. data/package-lock.json +0 -1064
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a51a7f69ebbca275fd9a215a52cd3e4d8db739e8e6cecf3eb522871f23295b5
4
- data.tar.gz: 58f033b5c4f8756532dd3dbe83c631b36560e3215a342f804916de205f53cb56
3
+ metadata.gz: 69fc6d5fce636d669cb33a9564a3c504eb255cb13a81985154589eb7cc6f9879
4
+ data.tar.gz: f2400bbda425b4e0f8d72b52d7edfcf761c8356638691074c79b72fdbca9f086
5
5
  SHA512:
6
- metadata.gz: e52a4b23f708892b12c3ca68a2b5e3c13a2c9b1d1b52057ede1548faa7c7d03914296ebb1402c7c1cd1f0540df1d6182ffa09de2cf3558410d499703bc8b352f
7
- data.tar.gz: 32201a386bc48ef35395e702a46661f78b12c4b15cab6214203e91e3599537cc53742f5ef2848ecf3d73b3c6c007413b55b4ea22bc4f8c83131733b9b2ace4a3
6
+ metadata.gz: 17016392e9b2931c961bf1cdb3c7f832af15896201b395995c124befb7de1987ee43997f9186c329f9fe6474101158c06a0772e8bf0bd6bbd9b9b4ddd84defeb
7
+ data.tar.gz: 29fe408c9a44ec5cf8ffd410f732d6cc5959e045480c94406a4f9cc4abc2badbc1843f449bba0b8cd5e2b6269c71f8e5d603b9e99a902e63e6692d16af0e4c6f
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.53.0](https://github.com/applandinc/appmap-ruby/compare/v0.52.1...v0.53.0) (2021-06-23)
2
+
3
+
4
+ ### Features
5
+
6
+ * appmap-agent-setup as a separate command not using GLI library ([f0eedb7](https://github.com/applandinc/appmap-ruby/commit/f0eedb7451368ea0399872f3be680e1581ac6200))
7
+
8
+ ## [0.52.1](https://github.com/applandinc/appmap-ruby/compare/v0.52.0...v0.52.1) (2021-06-23)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Better project name guesser ([d22f379](https://github.com/applandinc/appmap-ruby/commit/d22f379623bd3022ba34d7241838fe6abbbb61d6))
14
+
15
+ # [0.52.0](https://github.com/applandinc/appmap-ruby/compare/v0.51.3...v0.52.0) (2021-06-22)
16
+
17
+
18
+ ### Features
19
+
20
+ * Bundle NPM package @appland/cli with this gem ([945e28c](https://github.com/applandinc/appmap-ruby/commit/945e28c699fff6bd97ae51983816e97955c4ff36))
21
+
22
+ ## [0.51.3](https://github.com/applandinc/appmap-ruby/compare/v0.51.2...v0.51.3) (2021-06-22)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * Remove outdate lore, command, and algorithm code ([d899989](https://github.com/applandinc/appmap-ruby/commit/d8999896c611c16f51a092f5f7afb3d7203d7e72))
28
+
29
+ ## [0.51.2](https://github.com/applandinc/appmap-ruby/compare/v0.51.1...v0.51.2) (2021-06-22)
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * Be less verbose when logging config messages ([fba2fd0](https://github.com/applandinc/appmap-ruby/commit/fba2fd01dbb7b1830194b49285654d6657d1c786))
35
+ * Method objects must support eql? and hash to ensure they are unique in a Set ([f4d5b11](https://github.com/applandinc/appmap-ruby/commit/f4d5b11db90aa50bdd1f768e039927833e83c30f))
36
+ * Require rails, then appmap/railtie ([07967a1](https://github.com/applandinc/appmap-ruby/commit/07967a14609891544a7dd874c648b7ef5a505f21))
37
+ * Use a hybrid strategy to auto-requiring appmap modules ([6fb09b8](https://github.com/applandinc/appmap-ruby/commit/6fb09b8c0bd55b1e29967d459ce1e2bd5b1ba9fe))
38
+
1
39
  ## [0.51.1](https://github.com/applandinc/appmap-ruby/compare/v0.51.0...v0.51.1) (2021-06-21)
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
- run_cmd( {"RUBY_VERSION" => ruby_version, "GEM_VERSION" => GEM_VERSION},
48
- " docker-compose build" \
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,25 @@ 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.extensions << "ext/appmap/extconf.rb"
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
- spec.add_dependency 'gli'
32
36
  spec.add_dependency 'method_source'
33
- spec.add_dependency 'parser'
34
37
  spec.add_dependency 'rack'
38
+ spec.add_dependency 'reverse_markdown'
35
39
 
36
40
  spec.add_development_dependency 'bundler', '>= 1.16'
37
- spec.add_development_dependency 'minitest', '~> 5.0'
41
+ spec.add_development_dependency 'minitest', '= 5.14.4'
38
42
  spec.add_development_dependency 'pry-byebug'
39
43
  spec.add_development_dependency 'rake', '>= 12.3.3'
40
44
  spec.add_development_dependency 'rdoc'
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'optparse'
5
+ require 'appmap'
6
+ require 'appmap/command/agent_setup/init'
7
+
8
+ @options = {:config_file => AppMap::DEFAULT_CONFIG_FILE_PATH}
9
+
10
+ OptionParser.new do |parser|
11
+ parser.banner = 'Usage: bundle exec exe/appmap-agent-init [options]'
12
+
13
+ description = "AppMap configuration file path (default: #{AppMap::DEFAULT_CONFIG_FILE_PATH})"
14
+ parser.on('-c', '--config=FILEPATH', description) do |filepath|
15
+ @options[:config_file] = filepath
16
+ end
17
+ end.parse!
18
+
19
+ AppMap::Command::AgentSetup::Init.new(@options[:config_file]).perform
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift File.join(__dir__, '../lib')
5
+
6
+ require 'appmap/command/inspect'
7
+ AppMap::Command::Inspect.run
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
@@ -51,7 +51,7 @@ module AppMap
51
51
  # Call this function before the program code is loaded by the Ruby VM, otherwise
52
52
  # the load events won't be seen and the hooks won't activate.
53
53
  def initialize_configuration(config_file_path = default_config_file_path)
54
- warn "Configuring AppMap from path #{config_file_path}"
54
+ Util.startup_message "Configuring AppMap from path #{config_file_path}"
55
55
  Config.load_from_file(config_file_path).tap do |configuration|
56
56
  self.configuration = configuration
57
57
  Hook.new(configuration).enable
@@ -112,17 +112,49 @@ module AppMap
112
112
  end
113
113
  end
114
114
 
115
- if defined?(::Rails::Railtie)
116
- require 'appmap/railtie'
117
- end
115
+ lambda do
116
+ Initializer = Struct.new(:class_name, :module_name, :gem_module_name)
118
117
 
119
- if defined?(::RSpec)
120
- require 'appmap/rspec'
121
- end
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
+ }
122
123
 
123
- # defined?(::Minitest) returns nil...
124
- if Gem.loaded_specs['minitest']
125
- require 'appmap/minitest'
126
- end
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
127
159
 
128
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,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
+ require 'appmap/util'
4
5
  require 'appmap/handler/net_http'
5
6
  require 'appmap/handler/rails/template'
7
+ require 'appmap/service/guesser'
6
8
 
7
9
  module AppMap
8
10
  class Config
@@ -53,7 +55,7 @@ module AppMap
53
55
  if path
54
56
  Package.new(path, gem, package_name, exclude, labels, shallow)
55
57
  else
56
- warn "#{gem} is not available in the bundle" if AppMap::Hook::LOG
58
+ AppMap::Util.startup_message "#{gem} is not available in the bundle"
57
59
  end
58
60
  end
59
61
 
@@ -284,7 +286,7 @@ module AppMap
284
286
  settings, the appmap gem will try and guess some reasonable defaults.
285
287
  To suppress this message, create the file:
286
288
 
287
- #{Pathname.new(config_file_name).expand_path}.
289
+ #{Pathname.new(config_file_name).expand_path}
288
290
 
289
291
  Here are the default settings that will be used in the meantime. You can
290
292
  copy and paste this example to start your appmap.yml.
@@ -308,7 +310,7 @@ module AppMap
308
310
 
309
311
  # Loads configuration from a Hash.
310
312
  def load(config_data)
311
- name = config_data['name'] || guess_name
313
+ name = config_data['name'] || Service::Guesser.guess_name
312
314
  config_params = {
313
315
  exclude: config_data['exclude']
314
316
  }.compact
@@ -344,33 +346,13 @@ module AppMap
344
346
  end
345
347
  end.compact
346
348
  else
347
- Array(guess_paths).map do |path|
349
+ Array(Service::Guesser.guess_paths).map do |path|
348
350
  Package.build_from_path(path)
349
351
  end
350
352
  end
351
353
 
352
354
  Config.new name, config_params
353
355
  end
354
-
355
- def guess_name
356
- reponame = lambda do
357
- next unless File.directory?('.git')
358
-
359
- repo_name = `git config --get remote.origin.url`.strip
360
- repo_name.split('/').last.split('.').first unless repo_name == ''
361
- end
362
- dirname = -> { Dir.pwd.split('/').last }
363
-
364
- reponame.() || dirname.()
365
- end
366
-
367
- def guess_paths
368
- if defined?(::Rails)
369
- %w[app/controllers app/models]
370
- elsif File.directory?('lib')
371
- %w[lib]
372
- end
373
- end
374
356
  end
375
357
 
376
358
  def to_h
@@ -14,16 +14,30 @@ module AppMap
14
14
  # The class name is generated from the template path. The package name is
15
15
  # 'app/views', and the method name is 'render'. The source location of the method
16
16
  # is, of course, the path to the view template.
17
- TemplateMethod = Struct.new(:path) do
18
- private_instance_methods :path
17
+ class TemplateMethod
19
18
  attr_reader :class_name
20
-
19
+
20
+ attr_reader :path
21
+ private_instance_methods :path
22
+
21
23
  def initialize(path)
22
- super
24
+ @path = path
23
25
 
24
26
  @class_name = path.parameterize.underscore
25
27
  end
26
-
28
+
29
+ def id
30
+ [ package, path, name ]
31
+ end
32
+
33
+ def hash
34
+ id.hash
35
+ end
36
+
37
+ def eql?(other)
38
+ other.is_a?(TemplateMethod) && id.eql?(other.id)
39
+ end
40
+
27
41
  def package
28
42
  'app/views'
29
43
  end